Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a0b9b9cfb | ||
|
|
510cff3570 | ||
|
|
12d881e810 | ||
|
|
201d82f5d0 | ||
|
|
61cc4f207e | ||
|
|
4948f270b3 | ||
|
|
ec2031e2a7 | ||
|
|
3f01c8833f | ||
|
|
23ba41533a | ||
|
|
803c05ec7e | ||
|
|
80d033fb43 | ||
|
|
ad39b7a718 | ||
|
|
736d419289 | ||
|
|
8e36a9c169 | ||
|
|
52a0622beb | ||
|
|
efd0b4993a | ||
|
|
23ccc34262 | ||
|
|
1a7b8fbc24 | ||
|
|
9b998e4d08 | ||
|
|
7f2a15c906 | ||
|
|
3915545605 | ||
|
|
531a4273c0 | ||
|
|
bc1695eff5 | ||
|
|
e98b66f8ae | ||
|
|
565e01a72c | ||
|
|
d059092897 | ||
|
|
54bf3ae32e | ||
|
|
45c03c564f | ||
|
|
4266c0a2fd | ||
|
|
43dfe01919 | ||
|
|
1c9521fec3 | ||
|
|
3eb52578f3 | ||
|
|
1e375f1964 | ||
|
|
7eda5f7c97 | ||
|
|
18c8f79f3e | ||
|
|
3a2c329e4b | ||
|
|
2a18fc8cde | ||
|
|
2a87a9154d | ||
|
|
cd98f93cff | ||
|
|
37fece22e8 | ||
|
|
d60a5bf900 | ||
|
|
237ad4beb3 | ||
|
|
289bbd52e5 | ||
|
|
1869f7966e | ||
|
|
2c0932a89b | ||
|
|
0974f681a4 | ||
|
|
5b119ae17f | ||
|
|
f169029622 | ||
|
|
b06c3e7d6c | ||
|
|
2c07b977ea | ||
|
|
c1b154a8e8 | ||
|
|
9dd12742f3 | ||
|
|
b09b12ce10 | ||
|
|
4923222412 | ||
|
|
4000945a1d | ||
|
|
bf853d5510 | ||
|
|
348a53a842 | ||
|
|
bf0b4b034c | ||
|
|
9470b872c0 | ||
|
|
c5c4de9888 | ||
|
|
14947ed15c | ||
|
|
39f6779874 | ||
|
|
662a541431 | ||
|
|
1c77b79f56 | ||
|
|
f1510489bd | ||
|
|
0faabe43f8 | ||
|
|
302fb53a76 | ||
|
|
dea76e1db0 | ||
|
|
ee1a084852 | ||
|
|
81e13ef7cf | ||
|
|
9d504ae85b | ||
|
|
f72dc6091b | ||
|
|
c28f9e2713 | ||
|
|
2cc72f1fd3 | ||
|
|
9c86db00d4 | ||
|
|
c44785be57 | ||
|
|
e3d529403d | ||
|
|
142acbdea7 | ||
|
|
673f0d7cdc | ||
|
|
89703d20fb | ||
|
|
51778b7cca | ||
|
|
a91ca620cf | ||
|
|
f3a1a84c9a | ||
|
|
d0e2cd15cb | ||
|
|
130fe11394 | ||
|
|
dc048d18d3 | ||
|
|
068a8c1b10 | ||
|
|
f938ad5406 | ||
|
|
49bb0041af | ||
|
|
16f729957f | ||
|
|
d3b7f8d21f | ||
|
|
ac110a1f21 | ||
|
|
5347aee8f7 | ||
|
|
e69b8ccceb | ||
|
|
198d127b35 | ||
|
|
0d31160b4e | ||
|
|
f4f5affdf7 | ||
|
|
a49c1f1782 | ||
|
|
ab7b6f1ece | ||
|
|
de2c92f6e0 | ||
|
|
4af2c9de0c | ||
|
|
a5ad5279a5 | ||
|
|
3640396b1a | ||
|
|
f040be9850 | ||
|
|
fe48775868 | ||
|
|
441f5d61fd | ||
|
|
1dd7961557 | ||
|
|
2a74609b90 | ||
|
|
3763c77f6b | ||
|
|
36fac00149 | ||
|
|
db2f540414 | ||
|
|
c7f008b069 | ||
|
|
d36ee9b845 | ||
|
|
764deea5f8 | ||
|
|
aa224c0205 | ||
|
|
ff2d18928d | ||
|
|
b74a468fad | ||
|
|
614fddee6a | ||
|
|
7cab86f647 | ||
|
|
923938edde | ||
|
|
2c4acdabdc | ||
|
|
ff9114aee3 | ||
|
|
c4807f4d2f | ||
|
|
2866951558 | ||
|
|
e02bf99fa4 | ||
|
|
bf25d7ac57 | ||
|
|
87cfbe3e5f | ||
|
|
eb70043e59 | ||
|
|
9242816b56 | ||
|
|
70d1301d6e | ||
|
|
83c3f4427c | ||
|
|
13f42d9085 | ||
|
|
38a0215b53 | ||
|
|
8b452453ce | ||
|
|
b37b79e868 | ||
|
|
043b3c01bb | ||
|
|
c30d8d50da | ||
|
|
5c2771710d | ||
|
|
202844ebd0 | ||
|
|
8e3a36a6db | ||
|
|
00fa1ae0c0 | ||
|
|
a6b942018d | ||
|
|
c4f739bef4 | ||
|
|
f2a3b6e7b4 | ||
|
|
cf6edcd0a1 | ||
|
|
43aa9fe8b3 | ||
|
|
019b833306 | ||
|
|
8243b27f44 | ||
|
|
e62165bc15 | ||
|
|
5d500b60e7 | ||
|
|
5bee32e349 | ||
|
|
f772bf54a5 | ||
|
|
d57b418214 | ||
|
|
e3f4e6cbda | ||
|
|
ab43c50224 | ||
|
|
6ae270d772 | ||
|
|
370b751e24 | ||
|
|
6fca9e7545 | ||
|
|
6381e99fb2 | ||
|
|
b81cbbade1 | ||
|
|
290aaa7521 | ||
|
|
815580a538 | ||
|
|
118bfc4ccb | ||
|
|
b880631aed | ||
|
|
30009521d7 | ||
|
|
d2858e93cb | ||
|
|
829dc6612a | ||
|
|
dd97e241a8 | ||
|
|
1dcb2ff23f | ||
|
|
957d678031 | ||
|
|
1981d5a730 | ||
|
|
93fc13ebc8 | ||
|
|
c0a9bf3c2e | ||
|
|
954e2bc48f | ||
|
|
7d64cb375c | ||
|
|
33341de7d7 | ||
|
|
fcf2087a15 | ||
|
|
c46fb924df | ||
|
|
0d348d46d8 | ||
|
|
f51e0660f4 | ||
|
|
0c5e8b17ad | ||
|
|
04fa41b5ce | ||
|
|
ab2ee08042 | ||
|
|
fb0ba59c41 | ||
|
|
6c903a8dd5 | ||
|
|
d0c3862479 | ||
|
|
e9dfdf6924 | ||
|
|
993a9dfc5a | ||
|
|
1eeba1cf89 | ||
|
|
bc6e27cc6f | ||
|
|
bff23b72c5 | ||
|
|
957823f56f | ||
|
|
4f1acdd158 | ||
|
|
e75909ef93 | ||
|
|
0d0f7e4357 | ||
|
|
5d589562fe | ||
|
|
ebc13bc180 | ||
|
|
460a4ee6d4 | ||
|
|
33b8a893ed | ||
|
|
02c244bf78 | ||
|
|
c8f5509b32 | ||
|
|
4a9ec65c9d | ||
|
|
fb5df613cf | ||
|
|
a1653fbfd0 | ||
|
|
71dd67cf57 | ||
|
|
ddbb8e27bf | ||
|
|
de95f96462 | ||
|
|
32990b5dae | ||
|
|
13ba880b49 | ||
|
|
75424d1139 | ||
|
|
107e243195 | ||
|
|
50e82c015d | ||
|
|
da4fe741b8 | ||
|
|
99b23ba1b7 | ||
|
|
dca60f29fa | ||
|
|
764d23eb25 | ||
|
|
04773ac90a | ||
|
|
35b891c5b0 | ||
|
|
f22a0d653d | ||
|
|
45f84ab7cc | ||
|
|
de4d4da52d | ||
|
|
7591a7f224 | ||
|
|
e162aceeb6 | ||
|
|
96abb5a806 | ||
|
|
44bb2f6c89 | ||
|
|
60af95d971 | ||
|
|
2bd6b13e53 | ||
|
|
3aa4b2b598 | ||
|
|
877cc84f85 | ||
|
|
35276a9441 | ||
|
|
bde926fce7 | ||
|
|
f33021552b | ||
|
|
d9967436da | ||
|
|
236d94fa9a | ||
|
|
5e334be457 | ||
|
|
78aa05228a | ||
|
|
c8e9c4046f | ||
|
|
ea4daa308d | ||
|
|
af3246be2d | ||
|
|
268775dae8 | ||
|
|
e30bac4c4b | ||
|
|
0ba773878f | ||
|
|
7c4d041d3c | ||
|
|
4d9e557f44 |
@@ -12,5 +12,10 @@
|
|||||||
# Visual Studio
|
# Visual Studio
|
||||||
*.sln text eol=crlf
|
*.sln text eol=crlf
|
||||||
*.vcxproj* text eol=crlf
|
*.vcxproj* text eol=crlf
|
||||||
|
*.vcproj* text eol=crlf
|
||||||
*.suo binary
|
*.suo binary
|
||||||
*.rc binary
|
*.rc binary
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
*.bat text eol=crlf
|
||||||
|
*.cmd text eol=crlf
|
||||||
|
|||||||
+8
-3
@@ -18,7 +18,12 @@
|
|||||||
*.app
|
*.app
|
||||||
|
|
||||||
# Visual C++
|
# Visual C++
|
||||||
visual/
|
projects/VS2008
|
||||||
|
projects/VS2010
|
||||||
|
projects/VS2012
|
||||||
|
projects/VS2013
|
||||||
|
projects/VS2015
|
||||||
|
build/bin
|
||||||
|
|
||||||
# IDEA solution files
|
# IDEA solution files
|
||||||
*.idea
|
*.idea
|
||||||
@@ -27,7 +32,7 @@ visual/
|
|||||||
.directory
|
.directory
|
||||||
_codelite/
|
_codelite/
|
||||||
_zstdbench/
|
_zstdbench/
|
||||||
zlib_wrapper/
|
.clang_complete
|
||||||
|
|
||||||
# CMake
|
# CMake
|
||||||
contrib/cmake/
|
projects/cmake/
|
||||||
|
|||||||
+86
-27
@@ -1,31 +1,90 @@
|
|||||||
language: c
|
language: c
|
||||||
|
|
||||||
before_install:
|
|
||||||
- sudo apt-get update -qq
|
|
||||||
- sudo apt-get install -qq clang
|
|
||||||
- sudo apt-get install -qq g++-multilib
|
|
||||||
- sudo apt-get install -qq gcc-multilib
|
|
||||||
- sudo apt-get install -qq valgrind
|
|
||||||
|
|
||||||
env:
|
|
||||||
- ZSTD_TRAVIS_CI_ENV=travis-install
|
|
||||||
- ZSTD_TRAVIS_CI_ENV=cmaketest
|
|
||||||
- ZSTD_TRAVIS_CI_ENV=clangtest
|
|
||||||
- ZSTD_TRAVIS_CI_ENV=gpptest
|
|
||||||
- ZSTD_TRAVIS_CI_ENV=gnu90test
|
|
||||||
- ZSTD_TRAVIS_CI_ENV=armtest-w-install
|
|
||||||
- ZSTD_TRAVIS_CI_ENV=test
|
|
||||||
- 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=asan
|
|
||||||
- ZSTD_TRAVIS_CI_ENV=asan32
|
|
||||||
- ZSTD_TRAVIS_CI_ENV="-C programs valgrindTest"
|
|
||||||
|
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
|
|
||||||
script:
|
|
||||||
- make $ZSTD_TRAVIS_CI_ENV
|
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
include:
|
||||||
|
# Container-based Ubuntu 12.04 LTS Server Edition 64 bit (doesn't support 32-bit includes)
|
||||||
|
- os: linux
|
||||||
|
sudo: false
|
||||||
|
env: PLATFORM="Ubuntu 12.04 container" MAKE_PARAM=travis-install
|
||||||
|
- os: linux
|
||||||
|
sudo: false
|
||||||
|
env: PLATFORM="Ubuntu 12.04 container" MAKE_PARAM=cmaketest
|
||||||
|
- os: linux
|
||||||
|
sudo: false
|
||||||
|
env: PLATFORM="Ubuntu 12.04 container" MAKE_PARAM=test
|
||||||
|
- os: linux
|
||||||
|
sudo: false
|
||||||
|
env: PLATFORM="Ubuntu 12.04 container" MAKE_PARAM="-C programs test-zstd_nolegacy"
|
||||||
|
- os: linux
|
||||||
|
sudo: false
|
||||||
|
env: PLATFORM="Ubuntu 12.04 container" MAKE_PARAM=usan
|
||||||
|
- os: linux
|
||||||
|
sudo: false
|
||||||
|
env: PLATFORM="Ubuntu 12.04 container" MAKE_PARAM=asan
|
||||||
|
- os: linux
|
||||||
|
sudo: false
|
||||||
|
env: PLATFORM="Ubuntu 12.04 container" MAKE_PARAM=zlibwrapper
|
||||||
|
# Standard Ubuntu 12.04 LTS Server Edition 64 bit
|
||||||
|
- os: linux
|
||||||
|
sudo: required
|
||||||
|
env: PLATFORM="Ubuntu 12.04" MAKE_PARAM=clangtest
|
||||||
|
- os: linux
|
||||||
|
sudo: required
|
||||||
|
env: PLATFORM="Ubuntu 12.04" MAKE_PARAM=gpptest
|
||||||
|
- os: linux
|
||||||
|
sudo: required
|
||||||
|
env: PLATFORM="Ubuntu 12.04" MAKE_PARAM=gnu90test
|
||||||
|
- os: linux
|
||||||
|
sudo: required
|
||||||
|
env: PLATFORM="Ubuntu 12.04" MAKE_PARAM=c99test
|
||||||
|
- os: linux
|
||||||
|
sudo: required
|
||||||
|
env: PLATFORM="Ubuntu 12.04" MAKE_PARAM=gnu99test
|
||||||
|
- os: linux
|
||||||
|
sudo: required
|
||||||
|
env: PLATFORM="Ubuntu 12.04" MAKE_PARAM=armtest-w-install
|
||||||
|
- os: linux
|
||||||
|
sudo: required
|
||||||
|
env: PLATFORM="Ubuntu 12.04" MAKE_PARAM="-C programs test32"
|
||||||
|
- os: linux
|
||||||
|
sudo: required
|
||||||
|
env: PLATFORM="Ubuntu 12.04" MAKE_PARAM="-C tests versionsTest"
|
||||||
|
- os: linux
|
||||||
|
sudo: required
|
||||||
|
env: PLATFORM="Ubuntu 12.04" MAKE_PARAM=asan32
|
||||||
|
- os: linux
|
||||||
|
sudo: required
|
||||||
|
env: PLATFORM="Ubuntu 12.04" MAKE_PARAM="-C programs valgrindTest"
|
||||||
|
# Ubuntu 14.04 LTS Server Edition 64 bit
|
||||||
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
|
sudo: required
|
||||||
|
env: PLATFORM="Ubuntu 14.04" MAKE_PARAM=ppctest-w-install
|
||||||
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
|
sudo: required
|
||||||
|
env: PLATFORM="Ubuntu 14.04" MAKE_PARAM=zlibwrapper
|
||||||
|
# OS X Mavericks
|
||||||
|
- os: osx
|
||||||
|
env: PLATFORM="OS X Mavericks" MAKE_PARAM=travis-install
|
||||||
|
- os: osx
|
||||||
|
env: PLATFORM="OS X Mavericks" MAKE_PARAM=gnu90test
|
||||||
|
- os: osx
|
||||||
|
env: PLATFORM="OS X Mavericks" MAKE_PARAM=test
|
||||||
|
exclude:
|
||||||
|
- compiler: gcc
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- set -e
|
||||||
|
- |
|
||||||
|
if [ "$TRAVIS_OS_NAME" == "linux" ]; then
|
||||||
|
CAN_I_RUN_SUDO=$(sudo -n uptime 2>&1|grep "load"|wc -l)
|
||||||
|
echo "CAN_I_RUN_SUDO=$CAN_I_RUN_SUDO\n"
|
||||||
|
if [ ${CAN_I_RUN_SUDO} -gt 0 ]; then
|
||||||
|
sudo apt-get install -y -qq clang g++-multilib gcc-multilib valgrind
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
script:
|
||||||
|
- make $MAKE_PARAM
|
||||||
|
|||||||
@@ -30,11 +30,9 @@
|
|||||||
# - zstd homepage : http://www.zstd.net/
|
# - zstd homepage : http://www.zstd.net/
|
||||||
# ################################################################
|
# ################################################################
|
||||||
|
|
||||||
# force a version number : uncomment below export (otherwise, default to the one declared into zstd.h)
|
|
||||||
#export VERSION := 0.6.1
|
|
||||||
|
|
||||||
PRGDIR = programs
|
PRGDIR = programs
|
||||||
ZSTDDIR = lib
|
ZSTDDIR = lib
|
||||||
|
ZWRAPDIR = zlibWrapper
|
||||||
|
|
||||||
# Define nul output
|
# Define nul output
|
||||||
ifneq (,$(filter Windows%,$(OS)))
|
ifneq (,$(filter Windows%,$(OS)))
|
||||||
@@ -43,7 +41,7 @@ else
|
|||||||
VOID = /dev/null
|
VOID = /dev/null
|
||||||
endif
|
endif
|
||||||
|
|
||||||
.PHONY: default all zstdprogram clean install uninstall travis-install test clangtest gpptest armtest usan asan uasan
|
.PHONY: default all zlibwrapper zstdprogram clean install uninstall travis-install test clangtest gpptest armtest usan asan uasan
|
||||||
|
|
||||||
default: zstdprogram
|
default: zstdprogram
|
||||||
|
|
||||||
@@ -54,19 +52,25 @@ all:
|
|||||||
zstdprogram:
|
zstdprogram:
|
||||||
$(MAKE) -C $(PRGDIR)
|
$(MAKE) -C $(PRGDIR)
|
||||||
|
|
||||||
|
zlibwrapper:
|
||||||
|
$(MAKE) -C $(ZSTDDIR) all
|
||||||
|
$(MAKE) -C $(ZWRAPDIR) all
|
||||||
|
|
||||||
test:
|
test:
|
||||||
$(MAKE) -C $(PRGDIR) $@
|
$(MAKE) -C $(PRGDIR) $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@$(MAKE) -C $(ZSTDDIR) $@ > $(VOID)
|
@$(MAKE) -C $(ZSTDDIR) $@ > $(VOID)
|
||||||
@$(MAKE) -C $(PRGDIR) $@ > $(VOID)
|
@$(MAKE) -C $(PRGDIR) $@ > $(VOID)
|
||||||
|
@$(MAKE) -C $(ZWRAPDIR) $@ > $(VOID)
|
||||||
@echo Cleaning completed
|
@echo Cleaning 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))
|
||||||
|
HOST_OS = POSIX
|
||||||
install:
|
install:
|
||||||
$(MAKE) -C $(ZSTDDIR) $@
|
$(MAKE) -C $(ZSTDDIR) $@
|
||||||
$(MAKE) -C $(PRGDIR) $@
|
$(MAKE) -C $(PRGDIR) $@
|
||||||
@@ -78,41 +82,20 @@ uninstall:
|
|||||||
travis-install:
|
travis-install:
|
||||||
$(MAKE) install PREFIX=~/install_test_dir
|
$(MAKE) install PREFIX=~/install_test_dir
|
||||||
|
|
||||||
cmaketest:
|
gpptest: clean
|
||||||
cd contrib/cmake ; cmake . ; $(MAKE)
|
$(MAKE) all CC=g++ CFLAGS="-O3 -Wall -Wextra -Wundef -Wshadow -Wcast-align -Werror"
|
||||||
|
|
||||||
clangtest: clean
|
clangtest: clean
|
||||||
clang -v
|
clang -v
|
||||||
$(MAKE) all CC=clang MOREFLAGS="-Werror -Wconversion -Wno-sign-conversion"
|
$(MAKE) all CC=clang MOREFLAGS="-Werror -Wconversion -Wno-sign-conversion"
|
||||||
|
|
||||||
gpptest: clean
|
|
||||||
$(MAKE) all CC=g++ CFLAGS="-O3 -Wall -Wextra -Wundef -Wshadow -Wcast-align -Werror"
|
|
||||||
|
|
||||||
gnu90test: clean
|
|
||||||
$(MAKE) all CFLAGS="-std=gnu90 -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 -Wswitch-enum -Wstrict-prototypes -Wundef -Wdeclaration-after-statement -Werror"
|
|
||||||
|
|
||||||
c90test: clean
|
|
||||||
$(MAKE) all CFLAGS="-std=c90 -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 -Wswitch-enum -Wstrict-prototypes -Wundef -Werror" # will fail, due to // and long long
|
|
||||||
|
|
||||||
bmix64test: clean
|
|
||||||
CFLAGS="-O3 -mbmi -Werror" $(MAKE) -C $(PRGDIR) test
|
|
||||||
|
|
||||||
bmix32test: clean
|
|
||||||
CFLAGS="-O3 -mbmi -mx32 -Werror" $(MAKE) -C $(PRGDIR) test
|
|
||||||
|
|
||||||
bmi32test: clean
|
|
||||||
CFLAGS="-O3 -mbmi -m32 -Werror" $(MAKE) -C $(PRGDIR) test
|
|
||||||
|
|
||||||
armtest: clean
|
armtest: clean
|
||||||
$(MAKE) -C $(PRGDIR) datagen # use native, faster
|
$(MAKE) -C $(PRGDIR) datagen # use native, faster
|
||||||
$(MAKE) -C $(PRGDIR) test CC=arm-linux-gnueabi-gcc ZSTDRTTEST= MOREFLAGS="-Werror -static"
|
$(MAKE) -C $(PRGDIR) test CC=arm-linux-gnueabi-gcc ZSTDRTTEST= MOREFLAGS="-Werror -static"
|
||||||
|
|
||||||
# for Travis CI
|
# for Travis CI
|
||||||
arminstall: clean
|
arminstall: clean
|
||||||
sudo apt-get install -q qemu
|
sudo apt-get install -y -q qemu binfmt-support qemu-user-static gcc-arm-linux-gnueabi
|
||||||
sudo apt-get install -q binfmt-support
|
|
||||||
sudo apt-get install -q qemu-user-static
|
|
||||||
sudo apt-get install -q gcc-arm-linux-gnueabi
|
|
||||||
|
|
||||||
# for Travis CI
|
# for Travis CI
|
||||||
armtest-w-install: clean arminstall armtest
|
armtest-w-install: clean arminstall armtest
|
||||||
@@ -123,21 +106,32 @@ ppctest: clean
|
|||||||
|
|
||||||
# for Travis CI
|
# for Travis CI
|
||||||
ppcinstall: clean
|
ppcinstall: clean
|
||||||
sudo apt-get install -q qemu
|
# sudo apt-get update -y -q
|
||||||
sudo apt-get install -q binfmt-support
|
sudo apt-get install -y -q qemu-system-ppc binfmt-support qemu-user-static gcc-powerpc-linux-gnu # doesn't work with Ubuntu 12.04
|
||||||
sudo apt-get install -q qemu-user-static
|
|
||||||
sudo apt-get update -q
|
|
||||||
sudo apt-get install -q gcc-powerpc-linux-gnu # unfortunately, doesn't work on Travis CI (package not available)
|
|
||||||
|
|
||||||
# for Travis CI
|
# for Travis CI
|
||||||
ppctest-w-install: clean ppcinstall ppctest
|
ppctest-w-install: clean ppcinstall ppctest
|
||||||
|
|
||||||
|
ppc64test: clean
|
||||||
|
$(MAKE) -C $(PRGDIR) datagen # use native, faster
|
||||||
|
$(MAKE) -C $(PRGDIR) test CC=powerpc64le-linux-gnu-gcc ZSTDRTTEST= MOREFLAGS="-Werror -static"
|
||||||
|
|
||||||
|
ppc64install: clean
|
||||||
|
sudo apt-get update -y -q
|
||||||
|
sudo apt-get install -y -q qemu-ppc64le binfmt-support qemu-user-static gcc-powerpc64le-linux-gnu
|
||||||
|
update-binfmts --displ
|
||||||
|
|
||||||
|
ppc64test-w-install: clean ppc64install ppc64test
|
||||||
|
|
||||||
usan: clean
|
usan: clean
|
||||||
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=undefined"
|
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=undefined"
|
||||||
|
|
||||||
asan: clean
|
asan: clean
|
||||||
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address"
|
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address"
|
||||||
|
|
||||||
|
msan: clean
|
||||||
|
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=memory" # datagen.c used to fail this test for no obvious reason
|
||||||
|
|
||||||
asan32: clean
|
asan32: clean
|
||||||
$(MAKE) -C $(PRGDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address"
|
$(MAKE) -C $(PRGDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address"
|
||||||
|
|
||||||
@@ -145,3 +139,45 @@ uasan: clean
|
|||||||
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address -fsanitize=undefined"
|
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address -fsanitize=undefined"
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
ifneq (,$(filter MSYS%,$(shell uname)))
|
||||||
|
HOST_OS = MSYS
|
||||||
|
CMAKE_PARAMS = -G"MSYS Makefiles"
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------
|
||||||
|
#make tests validated only for MSYS, Linux, OSX, kFreeBSD and Hurd targets
|
||||||
|
#------------------------------------------------------------------------
|
||||||
|
ifneq (,$(filter $(HOST_OS),MSYS POSIX))
|
||||||
|
cmaketest:
|
||||||
|
cmake --version
|
||||||
|
rm -rf projects/cmake/build
|
||||||
|
mkdir projects/cmake/build
|
||||||
|
cd projects/cmake/build ; cmake -DPREFIX:STRING=~/install_test_dir $(CMAKE_PARAMS) .. ; $(MAKE) install ; $(MAKE) uninstall
|
||||||
|
|
||||||
|
c90test: clean
|
||||||
|
CFLAGS="-std=c90" $(MAKE) all # will fail, due to // and long long
|
||||||
|
|
||||||
|
gnu90test: clean
|
||||||
|
CFLAGS="-std=gnu90" $(MAKE) all
|
||||||
|
|
||||||
|
c99test: clean
|
||||||
|
CFLAGS="-std=c99" $(MAKE) all
|
||||||
|
|
||||||
|
gnu99test: clean
|
||||||
|
CFLAGS="-std=gnu99" $(MAKE) all
|
||||||
|
|
||||||
|
c11test: clean
|
||||||
|
CFLAGS="-std=c11" $(MAKE) all
|
||||||
|
|
||||||
|
bmix64test: clean
|
||||||
|
CFLAGS="-O3 -mbmi -Werror" $(MAKE) -C $(PRGDIR) test
|
||||||
|
|
||||||
|
bmix32test: clean
|
||||||
|
CFLAGS="-O3 -mbmi -mx32 -Werror" $(MAKE) -C $(PRGDIR) test
|
||||||
|
|
||||||
|
bmi32test: clean
|
||||||
|
CFLAGS="-O3 -mbmi -m32 -Werror" $(MAKE) -C $(PRGDIR) test
|
||||||
|
endif
|
||||||
|
|||||||
@@ -1,3 +1,16 @@
|
|||||||
|
v0.7.0
|
||||||
|
New : Support for directory compression, using `-r`, thanks to Przemyslaw Skibinski
|
||||||
|
New : Command `--rm`, to remove source file after successful de/compression
|
||||||
|
New : Visual build scripts, by Christophe Chevalier
|
||||||
|
New : Support for Sparse File-systems (do not use space for zero-filled sectors)
|
||||||
|
New : Frame checksum support
|
||||||
|
New : Support pass-through mode (when using `-df`)
|
||||||
|
API : more efficient Dictionary API : `ZSTD_compress_usingCDict()`, `ZSTD_decompress_usingDDict()`
|
||||||
|
API : create dictionary files from custom content, by Giuseppe Ottaviano
|
||||||
|
API : support for custom malloc/free functions
|
||||||
|
New : controllable Dictionary ID
|
||||||
|
New : Support for skippable frames
|
||||||
|
|
||||||
v0.6.1
|
v0.6.1
|
||||||
New : zlib wrapper API, thanks to Przemyslaw Skibinski
|
New : zlib wrapper API, thanks to Przemyslaw Skibinski
|
||||||
New : Ability to compile compressor / decompressor separately
|
New : Ability to compile compressor / decompressor separately
|
||||||
@@ -108,4 +121,3 @@ detects write-flush errors
|
|||||||
git@github.com:Cyan4973/zstd.git
|
git@github.com:Cyan4973/zstd.git
|
||||||
v0.1.0
|
v0.1.0
|
||||||
first release
|
first release
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
**Zstd**, short for Zstandard, is a fast lossless compression algorithm, targeting real-time compression scenarios at zlib-level compression ratio.
|
**Zstd**, short for Zstandard, is a fast lossless compression algorithm, targeting real-time compression scenarios at zlib-level and better compression ratios.
|
||||||
|
|
||||||
It is provided as a BSD-license package, hosted on Github.
|
It is provided as a BSD-license package, hosted on Github.
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ It is provided as a BSD-license package, hosted on Github.
|
|||||||
|master | [](https://travis-ci.org/Cyan4973/zstd) |
|
|master | [](https://travis-ci.org/Cyan4973/zstd) |
|
||||||
|dev | [](https://travis-ci.org/Cyan4973/zstd) |
|
|dev | [](https://travis-ci.org/Cyan4973/zstd) |
|
||||||
|
|
||||||
As a reference, several fast compression algorithms were tested and compared to [zlib] on a Core i7-3930K CPU @ 4.5GHz, using [lzbench], an open-source in-memory benchmark by @inikep compiled with gcc 5.2.1, on the [Silesia compression corpus].
|
As a reference, several fast compression algorithms were tested and compared on a Core i7-3930K CPU @ 4.5GHz, using [lzbench], an open-source in-memory benchmark by @inikep compiled with gcc 5.2.1, with the [Silesia compression corpus].
|
||||||
|
|
||||||
[lzbench]: https://github.com/inikep/lzbench
|
[lzbench]: https://github.com/inikep/lzbench
|
||||||
[Silesia compression corpus]: http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia
|
[Silesia compression corpus]: http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia
|
||||||
@@ -16,7 +16,7 @@ As a reference, several fast compression algorithms were tested and compared to
|
|||||||
|Name | Ratio | C.speed | D.speed |
|
|Name | Ratio | C.speed | D.speed |
|
||||||
|-----------------|-------|--------:|--------:|
|
|-----------------|-------|--------:|--------:|
|
||||||
| | | MB/s | MB/s |
|
| | | MB/s | MB/s |
|
||||||
|**zstd 0.6.0 -1**|**2.877**|**330**| **915** |
|
|**zstd 0.7.0 -1**|**2.877**|**325**| **930** |
|
||||||
| [zlib] 1.2.8 -1 | 2.730 | 95 | 360 |
|
| [zlib] 1.2.8 -1 | 2.730 | 95 | 360 |
|
||||||
| brotli -0 | 2.708 | 220 | 430 |
|
| brotli -0 | 2.708 | 220 | 430 |
|
||||||
| QuickLZ 1.5 | 2.237 | 510 | 605 |
|
| QuickLZ 1.5 | 2.237 | 510 | 605 |
|
||||||
@@ -28,16 +28,16 @@ As a reference, several fast compression algorithms were tested and compared to
|
|||||||
[zlib]:http://www.zlib.net/
|
[zlib]:http://www.zlib.net/
|
||||||
[LZ4]: http://www.lz4.org/
|
[LZ4]: http://www.lz4.org/
|
||||||
|
|
||||||
Zstd can also offer stronger compression ratio at the cost of compression speed.
|
Zstd can also offer stronger compression ratios at the cost of compression speed.
|
||||||
Speed vs Compression trade-off is configurable by small increment. Decompression speed is preserved and remain roughly the same at all settings, a property shared by most LZ compression algorithms, such as [zlib].
|
Speed vs Compression trade-off is configurable by small increment. Decompression speed is preserved and remain roughly the same at all settings, a property shared by most LZ compression algorithms, such as [zlib] or lzma.
|
||||||
|
|
||||||
The following test is run on a Core i7-3930K CPU @ 4.5GHz, using [lzbench], an open-source in-memory benchmark by @inikep compiled with gcc 5.2.1, on the [Silesia compression corpus].
|
The following tests were run on a Core i7-3930K CPU @ 4.5GHz, using [lzbench], an open-source in-memory benchmark by @inikep compiled with gcc 5.2.1, on the [Silesia compression corpus].
|
||||||
|
|
||||||
Compression Speed vs Ratio | Decompression Speed
|
Compression Speed vs Ratio | Decompression Speed
|
||||||
---------------------------|--------------------
|
---------------------------|--------------------
|
||||||
 | 
|
 | 
|
||||||
|
|
||||||
Several algorithms can produce higher compression ratio at slower speed, falling outside of the graph.
|
Several algorithms can produce higher compression ratio but at slower speed, falling outside of the graph.
|
||||||
For a larger picture including very slow modes, [click on this link](images/DCspeed5.png) .
|
For a larger picture including very slow modes, [click on this link](images/DCspeed5.png) .
|
||||||
|
|
||||||
|
|
||||||
@@ -74,8 +74,10 @@ Hence, deploying one dictionary per type of data will provide the greater benefi
|
|||||||
|
|
||||||
### Status
|
### Status
|
||||||
|
|
||||||
Zstd is in development. The internal format evolves to reach better performance. "Final Format" is projected H1 2016, and will be tagged `v1.0`. Zstd offers legacy support, meaning any data compressed by any version >= 0.1 (therefore including current one) remain decodable in the future.
|
Zstd compression format has reached "Final status". It means it is planned to become the official stable zstd format and be tagged `v1.0`. The reason it's not yet tagged `v1.0` is that it currently performs its "validation period", making sure the format holds all its promises and nothing was missed.
|
||||||
The library is also quite robust, able to withstand hazards situations, including invalid inputs. Library reliability has been tested using [Fuzz Testing](https://en.wikipedia.org/wiki/Fuzz_testing), with both [internal tools](programs/fuzzer.c) and [external ones](http://lcamtuf.coredump.cx/afl). Therefore, Zstandard is considered safe for production environments.
|
Zstd library also offers legacy decoder support. Any data compressed by any version >= `v0.1` (hence including current one) remains decodable now and in the future.
|
||||||
|
The library has been validated using strong [fuzzer tests](https://en.wikipedia.org/wiki/Fuzz_testing), including both [internal tools](programs/fuzzer.c) and [external ones](http://lcamtuf.coredump.cx/afl). It's able to withstand hazard situations, including invalid inputs.
|
||||||
|
As a consequence, Zstandard is considered safe for, and is currently used in, production environments.
|
||||||
|
|
||||||
### Branch Policy
|
### Branch Policy
|
||||||
|
|
||||||
|
|||||||
+98
-19
@@ -1,25 +1,104 @@
|
|||||||
version: 1.0.{build}
|
version: 1.0.{build}
|
||||||
configuration:
|
|
||||||
- Release
|
|
||||||
- Debug
|
|
||||||
platform:
|
|
||||||
- Win32
|
|
||||||
- x64
|
|
||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
# - PlatformToolset: v100
|
- COMPILER: "visual"
|
||||||
- PlatformToolset: v110
|
CONFIGURATION: "Debug"
|
||||||
- PlatformToolset: v120
|
PLATFORM: "x64"
|
||||||
- PlatformToolset: v140
|
- COMPILER: "visual"
|
||||||
|
CONFIGURATION: "Debug"
|
||||||
|
PLATFORM: "Win32"
|
||||||
|
- COMPILER: "visual"
|
||||||
|
CONFIGURATION: "Release"
|
||||||
|
PLATFORM: "x64"
|
||||||
|
- COMPILER: "visual"
|
||||||
|
CONFIGURATION: "Release"
|
||||||
|
PLATFORM: "Win32"
|
||||||
|
- COMPILER: "gcc"
|
||||||
|
MAKE_PARAMS: "test"
|
||||||
|
PLATFORM: "mingw64"
|
||||||
|
- COMPILER: "gcc"
|
||||||
|
MAKE_PARAMS: "test"
|
||||||
|
PLATFORM: "mingw32"
|
||||||
|
|
||||||
|
install:
|
||||||
|
- ECHO Installing %COMPILER% %PLATFORM% %CONFIGURATION%
|
||||||
|
- if [%COMPILER%]==[gcc] SET PATH_ORIGINAL=%PATH%
|
||||||
|
- if [%COMPILER%]==[gcc] (
|
||||||
|
SET "CLANG_PARAMS=-C programs zstd fullbench fuzzer zbufftest paramgrill datagen CC=clang MOREFLAGS="--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion"" &&
|
||||||
|
SET "PATH_MINGW32=c:\MinGW\bin;c:\MinGW\usr\bin" &&
|
||||||
|
SET "PATH_MINGW64=c:\msys64\mingw64\bin;c:\msys64\usr\bin" &&
|
||||||
|
COPY C:\MinGW\bin\mingw32-make.exe C:\MinGW\bin\make.exe
|
||||||
|
) else (
|
||||||
|
IF [%PLATFORM%]==[x64] (SET ADDITIONALPARAM=/p:LibraryPath="C:\Program Files\Microsoft SDKs\Windows\v7.1\lib\x64;c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64;C:\Program Files (x86)\Microsoft Visual Studio 10.0\;C:\Program Files (x86)\Microsoft Visual Studio 10.0\lib\amd64;")
|
||||||
|
)
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- cmd: >-
|
- ECHO Building %COMPILER% %PLATFORM% %CONFIGURATION%
|
||||||
ECHO PlatformToolset=%PlatformToolset%
|
- if [%PLATFORM%]==[mingw32] SET PATH=%PATH_MINGW32%;%PATH_ORIGINAL%
|
||||||
|
- if [%PLATFORM%]==[mingw64] SET PATH=%PATH_MINGW64%;%PATH_ORIGINAL%
|
||||||
|
- if [%PLATFORM%]==[mingw64] (
|
||||||
|
make clean &&
|
||||||
|
ECHO *** &&
|
||||||
|
ECHO *** Building clang &&
|
||||||
|
ECHO *** &&
|
||||||
|
ECHO make %CLANG_PARAMS% &&
|
||||||
|
make %CLANG_PARAMS% &&
|
||||||
|
COPY programs\fuzzer.exe projects\fuzzer_clang.exe &&
|
||||||
|
make clean
|
||||||
|
)
|
||||||
|
- if [%COMPILER%]==[gcc] (
|
||||||
|
ECHO *** &&
|
||||||
|
ECHO *** Building %PLATFORM% &&
|
||||||
|
ECHO *** &&
|
||||||
|
ECHO make %MAKE_PARAMS% &&
|
||||||
|
make %MAKE_PARAMS% &&
|
||||||
|
make clean
|
||||||
|
)
|
||||||
|
- if [%COMPILER%]==[visual] (
|
||||||
|
ECHO *** &&
|
||||||
|
ECHO *** Building Visual Studio 2008 %PLATFORM%\%CONFIGURATION% &&
|
||||||
|
ECHO *** &&
|
||||||
|
msbuild "projects\VS2008\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v90 /t:Clean,Build /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
||||||
|
COPY projects\VS2008\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe projects\fuzzer_VS2008_%PLATFORM%_%CONFIGURATION%.exe &&
|
||||||
|
ECHO *** &&
|
||||||
|
ECHO *** Building Visual Studio 2010 %PLATFORM%\%CONFIGURATION% &&
|
||||||
|
ECHO *** &&
|
||||||
|
msbuild "projects\VS2010\zstd.sln" %ADDITIONALPARAM% /m /verbosity:minimal /property:PlatformToolset=v100 /t:Clean,Build /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
||||||
|
COPY projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe projects\fuzzer_VS2010_%PLATFORM%_%CONFIGURATION%.exe &&
|
||||||
|
ECHO *** &&
|
||||||
|
ECHO *** Building Visual Studio 2012 %PLATFORM%\%CONFIGURATION% &&
|
||||||
|
ECHO *** &&
|
||||||
|
msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /t:Clean,Build /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
||||||
|
COPY projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe projects\fuzzer_VS2012_%PLATFORM%_%CONFIGURATION%.exe &&
|
||||||
|
ECHO *** &&
|
||||||
|
ECHO *** Building Visual Studio 2013 %PLATFORM%\%CONFIGURATION% &&
|
||||||
|
ECHO *** &&
|
||||||
|
msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v120 /t:Clean,Build /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
||||||
|
COPY projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe projects\fuzzer_VS2013_%PLATFORM%_%CONFIGURATION%.exe &&
|
||||||
|
ECHO *** &&
|
||||||
|
ECHO *** Building Visual Studio 2015 %PLATFORM%\%CONFIGURATION% &&
|
||||||
|
ECHO *** &&
|
||||||
|
msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /t:Clean,Build /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
||||||
|
COPY projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe projects\fuzzer_VS2015_%PLATFORM%_%CONFIGURATION%.exe &&
|
||||||
|
COPY projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe programs\
|
||||||
|
)
|
||||||
|
|
||||||
msbuild "visual\2013\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=%PlatformToolset% /t:Clean,Build /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
|
||||||
test_script:
|
test_script:
|
||||||
- cmd: >-
|
- ECHO Testing %COMPILER% %PLATFORM% %CONFIGURATION%
|
||||||
ECHO %APPVEYOR_BUILD_FOLDER%\visual\2013\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe %FUZZERTEST%
|
- SET FUZZERTEST=-T1mn
|
||||||
|
- if [%COMPILER%]==[gcc] (
|
||||||
SET FUZZERTEST=-T2mn
|
if [%PLATFORM%]==[mingw64] projects\fuzzer_clang.exe %FUZZERTEST%
|
||||||
|
)
|
||||||
IF %CONFIGURATION%==Release (%APPVEYOR_BUILD_FOLDER%\visual\2013\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe %FUZZERTEST%)
|
- if [%COMPILER%]==[visual] if [%CONFIGURATION%]==[Release] (
|
||||||
|
CD programs &&
|
||||||
|
SET ZSTD=./zstd.exe &&
|
||||||
|
sh -e playTests.sh --test-large-data &&
|
||||||
|
fullbench.exe -i1 &&
|
||||||
|
fullbench.exe -i1 -P0 &&
|
||||||
|
CD .. &&
|
||||||
|
projects\fuzzer_VS2008_%PLATFORM%_Release.exe %FUZZERTEST% &&
|
||||||
|
projects\fuzzer_VS2010_%PLATFORM%_Release.exe %FUZZERTEST% &&
|
||||||
|
projects\fuzzer_VS2012_%PLATFORM%_Release.exe %FUZZERTEST% &&
|
||||||
|
projects\fuzzer_VS2013_%PLATFORM%_Release.exe %FUZZERTEST% &&
|
||||||
|
projects\fuzzer_VS2015_%PLATFORM%_Release.exe %FUZZERTEST%
|
||||||
|
)
|
||||||
|
|||||||
+8
-11
@@ -43,24 +43,21 @@ VERSION?= $(LIBVER)
|
|||||||
|
|
||||||
DESTDIR?=
|
DESTDIR?=
|
||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
CPPFLAGS= -I./common
|
|
||||||
CFLAGS ?= -O3
|
|
||||||
CFLAGS += -std=c99 -Wall -Wextra -Wundef -Wshadow -Wcast-qual -Wcast-align -Wstrict-prototypes -Wstrict-aliasing=1
|
|
||||||
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MOREFLAGS)
|
|
||||||
|
|
||||||
LIBDIR ?= $(PREFIX)/lib
|
LIBDIR ?= $(PREFIX)/lib
|
||||||
INCLUDEDIR=$(PREFIX)/include
|
INCLUDEDIR=$(PREFIX)/include
|
||||||
|
|
||||||
ZSTDCOMP_FILES := compress/zstd_compress.c compress/fse_compress.c compress/huf_compress.c compress/zbuff_compress.c
|
CPPFLAGS= -I./common -DXXH_NAMESPACE=ZSTD_
|
||||||
ZSTDDECOMP_FILES := decompress/zstd_decompress.c common/fse_decompress.c decompress/huf_decompress.c decompress/zbuff_decompress.c
|
CFLAGS ?= -O3
|
||||||
ZSTDDICT_FILES := dictBuilder/zdict.c dictBuilder/divsufsort.c
|
CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef
|
||||||
ZSTD_FILES := $(ZSTDDECOMP_FILES) common/entropy_common.c common/zstd_common.c $(ZSTDCOMP_FILES) $(ZSTDDICT_FILES)
|
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MOREFLAGS)
|
||||||
ZSTD_LEGACY:= legacy/zstd_v01.c legacy/zstd_v02.c legacy/zstd_v03.c legacy/zstd_v04.c legacy/zstd_v05.c
|
|
||||||
|
|
||||||
|
ZSTD_FILES := common/*.c compress/*.c decompress/*.c dictBuilder/*.c
|
||||||
|
|
||||||
ifeq ($(ZSTD_LEGACY_SUPPORT), 0)
|
ifeq ($(ZSTD_LEGACY_SUPPORT), 0)
|
||||||
CPPFLAGS += -DZSTD_LEGACY_SUPPORT=0
|
CPPFLAGS += -DZSTD_LEGACY_SUPPORT=0
|
||||||
else
|
else
|
||||||
ZSTD_FILES+= $(ZSTD_LEGACY)
|
ZSTD_FILES+= legacy/*.c
|
||||||
CPPFLAGS += -I./legacy -DZSTD_LEGACY_SUPPORT=1
|
CPPFLAGS += -I./legacy -DZSTD_LEGACY_SUPPORT=1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
+2
-10
@@ -12,13 +12,10 @@ To build the zstd library the following files are required:
|
|||||||
- [common/error_public.h](common/error_public.h)
|
- [common/error_public.h](common/error_public.h)
|
||||||
- common/fse.h
|
- common/fse.h
|
||||||
- common/fse_decompress.c
|
- common/fse_decompress.c
|
||||||
- common/fse_static.h
|
|
||||||
- common/huf.h
|
- common/huf.h
|
||||||
- common/huf_static.h
|
|
||||||
- [common/mem.h](common/mem.h)
|
- [common/mem.h](common/mem.h)
|
||||||
- [common/zstd.h]
|
- [common/zstd.h]
|
||||||
- common/zstd_internal.h
|
- common/zstd_internal.h
|
||||||
- common/zstd_static.h
|
|
||||||
- compress/fse_compress.c
|
- compress/fse_compress.c
|
||||||
- compress/huf_compress.c
|
- compress/huf_compress.c
|
||||||
- compress/zstd_compress.c
|
- compress/zstd_compress.c
|
||||||
@@ -27,12 +24,10 @@ To build the zstd library the following files are required:
|
|||||||
- decompress/zstd_decompress.c
|
- decompress/zstd_decompress.c
|
||||||
|
|
||||||
Stable API is exposed in [common/zstd.h].
|
Stable API is exposed in [common/zstd.h].
|
||||||
Advanced and experimental API is exposed in [common/zstd_static.h].
|
Advanced and experimental API can be enabled by defining `ZSTD_STATIC_LINKING_ONLY`.
|
||||||
API elements of [common/zstd_static.h] should be used with static linking only,
|
Never use them with a dynamic library, as their definition may change in future versions.
|
||||||
as their definition may change in future version of the library.
|
|
||||||
|
|
||||||
[common/zstd.h]: common/zstd.h
|
[common/zstd.h]: common/zstd.h
|
||||||
[common/zstd_static.h]: common/zstd_static.h
|
|
||||||
|
|
||||||
|
|
||||||
#### Separate compressor and decompressor
|
#### Separate compressor and decompressor
|
||||||
@@ -47,7 +42,6 @@ This complementary API makes streaming integration easier.
|
|||||||
It is used by `zstd` command line utility, and [7zip plugin](http://mcmilk.de/projects/7-Zip-ZStd) :
|
It is used by `zstd` command line utility, and [7zip plugin](http://mcmilk.de/projects/7-Zip-ZStd) :
|
||||||
|
|
||||||
- common/zbuff.h
|
- common/zbuff.h
|
||||||
- common/zbuff_static.h
|
|
||||||
- compress/zbuff_compress.c
|
- compress/zbuff_compress.c
|
||||||
- decompress/zbuff_decompress.c
|
- decompress/zbuff_decompress.c
|
||||||
|
|
||||||
@@ -59,7 +53,6 @@ To create dictionaries from training sets :
|
|||||||
- dictBuilder/divsufsort.h
|
- dictBuilder/divsufsort.h
|
||||||
- dictBuilder/zdict.c
|
- dictBuilder/zdict.c
|
||||||
- dictBuilder/zdict.h
|
- dictBuilder/zdict.h
|
||||||
- dictBuilder/zdict_static.h
|
|
||||||
|
|
||||||
#### Miscellaneous
|
#### Miscellaneous
|
||||||
|
|
||||||
@@ -68,4 +61,3 @@ The other files are not source code. There are :
|
|||||||
- LICENSE : contains the BSD license text
|
- LICENSE : contains the BSD license text
|
||||||
- Makefile : script to compile or install zstd library (static or dynamic)
|
- Makefile : script to compile or install zstd library (static or dynamic)
|
||||||
- libzstd.pc.in : for pkg-config (make install)
|
- libzstd.pc.in : for pkg-config (make install)
|
||||||
|
|
||||||
|
|||||||
@@ -162,14 +162,12 @@ MEM_STATIC unsigned BIT_highbit32 (register U32 val)
|
|||||||
# else /* Software version */
|
# else /* Software version */
|
||||||
static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
|
static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
|
||||||
U32 v = val;
|
U32 v = val;
|
||||||
unsigned r;
|
|
||||||
v |= v >> 1;
|
v |= v >> 1;
|
||||||
v |= v >> 2;
|
v |= v >> 2;
|
||||||
v |= v >> 4;
|
v |= v >> 4;
|
||||||
v |= v >> 8;
|
v |= v >> 8;
|
||||||
v |= v >> 16;
|
v |= v >> 16;
|
||||||
r = DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
|
return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
|
||||||
return r;
|
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,8 +266,8 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
|
|||||||
bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
|
bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
|
||||||
bitD->bitContainer = MEM_readLEST(bitD->ptr);
|
bitD->bitContainer = MEM_readLEST(bitD->ptr);
|
||||||
{ BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
|
{ BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
|
||||||
if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */
|
bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
|
||||||
bitD->bitsConsumed = 8 - BIT_highbit32(lastByte); }
|
if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
|
||||||
} else {
|
} else {
|
||||||
bitD->start = (const char*)srcBuffer;
|
bitD->start = (const char*)srcBuffer;
|
||||||
bitD->ptr = bitD->start;
|
bitD->ptr = bitD->start;
|
||||||
@@ -285,8 +283,8 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
|
|||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
{ BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
|
{ BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
|
||||||
if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */
|
bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
|
||||||
bitD->bitsConsumed = 8 - BIT_highbit32(lastByte); }
|
if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
|
||||||
bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
|
bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,7 +373,7 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
|
|||||||
if status == unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */
|
if status == unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */
|
||||||
MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
|
MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
|
||||||
{
|
{
|
||||||
if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should never happen */
|
if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should not happen => corruption detected */
|
||||||
return BIT_DStream_overflow;
|
return BIT_DStream_overflow;
|
||||||
|
|
||||||
if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) {
|
if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) {
|
||||||
|
|||||||
@@ -35,12 +35,12 @@
|
|||||||
/* *************************************
|
/* *************************************
|
||||||
* Dependencies
|
* Dependencies
|
||||||
***************************************/
|
***************************************/
|
||||||
#include <stdlib.h>
|
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "fse_static.h" /* FSE_MIN_TABLELOG */
|
#include "error_private.h" /* ERR_*, ERROR */
|
||||||
#include "error_private.h"
|
#define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */
|
||||||
#include "fse.h" /* declaration of FSE_isError, FSE_getErrorName */
|
#include "fse.h" /* FSE_isError, FSE_getErrorName */
|
||||||
#include "huf.h" /* declaration of HUF_isError, HUF_getErrorName */
|
#define HUF_STATIC_LINKING_ONLY /* HUF_TABLELOG_ABSOLUTEMAX */
|
||||||
|
#include "huf.h" /* HUF_isError, HUF_getErrorName */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -156,3 +156,76 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
|
|||||||
if ((size_t)(ip-istart) > hbSize) return ERROR(srcSize_wrong);
|
if ((size_t)(ip-istart) > hbSize) return ERROR(srcSize_wrong);
|
||||||
return ip-istart;
|
return ip-istart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! HUF_readStats() :
|
||||||
|
Read compact Huffman tree, saved by HUF_writeCTable().
|
||||||
|
`huffWeight` is destination buffer.
|
||||||
|
@return : size read from `src` , or an error Code .
|
||||||
|
Note : Needed by HUF_readCTable() and HUF_readDTableXn() .
|
||||||
|
*/
|
||||||
|
size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
||||||
|
U32* nbSymbolsPtr, U32* tableLogPtr,
|
||||||
|
const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
U32 weightTotal;
|
||||||
|
const BYTE* ip = (const BYTE*) src;
|
||||||
|
size_t iSize = ip[0];
|
||||||
|
size_t oSize;
|
||||||
|
|
||||||
|
//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
|
if (iSize >= 128) { /* special header */
|
||||||
|
if (iSize >= (242)) { /* RLE */
|
||||||
|
static U32 l[14] = { 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 127, 128 };
|
||||||
|
oSize = l[iSize-242];
|
||||||
|
memset(huffWeight, 1, hwSize);
|
||||||
|
iSize = 0;
|
||||||
|
}
|
||||||
|
else { /* Incompressible */
|
||||||
|
oSize = iSize - 127;
|
||||||
|
iSize = ((oSize+1)/2);
|
||||||
|
if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
|
||||||
|
if (oSize >= hwSize) return ERROR(corruption_detected);
|
||||||
|
ip += 1;
|
||||||
|
{ U32 n;
|
||||||
|
for (n=0; n<oSize; n+=2) {
|
||||||
|
huffWeight[n] = ip[n/2] >> 4;
|
||||||
|
huffWeight[n+1] = ip[n/2] & 15;
|
||||||
|
} } } }
|
||||||
|
else { /* header compressed with FSE (normal case) */
|
||||||
|
if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
|
||||||
|
oSize = FSE_decompress(huffWeight, hwSize-1, ip+1, iSize); /* max (hwSize-1) values decoded, as last one is implied */
|
||||||
|
if (FSE_isError(oSize)) return oSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* collect weight stats */
|
||||||
|
memset(rankStats, 0, (HUF_TABLELOG_ABSOLUTEMAX + 1) * sizeof(U32));
|
||||||
|
weightTotal = 0;
|
||||||
|
{ U32 n; for (n=0; n<oSize; n++) {
|
||||||
|
if (huffWeight[n] >= HUF_TABLELOG_ABSOLUTEMAX) return ERROR(corruption_detected);
|
||||||
|
rankStats[huffWeight[n]]++;
|
||||||
|
weightTotal += (1 << huffWeight[n]) >> 1;
|
||||||
|
} }
|
||||||
|
|
||||||
|
/* get last non-null symbol weight (implied, total must be 2^n) */
|
||||||
|
{ U32 const tableLog = BIT_highbit32(weightTotal) + 1;
|
||||||
|
if (tableLog > HUF_TABLELOG_ABSOLUTEMAX) return ERROR(corruption_detected);
|
||||||
|
*tableLogPtr = tableLog;
|
||||||
|
/* determine last weight */
|
||||||
|
{ U32 const total = 1 << tableLog;
|
||||||
|
U32 const rest = total - weightTotal;
|
||||||
|
U32 const verif = 1 << BIT_highbit32(rest);
|
||||||
|
U32 const lastWeight = BIT_highbit32(rest) + 1;
|
||||||
|
if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */
|
||||||
|
huffWeight[oSize] = (BYTE)lastWeight;
|
||||||
|
rankStats[lastWeight]++;
|
||||||
|
} }
|
||||||
|
|
||||||
|
/* check tree construction validity */
|
||||||
|
if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */
|
||||||
|
|
||||||
|
/* results */
|
||||||
|
*nbSymbolsPtr = (U32)(oSize+1);
|
||||||
|
return iSize+1;
|
||||||
|
}
|
||||||
|
|||||||
@@ -102,10 +102,12 @@ ERR_STATIC const char* ERR_getErrorString(ERR_enum code)
|
|||||||
case PREFIX(dstSize_tooSmall): return "Destination buffer is too small";
|
case PREFIX(dstSize_tooSmall): return "Destination buffer is too small";
|
||||||
case PREFIX(srcSize_wrong): return "Src size incorrect";
|
case PREFIX(srcSize_wrong): return "Src size incorrect";
|
||||||
case PREFIX(corruption_detected): return "Corrupted block detected";
|
case PREFIX(corruption_detected): return "Corrupted block detected";
|
||||||
|
case PREFIX(checksum_wrong): return "Restored data doesn't match checksum";
|
||||||
case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported";
|
case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported";
|
||||||
case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large";
|
case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large";
|
||||||
case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small";
|
case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small";
|
||||||
case PREFIX(dictionary_corrupted): return "Dictionary is corrupted";
|
case PREFIX(dictionary_corrupted): return "Dictionary is corrupted";
|
||||||
|
case PREFIX(dictionary_wrong): return "Dictionary mismatch";
|
||||||
case PREFIX(maxCode):
|
case PREFIX(maxCode):
|
||||||
default: return notErrorCode;
|
default: return notErrorCode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,10 +54,12 @@ typedef enum {
|
|||||||
ZSTD_error_dstSize_tooSmall,
|
ZSTD_error_dstSize_tooSmall,
|
||||||
ZSTD_error_srcSize_wrong,
|
ZSTD_error_srcSize_wrong,
|
||||||
ZSTD_error_corruption_detected,
|
ZSTD_error_corruption_detected,
|
||||||
|
ZSTD_error_checksum_wrong,
|
||||||
ZSTD_error_tableLog_tooLarge,
|
ZSTD_error_tableLog_tooLarge,
|
||||||
ZSTD_error_maxSymbolValue_tooLarge,
|
ZSTD_error_maxSymbolValue_tooLarge,
|
||||||
ZSTD_error_maxSymbolValue_tooSmall,
|
ZSTD_error_maxSymbolValue_tooSmall,
|
||||||
ZSTD_error_dictionary_corrupted,
|
ZSTD_error_dictionary_corrupted,
|
||||||
|
ZSTD_error_dictionary_wrong,
|
||||||
ZSTD_error_maxCode
|
ZSTD_error_maxCode
|
||||||
} ZSTD_ErrorCode;
|
} ZSTD_ErrorCode;
|
||||||
|
|
||||||
|
|||||||
+351
-2
@@ -132,8 +132,8 @@ size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr, const void* src,
|
|||||||
/*! FSE_optimalTableLog():
|
/*! FSE_optimalTableLog():
|
||||||
dynamically downsize 'tableLog' when conditions are met.
|
dynamically downsize 'tableLog' when conditions are met.
|
||||||
It saves CPU time, by using smaller tables, while preserving or even improving compression ratio.
|
It saves CPU time, by using smaller tables, while preserving or even improving compression ratio.
|
||||||
@return : recommended tableLog (necessarily <= initial 'tableLog') */
|
@return : recommended tableLog (necessarily <= 'maxTableLog') */
|
||||||
unsigned FSE_optimalTableLog(unsigned tableLog, size_t srcSize, unsigned maxSymbolValue);
|
unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);
|
||||||
|
|
||||||
/*! FSE_normalizeCount():
|
/*! FSE_normalizeCount():
|
||||||
normalize counts so that sum(count[]) == Power_of_2 (2^tableLog)
|
normalize counts so that sum(count[]) == Power_of_2 (2^tableLog)
|
||||||
@@ -272,6 +272,355 @@ If there is an error, the function will return an error code, which can be teste
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef FSE_STATIC_LINKING_ONLY
|
||||||
|
|
||||||
|
/* *** Dependency *** */
|
||||||
|
#include "bitstream.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* *****************************************
|
||||||
|
* Static allocation
|
||||||
|
*******************************************/
|
||||||
|
/* FSE buffer bounds */
|
||||||
|
#define FSE_NCOUNTBOUND 512
|
||||||
|
#define FSE_BLOCKBOUND(size) (size + (size>>7))
|
||||||
|
#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
|
||||||
|
|
||||||
|
/* It is possible to statically allocate FSE CTable/DTable as a table of unsigned using below macros */
|
||||||
|
#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2))
|
||||||
|
#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<maxTableLog))
|
||||||
|
|
||||||
|
|
||||||
|
/* *****************************************
|
||||||
|
* FSE advanced API
|
||||||
|
*******************************************/
|
||||||
|
size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);
|
||||||
|
/**< same as FSE_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr */
|
||||||
|
|
||||||
|
unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus);
|
||||||
|
/**< same as FSE_optimalTableLog(), which used `minus==2` */
|
||||||
|
|
||||||
|
size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits);
|
||||||
|
/**< build a fake FSE_CTable, designed to not compress an input, where each symbol uses nbBits */
|
||||||
|
|
||||||
|
size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue);
|
||||||
|
/**< build a fake FSE_CTable, designed to compress always the same symbolValue */
|
||||||
|
|
||||||
|
size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits);
|
||||||
|
/**< build a fake FSE_DTable, designed to read an uncompressed bitstream where each symbol uses nbBits */
|
||||||
|
|
||||||
|
size_t FSE_buildDTable_rle (FSE_DTable* dt, unsigned char symbolValue);
|
||||||
|
/**< build a fake FSE_DTable, designed to always generate the same symbolValue */
|
||||||
|
|
||||||
|
|
||||||
|
/* *****************************************
|
||||||
|
* FSE symbol compression API
|
||||||
|
*******************************************/
|
||||||
|
/*!
|
||||||
|
This API consists of small unitary functions, which highly benefit from being inlined.
|
||||||
|
You will want to enable link-time-optimization to ensure these functions are properly inlined in your binary.
|
||||||
|
Visual seems to do it automatically.
|
||||||
|
For gcc or clang, you'll need to add -flto flag at compilation and linking stages.
|
||||||
|
If none of these solutions is applicable, include "fse.c" directly.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ptrdiff_t value;
|
||||||
|
const void* stateTable;
|
||||||
|
const void* symbolTT;
|
||||||
|
unsigned stateLog;
|
||||||
|
} FSE_CState_t;
|
||||||
|
|
||||||
|
static void FSE_initCState(FSE_CState_t* CStatePtr, const FSE_CTable* ct);
|
||||||
|
|
||||||
|
static void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* CStatePtr, unsigned symbol);
|
||||||
|
|
||||||
|
static void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* CStatePtr);
|
||||||
|
|
||||||
|
/**<
|
||||||
|
These functions are inner components of FSE_compress_usingCTable().
|
||||||
|
They allow the creation of custom streams, mixing multiple tables and bit sources.
|
||||||
|
|
||||||
|
A key property to keep in mind is that encoding and decoding are done **in reverse direction**.
|
||||||
|
So the first symbol you will encode is the last you will decode, like a LIFO stack.
|
||||||
|
|
||||||
|
You will need a few variables to track your CStream. They are :
|
||||||
|
|
||||||
|
FSE_CTable ct; // Provided by FSE_buildCTable()
|
||||||
|
BIT_CStream_t bitStream; // bitStream tracking structure
|
||||||
|
FSE_CState_t state; // State tracking structure (can have several)
|
||||||
|
|
||||||
|
|
||||||
|
The first thing to do is to init bitStream and state.
|
||||||
|
size_t errorCode = BIT_initCStream(&bitStream, dstBuffer, maxDstSize);
|
||||||
|
FSE_initCState(&state, ct);
|
||||||
|
|
||||||
|
Note that BIT_initCStream() can produce an error code, so its result should be tested, using FSE_isError();
|
||||||
|
You can then encode your input data, byte after byte.
|
||||||
|
FSE_encodeSymbol() outputs a maximum of 'tableLog' bits at a time.
|
||||||
|
Remember decoding will be done in reverse direction.
|
||||||
|
FSE_encodeByte(&bitStream, &state, symbol);
|
||||||
|
|
||||||
|
At any time, you can also add any bit sequence.
|
||||||
|
Note : maximum allowed nbBits is 25, for compatibility with 32-bits decoders
|
||||||
|
BIT_addBits(&bitStream, bitField, nbBits);
|
||||||
|
|
||||||
|
The above methods don't commit data to memory, they just store it into local register, for speed.
|
||||||
|
Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t).
|
||||||
|
Writing data to memory is a manual operation, performed by the flushBits function.
|
||||||
|
BIT_flushBits(&bitStream);
|
||||||
|
|
||||||
|
Your last FSE encoding operation shall be to flush your last state value(s).
|
||||||
|
FSE_flushState(&bitStream, &state);
|
||||||
|
|
||||||
|
Finally, you must close the bitStream.
|
||||||
|
The function returns the size of CStream in bytes.
|
||||||
|
If data couldn't fit into dstBuffer, it will return a 0 ( == not compressible)
|
||||||
|
If there is an error, it returns an errorCode (which can be tested using FSE_isError()).
|
||||||
|
size_t size = BIT_closeCStream(&bitStream);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* *****************************************
|
||||||
|
* FSE symbol decompression API
|
||||||
|
*******************************************/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
size_t state;
|
||||||
|
const void* table; /* precise table may vary, depending on U16 */
|
||||||
|
} FSE_DState_t;
|
||||||
|
|
||||||
|
|
||||||
|
static void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt);
|
||||||
|
|
||||||
|
static unsigned char FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);
|
||||||
|
|
||||||
|
static unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr);
|
||||||
|
|
||||||
|
/**<
|
||||||
|
Let's now decompose FSE_decompress_usingDTable() into its unitary components.
|
||||||
|
You will decode FSE-encoded symbols from the bitStream,
|
||||||
|
and also any other bitFields you put in, **in reverse order**.
|
||||||
|
|
||||||
|
You will need a few variables to track your bitStream. They are :
|
||||||
|
|
||||||
|
BIT_DStream_t DStream; // Stream context
|
||||||
|
FSE_DState_t DState; // State context. Multiple ones are possible
|
||||||
|
FSE_DTable* DTablePtr; // Decoding table, provided by FSE_buildDTable()
|
||||||
|
|
||||||
|
The first thing to do is to init the bitStream.
|
||||||
|
errorCode = BIT_initDStream(&DStream, srcBuffer, srcSize);
|
||||||
|
|
||||||
|
You should then retrieve your initial state(s)
|
||||||
|
(in reverse flushing order if you have several ones) :
|
||||||
|
errorCode = FSE_initDState(&DState, &DStream, DTablePtr);
|
||||||
|
|
||||||
|
You can then decode your data, symbol after symbol.
|
||||||
|
For information the maximum number of bits read by FSE_decodeSymbol() is 'tableLog'.
|
||||||
|
Keep in mind that symbols are decoded in reverse order, like a LIFO stack (last in, first out).
|
||||||
|
unsigned char symbol = FSE_decodeSymbol(&DState, &DStream);
|
||||||
|
|
||||||
|
You can retrieve any bitfield you eventually stored into the bitStream (in reverse order)
|
||||||
|
Note : maximum allowed nbBits is 25, for 32-bits compatibility
|
||||||
|
size_t bitField = BIT_readBits(&DStream, nbBits);
|
||||||
|
|
||||||
|
All above operations only read from local register (which size depends on size_t).
|
||||||
|
Refueling the register from memory is manually performed by the reload method.
|
||||||
|
endSignal = FSE_reloadDStream(&DStream);
|
||||||
|
|
||||||
|
BIT_reloadDStream() result tells if there is still some more data to read from DStream.
|
||||||
|
BIT_DStream_unfinished : there is still some data left into the DStream.
|
||||||
|
BIT_DStream_endOfBuffer : Dstream reached end of buffer. Its container may no longer be completely filled.
|
||||||
|
BIT_DStream_completed : Dstream reached its exact end, corresponding in general to decompression completed.
|
||||||
|
BIT_DStream_tooFar : Dstream went too far. Decompression result is corrupted.
|
||||||
|
|
||||||
|
When reaching end of buffer (BIT_DStream_endOfBuffer), progress slowly, notably if you decode multiple symbols per loop,
|
||||||
|
to properly detect the exact end of stream.
|
||||||
|
After each decoded symbol, check if DStream is fully consumed using this simple test :
|
||||||
|
BIT_reloadDStream(&DStream) >= BIT_DStream_completed
|
||||||
|
|
||||||
|
When it's done, verify decompression is fully completed, by checking both DStream and the relevant states.
|
||||||
|
Checking if DStream has reached its end is performed by :
|
||||||
|
BIT_endOfDStream(&DStream);
|
||||||
|
Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible.
|
||||||
|
FSE_endOfDState(&DState);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* *****************************************
|
||||||
|
* FSE unsafe API
|
||||||
|
*******************************************/
|
||||||
|
static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);
|
||||||
|
/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */
|
||||||
|
|
||||||
|
|
||||||
|
/* *****************************************
|
||||||
|
* Implementation of inlined functions
|
||||||
|
*******************************************/
|
||||||
|
typedef struct {
|
||||||
|
int deltaFindState;
|
||||||
|
U32 deltaNbBits;
|
||||||
|
} FSE_symbolCompressionTransform; /* total 8 bytes */
|
||||||
|
|
||||||
|
MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct)
|
||||||
|
{
|
||||||
|
const void* ptr = ct;
|
||||||
|
const U16* u16ptr = (const U16*) ptr;
|
||||||
|
const U32 tableLog = MEM_read16(ptr);
|
||||||
|
statePtr->value = (ptrdiff_t)1<<tableLog;
|
||||||
|
statePtr->stateTable = u16ptr+2;
|
||||||
|
statePtr->symbolTT = ((const U32*)ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1));
|
||||||
|
statePtr->stateLog = tableLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! FSE_initCState2() :
|
||||||
|
* Same as FSE_initCState(), but the first symbol to include (which will be the last to be read)
|
||||||
|
* uses the smallest state value possible, saving the cost of this symbol */
|
||||||
|
MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol)
|
||||||
|
{
|
||||||
|
FSE_initCState(statePtr, ct);
|
||||||
|
{ const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
|
||||||
|
const U16* stateTable = (const U16*)(statePtr->stateTable);
|
||||||
|
U32 nbBitsOut = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16);
|
||||||
|
statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits;
|
||||||
|
statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, U32 symbol)
|
||||||
|
{
|
||||||
|
const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
|
||||||
|
const U16* const stateTable = (const U16*)(statePtr->stateTable);
|
||||||
|
U32 nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16);
|
||||||
|
BIT_addBits(bitC, statePtr->value, nbBitsOut);
|
||||||
|
statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr)
|
||||||
|
{
|
||||||
|
BIT_addBits(bitC, statePtr->value, statePtr->stateLog);
|
||||||
|
BIT_flushBits(bitC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*<===== Decompression =====>*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
U16 tableLog;
|
||||||
|
U16 fastMode;
|
||||||
|
} FSE_DTableHeader; /* sizeof U32 */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned short newState;
|
||||||
|
unsigned char symbol;
|
||||||
|
unsigned char nbBits;
|
||||||
|
} FSE_decode_t; /* size == U32 */
|
||||||
|
|
||||||
|
MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt)
|
||||||
|
{
|
||||||
|
const void* ptr = dt;
|
||||||
|
const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr;
|
||||||
|
DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog);
|
||||||
|
BIT_reloadDStream(bitD);
|
||||||
|
DStatePtr->table = dt + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr)
|
||||||
|
{
|
||||||
|
FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
|
||||||
|
return DInfo.symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
|
||||||
|
{
|
||||||
|
FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
|
||||||
|
U32 const nbBits = DInfo.nbBits;
|
||||||
|
size_t const lowBits = BIT_readBits(bitD, nbBits);
|
||||||
|
DStatePtr->state = DInfo.newState + lowBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
|
||||||
|
{
|
||||||
|
FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
|
||||||
|
U32 const nbBits = DInfo.nbBits;
|
||||||
|
BYTE const symbol = DInfo.symbol;
|
||||||
|
size_t const lowBits = BIT_readBits(bitD, nbBits);
|
||||||
|
|
||||||
|
DStatePtr->state = DInfo.newState + lowBits;
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! FSE_decodeSymbolFast() :
|
||||||
|
unsafe, only works if no symbol has a probability > 50% */
|
||||||
|
MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
|
||||||
|
{
|
||||||
|
FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
|
||||||
|
U32 const nbBits = DInfo.nbBits;
|
||||||
|
BYTE const symbol = DInfo.symbol;
|
||||||
|
size_t const lowBits = BIT_readBitsFast(bitD, nbBits);
|
||||||
|
|
||||||
|
DStatePtr->state = DInfo.newState + lowBits;
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
|
||||||
|
{
|
||||||
|
return DStatePtr->state == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FSE_COMMONDEFS_ONLY
|
||||||
|
|
||||||
|
/* **************************************************************
|
||||||
|
* 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
|
||||||
|
* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */
|
||||||
|
#define FSE_MAX_MEMORY_USAGE 14
|
||||||
|
#define FSE_DEFAULT_MEMORY_USAGE 13
|
||||||
|
|
||||||
|
/*!FSE_MAX_SYMBOL_VALUE :
|
||||||
|
* Maximum symbol value authorized.
|
||||||
|
* Required for proper stack allocation */
|
||||||
|
#define FSE_MAX_SYMBOL_VALUE 255
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************************************************
|
||||||
|
* template functions type & suffix
|
||||||
|
****************************************************************/
|
||||||
|
#define FSE_FUNCTION_TYPE BYTE
|
||||||
|
#define FSE_FUNCTION_EXTENSION
|
||||||
|
#define FSE_DECODE_TYPE FSE_decode_t
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* !FSE_COMMONDEFS_ONLY */
|
||||||
|
|
||||||
|
|
||||||
|
/* ***************************************************************
|
||||||
|
* Constants
|
||||||
|
*****************************************************************/
|
||||||
|
#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2)
|
||||||
|
#define FSE_MAX_TABLESIZE (1U<<FSE_MAX_TABLELOG)
|
||||||
|
#define FSE_MAXTABLESIZE_MASK (FSE_MAX_TABLESIZE-1)
|
||||||
|
#define FSE_DEFAULT_TABLELOG (FSE_DEFAULT_MEMORY_USAGE-2)
|
||||||
|
#define FSE_MIN_TABLELOG 5
|
||||||
|
|
||||||
|
#define FSE_TABLELOG_ABSOLUTE_MAX 15
|
||||||
|
#if FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX
|
||||||
|
# error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FSE_TABLESTEP(tableSize) ((tableSize>>1) + (tableSize>>3) + 3)
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* FSE_STATIC_LINKING_ONLY */
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -58,7 +58,8 @@
|
|||||||
#include <string.h> /* memcpy, memset */
|
#include <string.h> /* memcpy, memset */
|
||||||
#include <stdio.h> /* printf (debug) */
|
#include <stdio.h> /* printf (debug) */
|
||||||
#include "bitstream.h"
|
#include "bitstream.h"
|
||||||
#include "fse_static.h"
|
#define FSE_STATIC_LINKING_ONLY
|
||||||
|
#include "fse.h"
|
||||||
|
|
||||||
|
|
||||||
/* **************************************************************
|
/* **************************************************************
|
||||||
|
|||||||
@@ -1,389 +0,0 @@
|
|||||||
/* ******************************************************************
|
|
||||||
FSE : Finite State Entropy coder
|
|
||||||
header file for static linking (only)
|
|
||||||
Copyright (C) 2013-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 :
|
|
||||||
- Source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
|
||||||
- Public forum : https://groups.google.com/forum/#!forum/lz4c
|
|
||||||
****************************************************************** */
|
|
||||||
#ifndef FSE_STATIC_H
|
|
||||||
#define FSE_STATIC_H
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* *****************************************
|
|
||||||
* Dependencies
|
|
||||||
*******************************************/
|
|
||||||
#include "fse.h"
|
|
||||||
#include "bitstream.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* *****************************************
|
|
||||||
* Static allocation
|
|
||||||
*******************************************/
|
|
||||||
/* FSE buffer bounds */
|
|
||||||
#define FSE_NCOUNTBOUND 512
|
|
||||||
#define FSE_BLOCKBOUND(size) (size + (size>>7))
|
|
||||||
#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
|
|
||||||
|
|
||||||
/* It is possible to statically allocate FSE CTable/DTable as a table of unsigned using below macros */
|
|
||||||
#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2))
|
|
||||||
#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<maxTableLog))
|
|
||||||
|
|
||||||
|
|
||||||
/* *****************************************
|
|
||||||
* FSE advanced API
|
|
||||||
*******************************************/
|
|
||||||
size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);
|
|
||||||
/* same as FSE_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr */
|
|
||||||
|
|
||||||
size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits);
|
|
||||||
/* build a fake FSE_CTable, designed to not compress an input, where each symbol uses nbBits */
|
|
||||||
|
|
||||||
size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue);
|
|
||||||
/* build a fake FSE_CTable, designed to compress always the same symbolValue */
|
|
||||||
|
|
||||||
size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits);
|
|
||||||
/* build a fake FSE_DTable, designed to read an uncompressed bitstream where each symbol uses nbBits */
|
|
||||||
|
|
||||||
size_t FSE_buildDTable_rle (FSE_DTable* dt, unsigned char symbolValue);
|
|
||||||
/* build a fake FSE_DTable, designed to always generate the same symbolValue */
|
|
||||||
|
|
||||||
|
|
||||||
/* *****************************************
|
|
||||||
* FSE symbol compression API
|
|
||||||
*******************************************/
|
|
||||||
/*!
|
|
||||||
This API consists of small unitary functions, which highly benefit from being inlined.
|
|
||||||
You will want to enable link-time-optimization to ensure these functions are properly inlined in your binary.
|
|
||||||
Visual seems to do it automatically.
|
|
||||||
For gcc or clang, you'll need to add -flto flag at compilation and linking stages.
|
|
||||||
If none of these solutions is applicable, include "fse.c" directly.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
ptrdiff_t value;
|
|
||||||
const void* stateTable;
|
|
||||||
const void* symbolTT;
|
|
||||||
unsigned stateLog;
|
|
||||||
} FSE_CState_t;
|
|
||||||
|
|
||||||
static void FSE_initCState(FSE_CState_t* CStatePtr, const FSE_CTable* ct);
|
|
||||||
|
|
||||||
static void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* CStatePtr, unsigned symbol);
|
|
||||||
|
|
||||||
static void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* CStatePtr);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
These functions are inner components of FSE_compress_usingCTable().
|
|
||||||
They allow the creation of custom streams, mixing multiple tables and bit sources.
|
|
||||||
|
|
||||||
A key property to keep in mind is that encoding and decoding are done **in reverse direction**.
|
|
||||||
So the first symbol you will encode is the last you will decode, like a LIFO stack.
|
|
||||||
|
|
||||||
You will need a few variables to track your CStream. They are :
|
|
||||||
|
|
||||||
FSE_CTable ct; // Provided by FSE_buildCTable()
|
|
||||||
BIT_CStream_t bitStream; // bitStream tracking structure
|
|
||||||
FSE_CState_t state; // State tracking structure (can have several)
|
|
||||||
|
|
||||||
|
|
||||||
The first thing to do is to init bitStream and state.
|
|
||||||
size_t errorCode = BIT_initCStream(&bitStream, dstBuffer, maxDstSize);
|
|
||||||
FSE_initCState(&state, ct);
|
|
||||||
|
|
||||||
Note that BIT_initCStream() can produce an error code, so its result should be tested, using FSE_isError();
|
|
||||||
You can then encode your input data, byte after byte.
|
|
||||||
FSE_encodeSymbol() outputs a maximum of 'tableLog' bits at a time.
|
|
||||||
Remember decoding will be done in reverse direction.
|
|
||||||
FSE_encodeByte(&bitStream, &state, symbol);
|
|
||||||
|
|
||||||
At any time, you can also add any bit sequence.
|
|
||||||
Note : maximum allowed nbBits is 25, for compatibility with 32-bits decoders
|
|
||||||
BIT_addBits(&bitStream, bitField, nbBits);
|
|
||||||
|
|
||||||
The above methods don't commit data to memory, they just store it into local register, for speed.
|
|
||||||
Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t).
|
|
||||||
Writing data to memory is a manual operation, performed by the flushBits function.
|
|
||||||
BIT_flushBits(&bitStream);
|
|
||||||
|
|
||||||
Your last FSE encoding operation shall be to flush your last state value(s).
|
|
||||||
FSE_flushState(&bitStream, &state);
|
|
||||||
|
|
||||||
Finally, you must close the bitStream.
|
|
||||||
The function returns the size of CStream in bytes.
|
|
||||||
If data couldn't fit into dstBuffer, it will return a 0 ( == not compressible)
|
|
||||||
If there is an error, it returns an errorCode (which can be tested using FSE_isError()).
|
|
||||||
size_t size = BIT_closeCStream(&bitStream);
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* *****************************************
|
|
||||||
* FSE symbol decompression API
|
|
||||||
*******************************************/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
size_t state;
|
|
||||||
const void* table; /* precise table may vary, depending on U16 */
|
|
||||||
} FSE_DState_t;
|
|
||||||
|
|
||||||
|
|
||||||
static void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt);
|
|
||||||
|
|
||||||
static unsigned char FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);
|
|
||||||
|
|
||||||
static unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Let's now decompose FSE_decompress_usingDTable() into its unitary components.
|
|
||||||
You will decode FSE-encoded symbols from the bitStream,
|
|
||||||
and also any other bitFields you put in, **in reverse order**.
|
|
||||||
|
|
||||||
You will need a few variables to track your bitStream. They are :
|
|
||||||
|
|
||||||
BIT_DStream_t DStream; // Stream context
|
|
||||||
FSE_DState_t DState; // State context. Multiple ones are possible
|
|
||||||
FSE_DTable* DTablePtr; // Decoding table, provided by FSE_buildDTable()
|
|
||||||
|
|
||||||
The first thing to do is to init the bitStream.
|
|
||||||
errorCode = BIT_initDStream(&DStream, srcBuffer, srcSize);
|
|
||||||
|
|
||||||
You should then retrieve your initial state(s)
|
|
||||||
(in reverse flushing order if you have several ones) :
|
|
||||||
errorCode = FSE_initDState(&DState, &DStream, DTablePtr);
|
|
||||||
|
|
||||||
You can then decode your data, symbol after symbol.
|
|
||||||
For information the maximum number of bits read by FSE_decodeSymbol() is 'tableLog'.
|
|
||||||
Keep in mind that symbols are decoded in reverse order, like a LIFO stack (last in, first out).
|
|
||||||
unsigned char symbol = FSE_decodeSymbol(&DState, &DStream);
|
|
||||||
|
|
||||||
You can retrieve any bitfield you eventually stored into the bitStream (in reverse order)
|
|
||||||
Note : maximum allowed nbBits is 25, for 32-bits compatibility
|
|
||||||
size_t bitField = BIT_readBits(&DStream, nbBits);
|
|
||||||
|
|
||||||
All above operations only read from local register (which size depends on size_t).
|
|
||||||
Refueling the register from memory is manually performed by the reload method.
|
|
||||||
endSignal = FSE_reloadDStream(&DStream);
|
|
||||||
|
|
||||||
BIT_reloadDStream() result tells if there is still some more data to read from DStream.
|
|
||||||
BIT_DStream_unfinished : there is still some data left into the DStream.
|
|
||||||
BIT_DStream_endOfBuffer : Dstream reached end of buffer. Its container may no longer be completely filled.
|
|
||||||
BIT_DStream_completed : Dstream reached its exact end, corresponding in general to decompression completed.
|
|
||||||
BIT_DStream_tooFar : Dstream went too far. Decompression result is corrupted.
|
|
||||||
|
|
||||||
When reaching end of buffer (BIT_DStream_endOfBuffer), progress slowly, notably if you decode multiple symbols per loop,
|
|
||||||
to properly detect the exact end of stream.
|
|
||||||
After each decoded symbol, check if DStream is fully consumed using this simple test :
|
|
||||||
BIT_reloadDStream(&DStream) >= BIT_DStream_completed
|
|
||||||
|
|
||||||
When it's done, verify decompression is fully completed, by checking both DStream and the relevant states.
|
|
||||||
Checking if DStream has reached its end is performed by :
|
|
||||||
BIT_endOfDStream(&DStream);
|
|
||||||
Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible.
|
|
||||||
FSE_endOfDState(&DState);
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* *****************************************
|
|
||||||
* FSE unsafe API
|
|
||||||
*******************************************/
|
|
||||||
static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);
|
|
||||||
/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */
|
|
||||||
|
|
||||||
|
|
||||||
/* *****************************************
|
|
||||||
* Implementation of inlined functions
|
|
||||||
*******************************************/
|
|
||||||
typedef struct {
|
|
||||||
int deltaFindState;
|
|
||||||
U32 deltaNbBits;
|
|
||||||
} FSE_symbolCompressionTransform; /* total 8 bytes */
|
|
||||||
|
|
||||||
MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct)
|
|
||||||
{
|
|
||||||
const void* ptr = ct;
|
|
||||||
const U16* u16ptr = (const U16*) ptr;
|
|
||||||
const U32 tableLog = MEM_read16(ptr);
|
|
||||||
statePtr->value = (ptrdiff_t)1<<tableLog;
|
|
||||||
statePtr->stateTable = u16ptr+2;
|
|
||||||
statePtr->symbolTT = ((const U32*)ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1));
|
|
||||||
statePtr->stateLog = tableLog;
|
|
||||||
}
|
|
||||||
|
|
||||||
MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol)
|
|
||||||
{
|
|
||||||
FSE_initCState(statePtr, ct);
|
|
||||||
{
|
|
||||||
const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
|
|
||||||
const U16* stateTable = (const U16*)(statePtr->stateTable);
|
|
||||||
U32 nbBitsOut = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16);
|
|
||||||
statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits;
|
|
||||||
statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, U32 symbol)
|
|
||||||
{
|
|
||||||
const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
|
|
||||||
const U16* const stateTable = (const U16*)(statePtr->stateTable);
|
|
||||||
U32 nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16);
|
|
||||||
BIT_addBits(bitC, statePtr->value, nbBitsOut);
|
|
||||||
statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
|
|
||||||
}
|
|
||||||
|
|
||||||
MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr)
|
|
||||||
{
|
|
||||||
BIT_addBits(bitC, statePtr->value, statePtr->stateLog);
|
|
||||||
BIT_flushBits(bitC);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*<===== Decompression =====>*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
U16 tableLog;
|
|
||||||
U16 fastMode;
|
|
||||||
} FSE_DTableHeader; /* sizeof U32 */
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned short newState;
|
|
||||||
unsigned char symbol;
|
|
||||||
unsigned char nbBits;
|
|
||||||
} FSE_decode_t; /* size == U32 */
|
|
||||||
|
|
||||||
MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt)
|
|
||||||
{
|
|
||||||
const void* ptr = dt;
|
|
||||||
const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr;
|
|
||||||
DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog);
|
|
||||||
BIT_reloadDStream(bitD);
|
|
||||||
DStatePtr->table = dt + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
MEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr)
|
|
||||||
{
|
|
||||||
FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
|
|
||||||
return DInfo.symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
MEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
|
|
||||||
{
|
|
||||||
FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
|
|
||||||
U32 const nbBits = DInfo.nbBits;
|
|
||||||
size_t const lowBits = BIT_readBits(bitD, nbBits);
|
|
||||||
DStatePtr->state = DInfo.newState + lowBits;
|
|
||||||
}
|
|
||||||
|
|
||||||
MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
|
|
||||||
{
|
|
||||||
FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
|
|
||||||
U32 const nbBits = DInfo.nbBits;
|
|
||||||
BYTE const symbol = DInfo.symbol;
|
|
||||||
size_t const lowBits = BIT_readBits(bitD, nbBits);
|
|
||||||
|
|
||||||
DStatePtr->state = DInfo.newState + lowBits;
|
|
||||||
return symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! FSE_decodeSymbolFast() :
|
|
||||||
unsafe, only works if no symbol has a probability > 50% */
|
|
||||||
MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
|
|
||||||
{
|
|
||||||
FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
|
|
||||||
U32 const nbBits = DInfo.nbBits;
|
|
||||||
BYTE const symbol = DInfo.symbol;
|
|
||||||
size_t const lowBits = BIT_readBitsFast(bitD, nbBits);
|
|
||||||
|
|
||||||
DStatePtr->state = DInfo.newState + lowBits;
|
|
||||||
return symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
|
|
||||||
{
|
|
||||||
return DStatePtr->state == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef FSE_COMMONDEFS_ONLY
|
|
||||||
|
|
||||||
/* **************************************************************
|
|
||||||
* 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
|
|
||||||
* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */
|
|
||||||
#define FSE_MAX_MEMORY_USAGE 14
|
|
||||||
#define FSE_DEFAULT_MEMORY_USAGE 13
|
|
||||||
|
|
||||||
/*!FSE_MAX_SYMBOL_VALUE :
|
|
||||||
* Maximum symbol value authorized.
|
|
||||||
* Required for proper stack allocation */
|
|
||||||
#define FSE_MAX_SYMBOL_VALUE 255
|
|
||||||
|
|
||||||
|
|
||||||
/* **************************************************************
|
|
||||||
* template functions type & suffix
|
|
||||||
****************************************************************/
|
|
||||||
#define FSE_FUNCTION_TYPE BYTE
|
|
||||||
#define FSE_FUNCTION_EXTENSION
|
|
||||||
#define FSE_DECODE_TYPE FSE_decode_t
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* !FSE_COMMONDEFS_ONLY */
|
|
||||||
|
|
||||||
|
|
||||||
/* ***************************************************************
|
|
||||||
* Constants
|
|
||||||
*****************************************************************/
|
|
||||||
#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2)
|
|
||||||
#define FSE_MAX_TABLESIZE (1U<<FSE_MAX_TABLELOG)
|
|
||||||
#define FSE_MAXTABLESIZE_MASK (FSE_MAX_TABLESIZE-1)
|
|
||||||
#define FSE_DEFAULT_TABLELOG (FSE_DEFAULT_MEMORY_USAGE-2)
|
|
||||||
#define FSE_MIN_TABLELOG 5
|
|
||||||
|
|
||||||
#define FSE_TABLELOG_ABSOLUTE_MAX 15
|
|
||||||
#if FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX
|
|
||||||
#error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define FSE_TABLESTEP(tableSize) ((tableSize>>1) + (tableSize>>3) + 3)
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* FSE_STATIC_H */
|
|
||||||
+156
-25
@@ -31,67 +31,198 @@
|
|||||||
You can contact the author at :
|
You can contact the author at :
|
||||||
- Source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
- Source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||||
****************************************************************** */
|
****************************************************************** */
|
||||||
#ifndef HUF_H
|
#ifndef HUF_H_298734234
|
||||||
#define HUF_H
|
#define HUF_H_298734234
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* ****************************************
|
/* *** Dependencies *** */
|
||||||
* Dependency
|
|
||||||
******************************************/
|
|
||||||
#include <stddef.h> /* size_t */
|
#include <stddef.h> /* size_t */
|
||||||
|
|
||||||
|
|
||||||
/* ****************************************
|
/* *** simple functions *** */
|
||||||
* HUF simple functions
|
/**
|
||||||
******************************************/
|
|
||||||
size_t HUF_compress(void* dst, size_t dstCapacity,
|
|
||||||
const void* src, size_t srcSize);
|
|
||||||
size_t HUF_decompress(void* dst, size_t dstSize,
|
|
||||||
const void* cSrc, size_t cSrcSize);
|
|
||||||
/*
|
|
||||||
HUF_compress() :
|
HUF_compress() :
|
||||||
Compress content of buffer 'src', of size 'srcSize', into destination buffer 'dst'.
|
Compress content from buffer 'src', of size 'srcSize', into buffer 'dst'.
|
||||||
'dst' buffer must be already allocated. Compression runs faster if dstCapacity >= HUF_compressBound(srcSize).
|
'dst' buffer must be already allocated.
|
||||||
Note : srcSize must be <= 128 KB
|
Compression runs faster if `dstCapacity` >= HUF_compressBound(srcSize).
|
||||||
@return : size of compressed data (<= dstCapacity)
|
`srcSize` must be <= `HUF_BLOCKSIZE_MAX` == 128 KB.
|
||||||
|
@return : size of compressed data (<= `dstCapacity`).
|
||||||
Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!!
|
Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!!
|
||||||
if return == 1, srcData is a single repeated byte symbol (RLE compression).
|
if return == 1, srcData is a single repeated byte symbol (RLE compression).
|
||||||
if HUF_isError(return), compression failed (more details using HUF_getErrorName())
|
if HUF_isError(return), compression failed (more details using HUF_getErrorName())
|
||||||
|
*/
|
||||||
|
size_t HUF_compress(void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
/**
|
||||||
HUF_decompress() :
|
HUF_decompress() :
|
||||||
Decompress HUF data from buffer 'cSrc', of size 'cSrcSize',
|
Decompress HUF data from buffer 'cSrc', of size 'cSrcSize',
|
||||||
into already allocated destination buffer 'dst', of size 'dstSize'.
|
into already allocated buffer 'dst', of minimum size 'dstSize'.
|
||||||
`dstSize` : must be the **exact** size of original (uncompressed) data.
|
`dstSize` : **must** be the ***exact*** size of original (uncompressed) data.
|
||||||
Note : in contrast with FSE, HUF_decompress can regenerate
|
Note : in contrast with FSE, HUF_decompress can regenerate
|
||||||
RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data,
|
RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data,
|
||||||
because it knows size to regenerate.
|
because it knows size to regenerate.
|
||||||
@return : size of regenerated data (== dstSize)
|
@return : size of regenerated data (== dstSize),
|
||||||
or an error code, which can be tested using HUF_isError()
|
or an error code, which can be tested using HUF_isError()
|
||||||
*/
|
*/
|
||||||
|
size_t HUF_decompress(void* dst, size_t dstSize,
|
||||||
|
const void* cSrc, size_t cSrcSize);
|
||||||
|
|
||||||
|
|
||||||
/* ****************************************
|
/* ****************************************
|
||||||
* Tool functions
|
* Tool functions
|
||||||
******************************************/
|
******************************************/
|
||||||
size_t HUF_compressBound(size_t size); /**< maximum compressed size */
|
#define HUF_BLOCKSIZE_MAX (128 * 1024)
|
||||||
|
size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */
|
||||||
|
|
||||||
/* Error Management */
|
/* Error Management */
|
||||||
unsigned HUF_isError(size_t code); /**< tells if a return value is an error code */
|
unsigned HUF_isError(size_t code); /**< tells if a return value is an error code */
|
||||||
const char* HUF_getErrorName(size_t code); /**< provides error code string (useful for debugging) */
|
const char* HUF_getErrorName(size_t code); /**< provides error code string (useful for debugging) */
|
||||||
|
|
||||||
|
|
||||||
/* ****************************************
|
/* *** Advanced function *** */
|
||||||
* Advanced functions
|
|
||||||
******************************************/
|
/** HUF_compress2() :
|
||||||
|
* Same as HUF_compress(), but offers direct control over `maxSymbolValue` and `tableLog` */
|
||||||
size_t HUF_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
|
size_t HUF_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HUF_STATIC_LINKING_ONLY
|
||||||
|
|
||||||
|
/* *** Dependencies *** */
|
||||||
|
#include "mem.h" /* U32 */
|
||||||
|
|
||||||
|
|
||||||
|
/* *** Constants *** */
|
||||||
|
#define HUF_TABLELOG_ABSOLUTEMAX 16 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
|
||||||
|
#define HUF_TABLELOG_MAX 12 /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */
|
||||||
|
#define HUF_TABLELOG_DEFAULT HUF_TABLELOG_MAX /* tableLog by default, when not specified */
|
||||||
|
#define HUF_SYMBOLVALUE_MAX 255
|
||||||
|
#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX)
|
||||||
|
# error "HUF_TABLELOG_MAX is too large !"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ****************************************
|
||||||
|
* Static allocation
|
||||||
|
******************************************/
|
||||||
|
/* HUF buffer bounds */
|
||||||
|
#define HUF_CTABLEBOUND 129
|
||||||
|
#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true if incompressible pre-filtered with fast heuristic */
|
||||||
|
#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
|
||||||
|
|
||||||
|
/* static allocation of HUF's Compression Table */
|
||||||
|
#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \
|
||||||
|
U32 name##hb[maxSymbolValue+1]; \
|
||||||
|
void* name##hv = &(name##hb); \
|
||||||
|
HUF_CElt* name = (HUF_CElt*)(name##hv) /* no final ; */
|
||||||
|
|
||||||
|
/* static allocation of HUF's DTable */
|
||||||
|
typedef U32 HUF_DTable;
|
||||||
|
#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<(maxTableLog)))
|
||||||
|
#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \
|
||||||
|
HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1)*0x1000001) }
|
||||||
|
#define HUF_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) \
|
||||||
|
HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog)*0x1000001) }
|
||||||
|
|
||||||
|
|
||||||
|
/* ****************************************
|
||||||
|
* Advanced decompression functions
|
||||||
|
******************************************/
|
||||||
|
size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */
|
||||||
|
size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */
|
||||||
|
|
||||||
|
size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
|
||||||
|
size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< considers RLE and uncompressed as errors */
|
||||||
|
size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */
|
||||||
|
size_t HUF_decompress4X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */
|
||||||
|
|
||||||
|
size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
|
||||||
|
size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */
|
||||||
|
size_t HUF_decompress1X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */
|
||||||
|
|
||||||
|
|
||||||
|
/* ****************************************
|
||||||
|
* HUF detailed API
|
||||||
|
******************************************/
|
||||||
|
/*!
|
||||||
|
HUF_compress() does the following:
|
||||||
|
1. count symbol occurrence from source[] into table count[] using FSE_count()
|
||||||
|
2. (optional) refine tableLog using HUF_optimalTableLog()
|
||||||
|
3. build Huffman table from count using HUF_buildCTable()
|
||||||
|
4. save Huffman table to memory buffer using HUF_writeCTable()
|
||||||
|
5. encode the data stream using HUF_compress4X_usingCTable()
|
||||||
|
|
||||||
|
The following API allows targeting specific sub-functions for advanced tasks.
|
||||||
|
For example, it's possible to compress several blocks using the same 'CTable',
|
||||||
|
or to save and regenerate 'CTable' using external methods.
|
||||||
|
*/
|
||||||
|
/* FSE_count() : find it within "fse.h" */
|
||||||
|
unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);
|
||||||
|
typedef struct HUF_CElt_s HUF_CElt; /* incomplete type */
|
||||||
|
size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits);
|
||||||
|
size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog);
|
||||||
|
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
|
||||||
|
|
||||||
|
|
||||||
|
/*! HUF_readStats() :
|
||||||
|
Read compact Huffman tree, saved by HUF_writeCTable().
|
||||||
|
`huffWeight` is destination buffer.
|
||||||
|
@return : size read from `src` , or an error Code .
|
||||||
|
Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */
|
||||||
|
size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
||||||
|
U32* nbSymbolsPtr, U32* tableLogPtr,
|
||||||
|
const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
/** HUF_readCTable() :
|
||||||
|
* Loading a CTable saved with HUF_writeCTable() */
|
||||||
|
size_t HUF_readCTable (HUF_CElt* CTable, unsigned maxSymbolValue, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
HUF_decompress() does the following:
|
||||||
|
1. select the decompression algorithm (X2, X4) based on pre-computed heuristics
|
||||||
|
2. build Huffman table from save, using HUF_readDTableXn()
|
||||||
|
3. decode 1 or 4 segments in parallel using HUF_decompressSXn_usingDTable
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** HUF_selectDecoder() :
|
||||||
|
* Tells which decoder is likely to decode faster,
|
||||||
|
* based on a set of pre-determined metrics.
|
||||||
|
* @return : 0==HUF_decompress4X2, 1==HUF_decompress4X4 .
|
||||||
|
* Assumption : 0 < cSrcSize < dstSize <= 128 KB */
|
||||||
|
U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize);
|
||||||
|
|
||||||
|
size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize);
|
||||||
|
size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
|
||||||
|
size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
|
||||||
|
size_t HUF_decompress4X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
|
||||||
|
|
||||||
|
|
||||||
|
/* single stream variants */
|
||||||
|
|
||||||
|
size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
|
||||||
|
size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
|
||||||
|
|
||||||
|
size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */
|
||||||
|
size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */
|
||||||
|
|
||||||
|
size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
|
||||||
|
size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
|
||||||
|
size_t HUF_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* HUF_STATIC_LINKING_ONLY */
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* HUF_H */
|
#endif /* HUF_H_298734234 */
|
||||||
|
|||||||
@@ -1,227 +0,0 @@
|
|||||||
/* ******************************************************************
|
|
||||||
Huffman codec, part of New Generation Entropy library
|
|
||||||
header file, for static linking only
|
|
||||||
Copyright (C) 2013-2016, 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 :
|
|
||||||
- Source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
|
||||||
****************************************************************** */
|
|
||||||
#ifndef HUF_STATIC_H
|
|
||||||
#define HUF_STATIC_H
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ****************************************
|
|
||||||
* Dependency
|
|
||||||
******************************************/
|
|
||||||
#include "huf.h"
|
|
||||||
#include "fse.h"
|
|
||||||
#include "bitstream.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ****************************************
|
|
||||||
* Static allocation
|
|
||||||
******************************************/
|
|
||||||
/* HUF buffer bounds */
|
|
||||||
#define HUF_CTABLEBOUND 129
|
|
||||||
#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true if incompressible pre-filtered with fast heuristic */
|
|
||||||
#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
|
|
||||||
|
|
||||||
/* static allocation of HUF's Compression Table */
|
|
||||||
#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \
|
|
||||||
U32 name##hb[maxSymbolValue+1]; \
|
|
||||||
void* name##hv = &(name##hb); \
|
|
||||||
HUF_CElt* name = (HUF_CElt*)(name##hv) /* no final ; */
|
|
||||||
|
|
||||||
/* static allocation of HUF's DTable */
|
|
||||||
#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<maxTableLog))
|
|
||||||
#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \
|
|
||||||
unsigned short DTable[HUF_DTABLE_SIZE(maxTableLog)] = { maxTableLog }
|
|
||||||
#define HUF_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) \
|
|
||||||
unsigned int DTable[HUF_DTABLE_SIZE(maxTableLog)] = { maxTableLog }
|
|
||||||
#define HUF_CREATE_STATIC_DTABLEX6(DTable, maxTableLog) \
|
|
||||||
unsigned int DTable[HUF_DTABLE_SIZE(maxTableLog) * 3 / 2] = { maxTableLog }
|
|
||||||
|
|
||||||
|
|
||||||
/* ****************************************
|
|
||||||
* Advanced decompression functions
|
|
||||||
******************************************/
|
|
||||||
size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */
|
|
||||||
size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbols decoder */
|
|
||||||
size_t HUF_decompress4X6 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* quad-symbols decoder, only works for dstSize >= 64 */
|
|
||||||
|
|
||||||
|
|
||||||
/* ****************************************
|
|
||||||
* HUF detailed API
|
|
||||||
******************************************/
|
|
||||||
/*!
|
|
||||||
HUF_compress() does the following:
|
|
||||||
1. count symbol occurrence from source[] into table count[] using FSE_count()
|
|
||||||
2. build Huffman table from count using HUF_buildCTable()
|
|
||||||
3. save Huffman table to memory buffer using HUF_writeCTable()
|
|
||||||
4. encode the data stream using HUF_compress4X_usingCTable()
|
|
||||||
|
|
||||||
The following API allows targeting specific sub-functions for advanced tasks.
|
|
||||||
For example, it's possible to compress several blocks using the same 'CTable',
|
|
||||||
or to save and regenerate 'CTable' using external methods.
|
|
||||||
*/
|
|
||||||
/* FSE_count() : find it within "fse.h" */
|
|
||||||
typedef struct HUF_CElt_s HUF_CElt; /* incomplete type */
|
|
||||||
size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits);
|
|
||||||
size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog);
|
|
||||||
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
HUF_decompress() does the following:
|
|
||||||
1. select the decompression algorithm (X2, X4, X6) based on pre-computed heuristics
|
|
||||||
2. build Huffman table from save, using HUF_readDTableXn()
|
|
||||||
3. decode 1 or 4 segments in parallel using HUF_decompressSXn_usingDTable
|
|
||||||
*/
|
|
||||||
size_t HUF_readDTableX2 (unsigned short* DTable, const void* src, size_t srcSize);
|
|
||||||
size_t HUF_readDTableX4 (unsigned* DTable, const void* src, size_t srcSize);
|
|
||||||
size_t HUF_readDTableX6 (unsigned* DTable, const void* src, size_t srcSize);
|
|
||||||
|
|
||||||
size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned short* DTable);
|
|
||||||
size_t HUF_decompress4X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned* DTable);
|
|
||||||
size_t HUF_decompress4X6_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned* DTable);
|
|
||||||
|
|
||||||
|
|
||||||
/* single stream variants */
|
|
||||||
|
|
||||||
size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
|
|
||||||
size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
|
|
||||||
|
|
||||||
size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */
|
|
||||||
size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */
|
|
||||||
size_t HUF_decompress1X6 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* quad-symbols decoder, only works for dstSize >= 64 */
|
|
||||||
|
|
||||||
size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned short* DTable);
|
|
||||||
size_t HUF_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned* DTable);
|
|
||||||
size_t HUF_decompress1X6_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned* DTable);
|
|
||||||
|
|
||||||
|
|
||||||
/* Loading a CTable saved with HUF_writeCTable() */
|
|
||||||
|
|
||||||
size_t HUF_readCTable (HUF_CElt* CTable, unsigned maxSymbolValue, const void* src, size_t srcSize);
|
|
||||||
|
|
||||||
|
|
||||||
/* **************************************************************
|
|
||||||
* Constants
|
|
||||||
****************************************************************/
|
|
||||||
#define HUF_ABSOLUTEMAX_TABLELOG 16 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
|
|
||||||
#define HUF_MAX_TABLELOG 12 /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */
|
|
||||||
#define HUF_DEFAULT_TABLELOG HUF_MAX_TABLELOG /* tableLog by default, when not specified */
|
|
||||||
#define HUF_MAX_SYMBOL_VALUE 255
|
|
||||||
#if (HUF_MAX_TABLELOG > HUF_ABSOLUTEMAX_TABLELOG)
|
|
||||||
# error "HUF_MAX_TABLELOG is too large !"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! HUF_readStats() :
|
|
||||||
Read compact Huffman tree, saved by HUF_writeCTable().
|
|
||||||
`huffWeight` is destination buffer.
|
|
||||||
@return : size read from `src`
|
|
||||||
*/
|
|
||||||
MEM_STATIC size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|
||||||
U32* nbSymbolsPtr, U32* tableLogPtr,
|
|
||||||
const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
U32 weightTotal;
|
|
||||||
const BYTE* ip = (const BYTE*) src;
|
|
||||||
size_t iSize = ip[0];
|
|
||||||
size_t oSize;
|
|
||||||
|
|
||||||
//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
|
|
||||||
|
|
||||||
if (iSize >= 128) { /* special header */
|
|
||||||
if (iSize >= (242)) { /* RLE */
|
|
||||||
static U32 l[14] = { 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 127, 128 };
|
|
||||||
oSize = l[iSize-242];
|
|
||||||
memset(huffWeight, 1, hwSize);
|
|
||||||
iSize = 0;
|
|
||||||
}
|
|
||||||
else { /* Incompressible */
|
|
||||||
oSize = iSize - 127;
|
|
||||||
iSize = ((oSize+1)/2);
|
|
||||||
if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
|
|
||||||
if (oSize >= hwSize) return ERROR(corruption_detected);
|
|
||||||
ip += 1;
|
|
||||||
{ U32 n;
|
|
||||||
for (n=0; n<oSize; n+=2) {
|
|
||||||
huffWeight[n] = ip[n/2] >> 4;
|
|
||||||
huffWeight[n+1] = ip[n/2] & 15;
|
|
||||||
} } } }
|
|
||||||
else { /* header compressed with FSE (normal case) */
|
|
||||||
if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
|
|
||||||
oSize = FSE_decompress(huffWeight, hwSize-1, ip+1, iSize); /* max (hwSize-1) values decoded, as last one is implied */
|
|
||||||
if (FSE_isError(oSize)) return oSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* collect weight stats */
|
|
||||||
memset(rankStats, 0, (HUF_ABSOLUTEMAX_TABLELOG + 1) * sizeof(U32));
|
|
||||||
weightTotal = 0;
|
|
||||||
{ U32 n; for (n=0; n<oSize; n++) {
|
|
||||||
if (huffWeight[n] >= HUF_ABSOLUTEMAX_TABLELOG) return ERROR(corruption_detected);
|
|
||||||
rankStats[huffWeight[n]]++;
|
|
||||||
weightTotal += (1 << huffWeight[n]) >> 1;
|
|
||||||
} }
|
|
||||||
|
|
||||||
/* get last non-null symbol weight (implied, total must be 2^n) */
|
|
||||||
{ U32 const tableLog = BIT_highbit32(weightTotal) + 1;
|
|
||||||
if (tableLog > HUF_ABSOLUTEMAX_TABLELOG) return ERROR(corruption_detected);
|
|
||||||
*tableLogPtr = tableLog;
|
|
||||||
/* determine last weight */
|
|
||||||
{ U32 const total = 1 << tableLog;
|
|
||||||
U32 const rest = total - weightTotal;
|
|
||||||
U32 const verif = 1 << BIT_highbit32(rest);
|
|
||||||
U32 const lastWeight = BIT_highbit32(rest) + 1;
|
|
||||||
if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */
|
|
||||||
huffWeight[oSize] = (BYTE)lastWeight;
|
|
||||||
rankStats[lastWeight]++;
|
|
||||||
} }
|
|
||||||
|
|
||||||
/* check tree construction validity */
|
|
||||||
if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */
|
|
||||||
|
|
||||||
/* results */
|
|
||||||
*nbSymbolsPtr = (U32)(oSize+1);
|
|
||||||
return iSize+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* HUF_STATIC_H */
|
|
||||||
+8
-2
@@ -42,13 +42,19 @@ extern "C" {
|
|||||||
/*-****************************************
|
/*-****************************************
|
||||||
* Dependencies
|
* Dependencies
|
||||||
******************************************/
|
******************************************/
|
||||||
#include <stddef.h> /* size_t, ptrdiff_t */
|
#include <stddef.h> /* size_t, ptrdiff_t */
|
||||||
#include <string.h> /* memcpy */
|
#include <string.h> /* memcpy */
|
||||||
|
#if defined(_MSC_VER) /* Visual Studio */
|
||||||
|
# include <stdlib.h> /* _byteswap_ulong */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*-****************************************
|
/*-****************************************
|
||||||
* Compiler specifics
|
* Compiler specifics
|
||||||
******************************************/
|
******************************************/
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# include <intrin.h> /* _byteswap_ */
|
||||||
|
#endif
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
# define MEM_STATIC static __attribute__((unused))
|
# define MEM_STATIC static __attribute__((unused))
|
||||||
#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
||||||
|
|||||||
@@ -1,41 +1,42 @@
|
|||||||
/*
|
/*
|
||||||
xxHash - Fast Hash algorithm
|
* xxHash - Fast Hash algorithm
|
||||||
Copyright (C) 2012-2016, Yann Collet
|
* Copyright (C) 2012-2016, Yann Collet
|
||||||
|
*
|
||||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||||
|
*
|
||||||
Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
met:
|
* met:
|
||||||
|
*
|
||||||
* Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* Redistributions in binary form must reproduce the above
|
* * Redistributions in binary form must reproduce the above
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
in the documentation and/or other materials provided with the
|
* in the documentation and/or other materials provided with the
|
||||||
distribution.
|
* distribution.
|
||||||
|
*
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
You can contact the author at :
|
* You can contact the author at :
|
||||||
- xxHash source repository : https://github.com/Cyan4973/xxHash
|
* - xxHash homepage: http://www.xxhash.com
|
||||||
|
* - xxHash source repository : https://github.com/Cyan4973/xxHash
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Tuning parameters
|
* Tuning parameters
|
||||||
***************************************/
|
***************************************/
|
||||||
/*!XXH_FORCE_MEMORY_ACCESS
|
/*!XXH_FORCE_MEMORY_ACCESS :
|
||||||
* By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
|
* By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
|
||||||
* Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
|
* Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
|
||||||
* The below switch allow to select different access method for improved performance.
|
* The below switch allow to select different access method for improved performance.
|
||||||
@@ -72,17 +73,40 @@ You can contact the author at :
|
|||||||
* to improve speed for Big-endian CPU.
|
* to improve speed for Big-endian CPU.
|
||||||
* This option has no impact on Little_Endian CPU.
|
* This option has no impact on Little_Endian CPU.
|
||||||
*/
|
*/
|
||||||
#define XXH_FORCE_NATIVE_FORMAT 0
|
#ifndef XXH_FORCE_NATIVE_FORMAT /* can be defined externally */
|
||||||
|
# define XXH_FORCE_NATIVE_FORMAT 0
|
||||||
/*!XXH_USELESS_ALIGN_BRANCH :
|
|
||||||
* This is a minor performance trick, only useful with lots of very small keys.
|
|
||||||
* It means : don't check for aligned/unaligned input, because performance will be the same.
|
|
||||||
* It saves one initial branch per hash.
|
|
||||||
*/
|
|
||||||
#if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
|
|
||||||
# define XXH_USELESS_ALIGN_BRANCH 1
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*!XXH_FORCE_ALIGN_CHECK :
|
||||||
|
* This is a minor performance trick, only useful with lots of very small keys.
|
||||||
|
* It means : check for aligned/unaligned input.
|
||||||
|
* The check costs one initial branch per hash; set to 0 when the input data
|
||||||
|
* is guaranteed to be aligned.
|
||||||
|
*/
|
||||||
|
#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */
|
||||||
|
# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
|
||||||
|
# define XXH_FORCE_ALIGN_CHECK 0
|
||||||
|
# else
|
||||||
|
# define XXH_FORCE_ALIGN_CHECK 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* Includes & Memory related functions
|
||||||
|
***************************************/
|
||||||
|
/* Modify the local functions below should you wish to use some other memory routines */
|
||||||
|
/* for malloc(), free() */
|
||||||
|
#include <stdlib.h>
|
||||||
|
static void* XXH_malloc(size_t s) { return malloc(s); }
|
||||||
|
static void XXH_free (void* p) { free(p); }
|
||||||
|
/* for memcpy() */
|
||||||
|
#include <string.h>
|
||||||
|
static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }
|
||||||
|
|
||||||
|
#define XXH_STATIC_LINKING_ONLY
|
||||||
|
#include "xxhash.h"
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Compiler Specific Options
|
* Compiler Specific Options
|
||||||
@@ -103,27 +127,12 @@ You can contact the author at :
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
|
||||||
* Includes & Memory related functions
|
|
||||||
***************************************/
|
|
||||||
/* Modify the local functions below should you wish to use some other memory routines */
|
|
||||||
/* for malloc(), free() */
|
|
||||||
#include <stdlib.h>
|
|
||||||
static void* XXH_malloc(size_t s) { return malloc(s); }
|
|
||||||
static void XXH_free (void* p) { free(p); }
|
|
||||||
/* for memcpy() */
|
|
||||||
#include <string.h>
|
|
||||||
static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }
|
|
||||||
|
|
||||||
#include "xxhash.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Basic Types
|
* Basic Types
|
||||||
***************************************/
|
***************************************/
|
||||||
#ifndef MEM_MODULE
|
#ifndef MEM_MODULE
|
||||||
# define MEM_MODULE
|
# define MEM_MODULE
|
||||||
# if !defined (__VMS) && ( defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ )
|
# if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
typedef uint8_t BYTE;
|
typedef uint8_t BYTE;
|
||||||
typedef uint16_t U16;
|
typedef uint16_t U16;
|
||||||
@@ -250,6 +259,11 @@ FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
|
|||||||
return XXH_readLE32_align(ptr, endian, XXH_unaligned);
|
return XXH_readLE32_align(ptr, endian, XXH_unaligned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static U32 XXH_readBE32(const void* ptr)
|
||||||
|
{
|
||||||
|
return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
|
FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
|
||||||
{
|
{
|
||||||
if (align==XXH_unaligned)
|
if (align==XXH_unaligned)
|
||||||
@@ -263,6 +277,11 @@ FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
|
|||||||
return XXH_readLE64_align(ptr, endian, XXH_unaligned);
|
return XXH_readLE64_align(ptr, endian, XXH_unaligned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static U64 XXH_readBE64(const void* ptr)
|
||||||
|
{
|
||||||
|
return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Macros
|
* Macros
|
||||||
@@ -273,17 +292,17 @@ FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
|
|||||||
/* *************************************
|
/* *************************************
|
||||||
* Constants
|
* Constants
|
||||||
***************************************/
|
***************************************/
|
||||||
#define PRIME32_1 2654435761U
|
static const U32 PRIME32_1 = 2654435761U;
|
||||||
#define PRIME32_2 2246822519U
|
static const U32 PRIME32_2 = 2246822519U;
|
||||||
#define PRIME32_3 3266489917U
|
static const U32 PRIME32_3 = 3266489917U;
|
||||||
#define PRIME32_4 668265263U
|
static const U32 PRIME32_4 = 668265263U;
|
||||||
#define PRIME32_5 374761393U
|
static const U32 PRIME32_5 = 374761393U;
|
||||||
|
|
||||||
#define PRIME64_1 11400714785074694791ULL
|
static const U64 PRIME64_1 = 11400714785074694791ULL;
|
||||||
#define PRIME64_2 14029467366897019727ULL
|
static const U64 PRIME64_2 = 14029467366897019727ULL;
|
||||||
#define PRIME64_3 1609587929392839161ULL
|
static const U64 PRIME64_3 = 1609587929392839161ULL;
|
||||||
#define PRIME64_4 9650029242287828579ULL
|
static const U64 PRIME64_4 = 9650029242287828579ULL;
|
||||||
#define PRIME64_5 2870177450012600261ULL
|
static const U64 PRIME64_5 = 2870177450012600261ULL;
|
||||||
|
|
||||||
XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
|
XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
|
||||||
|
|
||||||
@@ -291,6 +310,15 @@ XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
|
|||||||
/* ***************************
|
/* ***************************
|
||||||
* Simple Hash Functions
|
* Simple Hash Functions
|
||||||
*****************************/
|
*****************************/
|
||||||
|
|
||||||
|
static U32 XXH32_round(U32 seed, U32 input)
|
||||||
|
{
|
||||||
|
seed += input * PRIME32_2;
|
||||||
|
seed = XXH_rotl32(seed, 13);
|
||||||
|
seed *= PRIME32_1;
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align)
|
FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align)
|
||||||
{
|
{
|
||||||
const BYTE* p = (const BYTE*)input;
|
const BYTE* p = (const BYTE*)input;
|
||||||
@@ -299,60 +327,40 @@ FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH
|
|||||||
#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)
|
#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)
|
||||||
|
|
||||||
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
|
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
|
||||||
if (p==NULL)
|
if (p==NULL) {
|
||||||
{
|
|
||||||
len=0;
|
len=0;
|
||||||
bEnd=p=(const BYTE*)(size_t)16;
|
bEnd=p=(const BYTE*)(size_t)16;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (len>=16)
|
if (len>=16) {
|
||||||
{
|
|
||||||
const BYTE* const limit = bEnd - 16;
|
const BYTE* const limit = bEnd - 16;
|
||||||
U32 v1 = seed + PRIME32_1 + PRIME32_2;
|
U32 v1 = seed + PRIME32_1 + PRIME32_2;
|
||||||
U32 v2 = seed + PRIME32_2;
|
U32 v2 = seed + PRIME32_2;
|
||||||
U32 v3 = seed + 0;
|
U32 v3 = seed + 0;
|
||||||
U32 v4 = seed - PRIME32_1;
|
U32 v4 = seed - PRIME32_1;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4;
|
||||||
v1 += XXH_get32bits(p) * PRIME32_2;
|
v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4;
|
||||||
v1 = XXH_rotl32(v1, 13);
|
v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4;
|
||||||
v1 *= PRIME32_1;
|
v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4;
|
||||||
p+=4;
|
} while (p<=limit);
|
||||||
v2 += XXH_get32bits(p) * PRIME32_2;
|
|
||||||
v2 = XXH_rotl32(v2, 13);
|
|
||||||
v2 *= PRIME32_1;
|
|
||||||
p+=4;
|
|
||||||
v3 += XXH_get32bits(p) * PRIME32_2;
|
|
||||||
v3 = XXH_rotl32(v3, 13);
|
|
||||||
v3 *= PRIME32_1;
|
|
||||||
p+=4;
|
|
||||||
v4 += XXH_get32bits(p) * PRIME32_2;
|
|
||||||
v4 = XXH_rotl32(v4, 13);
|
|
||||||
v4 *= PRIME32_1;
|
|
||||||
p+=4;
|
|
||||||
}
|
|
||||||
while (p<=limit);
|
|
||||||
|
|
||||||
h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
|
h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
h32 = seed + PRIME32_5;
|
h32 = seed + PRIME32_5;
|
||||||
}
|
}
|
||||||
|
|
||||||
h32 += (U32) len;
|
h32 += (U32) len;
|
||||||
|
|
||||||
while (p+4<=bEnd)
|
while (p+4<=bEnd) {
|
||||||
{
|
|
||||||
h32 += XXH_get32bits(p) * PRIME32_3;
|
h32 += XXH_get32bits(p) * PRIME32_3;
|
||||||
h32 = XXH_rotl32(h32, 17) * PRIME32_4 ;
|
h32 = XXH_rotl32(h32, 17) * PRIME32_4 ;
|
||||||
p+=4;
|
p+=4;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (p<bEnd)
|
while (p<bEnd) {
|
||||||
{
|
|
||||||
h32 += (*p) * PRIME32_5;
|
h32 += (*p) * PRIME32_5;
|
||||||
h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
|
h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
|
||||||
p++;
|
p++;
|
||||||
@@ -372,22 +380,20 @@ XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int s
|
|||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
/* Simple version, good for code maintenance, but unfortunately slow for small inputs */
|
/* Simple version, good for code maintenance, but unfortunately slow for small inputs */
|
||||||
XXH32_state_t state;
|
XXH32_CREATESTATE_STATIC(state);
|
||||||
XXH32_reset(&state, seed);
|
XXH32_reset(state, seed);
|
||||||
XXH32_update(&state, input, len);
|
XXH32_update(state, input, len);
|
||||||
return XXH32_digest(&state);
|
return XXH32_digest(state);
|
||||||
#else
|
#else
|
||||||
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
|
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
|
||||||
|
|
||||||
# if !defined(XXH_USELESS_ALIGN_BRANCH)
|
if (XXH_FORCE_ALIGN_CHECK) {
|
||||||
if ((((size_t)input) & 3) == 0) /* Input is 4-bytes aligned, leverage the speed benefit */
|
if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */
|
||||||
{
|
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
||||||
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
|
||||||
return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
|
else
|
||||||
else
|
return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
|
||||||
return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
|
} }
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
||||||
return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
|
return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
|
||||||
@@ -396,103 +402,77 @@ XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int s
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static U64 XXH64_round(U64 acc, U64 input)
|
||||||
|
{
|
||||||
|
acc += input * PRIME64_2;
|
||||||
|
acc = XXH_rotl64(acc, 31);
|
||||||
|
acc *= PRIME64_1;
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static U64 XXH64_mergeRound(U64 acc, U64 val)
|
||||||
|
{
|
||||||
|
val = XXH64_round(0, val);
|
||||||
|
acc ^= val;
|
||||||
|
acc = acc * PRIME64_1 + PRIME64_4;
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align)
|
FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align)
|
||||||
{
|
{
|
||||||
const BYTE* p = (const BYTE*)input;
|
const BYTE* p = (const BYTE*)input;
|
||||||
const BYTE* bEnd = p + len;
|
const BYTE* const bEnd = p + len;
|
||||||
U64 h64;
|
U64 h64;
|
||||||
#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)
|
#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)
|
||||||
|
|
||||||
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
|
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
|
||||||
if (p==NULL)
|
if (p==NULL) {
|
||||||
{
|
|
||||||
len=0;
|
len=0;
|
||||||
bEnd=p=(const BYTE*)(size_t)32;
|
bEnd=p=(const BYTE*)(size_t)32;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (len>=32)
|
if (len>=32) {
|
||||||
{
|
|
||||||
const BYTE* const limit = bEnd - 32;
|
const BYTE* const limit = bEnd - 32;
|
||||||
U64 v1 = seed + PRIME64_1 + PRIME64_2;
|
U64 v1 = seed + PRIME64_1 + PRIME64_2;
|
||||||
U64 v2 = seed + PRIME64_2;
|
U64 v2 = seed + PRIME64_2;
|
||||||
U64 v3 = seed + 0;
|
U64 v3 = seed + 0;
|
||||||
U64 v4 = seed - PRIME64_1;
|
U64 v4 = seed - PRIME64_1;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8;
|
||||||
v1 += XXH_get64bits(p) * PRIME64_2;
|
v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8;
|
||||||
p+=8;
|
v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8;
|
||||||
v1 = XXH_rotl64(v1, 31);
|
v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8;
|
||||||
v1 *= PRIME64_1;
|
} while (p<=limit);
|
||||||
v2 += XXH_get64bits(p) * PRIME64_2;
|
|
||||||
p+=8;
|
|
||||||
v2 = XXH_rotl64(v2, 31);
|
|
||||||
v2 *= PRIME64_1;
|
|
||||||
v3 += XXH_get64bits(p) * PRIME64_2;
|
|
||||||
p+=8;
|
|
||||||
v3 = XXH_rotl64(v3, 31);
|
|
||||||
v3 *= PRIME64_1;
|
|
||||||
v4 += XXH_get64bits(p) * PRIME64_2;
|
|
||||||
p+=8;
|
|
||||||
v4 = XXH_rotl64(v4, 31);
|
|
||||||
v4 *= PRIME64_1;
|
|
||||||
}
|
|
||||||
while (p<=limit);
|
|
||||||
|
|
||||||
h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
|
h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
|
||||||
|
h64 = XXH64_mergeRound(h64, v1);
|
||||||
|
h64 = XXH64_mergeRound(h64, v2);
|
||||||
|
h64 = XXH64_mergeRound(h64, v3);
|
||||||
|
h64 = XXH64_mergeRound(h64, v4);
|
||||||
|
|
||||||
v1 *= PRIME64_2;
|
} else {
|
||||||
v1 = XXH_rotl64(v1, 31);
|
|
||||||
v1 *= PRIME64_1;
|
|
||||||
h64 ^= v1;
|
|
||||||
h64 = h64 * PRIME64_1 + PRIME64_4;
|
|
||||||
|
|
||||||
v2 *= PRIME64_2;
|
|
||||||
v2 = XXH_rotl64(v2, 31);
|
|
||||||
v2 *= PRIME64_1;
|
|
||||||
h64 ^= v2;
|
|
||||||
h64 = h64 * PRIME64_1 + PRIME64_4;
|
|
||||||
|
|
||||||
v3 *= PRIME64_2;
|
|
||||||
v3 = XXH_rotl64(v3, 31);
|
|
||||||
v3 *= PRIME64_1;
|
|
||||||
h64 ^= v3;
|
|
||||||
h64 = h64 * PRIME64_1 + PRIME64_4;
|
|
||||||
|
|
||||||
v4 *= PRIME64_2;
|
|
||||||
v4 = XXH_rotl64(v4, 31);
|
|
||||||
v4 *= PRIME64_1;
|
|
||||||
h64 ^= v4;
|
|
||||||
h64 = h64 * PRIME64_1 + PRIME64_4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
h64 = seed + PRIME64_5;
|
h64 = seed + PRIME64_5;
|
||||||
}
|
}
|
||||||
|
|
||||||
h64 += (U64) len;
|
h64 += (U64) len;
|
||||||
|
|
||||||
while (p+8<=bEnd)
|
while (p+8<=bEnd) {
|
||||||
{
|
U64 const k1 = XXH64_round(0, XXH_get64bits(p));
|
||||||
U64 k1 = XXH_get64bits(p);
|
|
||||||
k1 *= PRIME64_2;
|
|
||||||
k1 = XXH_rotl64(k1,31);
|
|
||||||
k1 *= PRIME64_1;
|
|
||||||
h64 ^= k1;
|
h64 ^= k1;
|
||||||
h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
|
h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
|
||||||
p+=8;
|
p+=8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p+4<=bEnd)
|
if (p+4<=bEnd) {
|
||||||
{
|
|
||||||
h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1;
|
h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1;
|
||||||
h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
|
h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
|
||||||
p+=4;
|
p+=4;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (p<bEnd)
|
while (p<bEnd) {
|
||||||
{
|
|
||||||
h64 ^= (*p) * PRIME64_5;
|
h64 ^= (*p) * PRIME64_5;
|
||||||
h64 = XXH_rotl64(h64, 11) * PRIME64_1;
|
h64 = XXH_rotl64(h64, 11) * PRIME64_1;
|
||||||
p++;
|
p++;
|
||||||
@@ -512,22 +492,20 @@ XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned
|
|||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
/* Simple version, good for code maintenance, but unfortunately slow for small inputs */
|
/* Simple version, good for code maintenance, but unfortunately slow for small inputs */
|
||||||
XXH64_state_t state;
|
XXH64_CREATESTATE_STATIC(state);
|
||||||
XXH64_reset(&state, seed);
|
XXH64_reset(state, seed);
|
||||||
XXH64_update(&state, input, len);
|
XXH64_update(state, input, len);
|
||||||
return XXH64_digest(&state);
|
return XXH64_digest(state);
|
||||||
#else
|
#else
|
||||||
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
|
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
|
||||||
|
|
||||||
# if !defined(XXH_USELESS_ALIGN_BRANCH)
|
if (XXH_FORCE_ALIGN_CHECK) {
|
||||||
if ((((size_t)input) & 7)==0) /* Input is aligned, let's leverage the speed advantage */
|
if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */
|
||||||
{
|
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
||||||
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
|
||||||
return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
|
else
|
||||||
else
|
return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
|
||||||
return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
|
} }
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
||||||
return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
|
return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
|
||||||
@@ -536,39 +514,13 @@ XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* **************************************************
|
/* **************************************************
|
||||||
* Advanced Hash Functions
|
* Advanced Hash Functions
|
||||||
****************************************************/
|
****************************************************/
|
||||||
|
|
||||||
/*** Allocation ***/
|
|
||||||
struct XXH32_state_s
|
|
||||||
{
|
|
||||||
U64 total_len;
|
|
||||||
U32 seed;
|
|
||||||
U32 v1;
|
|
||||||
U32 v2;
|
|
||||||
U32 v3;
|
|
||||||
U32 v4;
|
|
||||||
U32 mem32[4]; /* defined as U32 for alignment */
|
|
||||||
U32 memsize;
|
|
||||||
}; /* typedef'd to XXH32_state_t within xxhash.h */
|
|
||||||
|
|
||||||
struct XXH64_state_s
|
|
||||||
{
|
|
||||||
U64 total_len;
|
|
||||||
U64 seed;
|
|
||||||
U64 v1;
|
|
||||||
U64 v2;
|
|
||||||
U64 v3;
|
|
||||||
U64 v4;
|
|
||||||
U64 mem64[4]; /* defined as U64 for alignment */
|
|
||||||
U32 memsize;
|
|
||||||
}; /* typedef'd to XXH64_state_t within xxhash.h */
|
|
||||||
|
|
||||||
|
|
||||||
XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
|
XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
|
||||||
{
|
{
|
||||||
XXH_STATIC_ASSERT(sizeof(XXH32_stateBody_t) >= sizeof(XXH32_state_t)); /* A compilation error here means XXH32_state_t is not large enough */
|
|
||||||
return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
|
return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
|
||||||
}
|
}
|
||||||
XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
|
XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
|
||||||
@@ -579,7 +531,6 @@ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
|
|||||||
|
|
||||||
XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
|
XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
|
||||||
{
|
{
|
||||||
XXH_STATIC_ASSERT(sizeof(XXH64_stateBody_t) >= sizeof(XXH64_state_t)); /* A compilation error here means XXH64_state_t is not large enough */
|
|
||||||
return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
|
return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
|
||||||
}
|
}
|
||||||
XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
|
XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
|
||||||
@@ -630,67 +581,37 @@ FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void
|
|||||||
|
|
||||||
state->total_len += len;
|
state->total_len += len;
|
||||||
|
|
||||||
if (state->memsize + len < 16) /* fill in tmp buffer */
|
if (state->memsize + len < 16) { /* fill in tmp buffer */
|
||||||
{
|
|
||||||
XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len);
|
XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len);
|
||||||
state->memsize += (U32)len;
|
state->memsize += (U32)len;
|
||||||
return XXH_OK;
|
return XXH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->memsize) /* some data left from previous update */
|
if (state->memsize) { /* some data left from previous update */
|
||||||
{
|
|
||||||
XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize);
|
XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize);
|
||||||
{
|
{ const U32* p32 = state->mem32;
|
||||||
const U32* p32 = state->mem32;
|
state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++;
|
||||||
state->v1 += XXH_readLE32(p32, endian) * PRIME32_2;
|
state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++;
|
||||||
state->v1 = XXH_rotl32(state->v1, 13);
|
state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++;
|
||||||
state->v1 *= PRIME32_1;
|
state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); p32++;
|
||||||
p32++;
|
|
||||||
state->v2 += XXH_readLE32(p32, endian) * PRIME32_2;
|
|
||||||
state->v2 = XXH_rotl32(state->v2, 13);
|
|
||||||
state->v2 *= PRIME32_1;
|
|
||||||
p32++;
|
|
||||||
state->v3 += XXH_readLE32(p32, endian) * PRIME32_2;
|
|
||||||
state->v3 = XXH_rotl32(state->v3, 13);
|
|
||||||
state->v3 *= PRIME32_1;
|
|
||||||
p32++;
|
|
||||||
state->v4 += XXH_readLE32(p32, endian) * PRIME32_2;
|
|
||||||
state->v4 = XXH_rotl32(state->v4, 13);
|
|
||||||
state->v4 *= PRIME32_1;
|
|
||||||
p32++;
|
|
||||||
}
|
}
|
||||||
p += 16-state->memsize;
|
p += 16-state->memsize;
|
||||||
state->memsize = 0;
|
state->memsize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p <= bEnd-16)
|
if (p <= bEnd-16) {
|
||||||
{
|
|
||||||
const BYTE* const limit = bEnd - 16;
|
const BYTE* const limit = bEnd - 16;
|
||||||
U32 v1 = state->v1;
|
U32 v1 = state->v1;
|
||||||
U32 v2 = state->v2;
|
U32 v2 = state->v2;
|
||||||
U32 v3 = state->v3;
|
U32 v3 = state->v3;
|
||||||
U32 v4 = state->v4;
|
U32 v4 = state->v4;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4;
|
||||||
v1 += XXH_readLE32(p, endian) * PRIME32_2;
|
v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4;
|
||||||
v1 = XXH_rotl32(v1, 13);
|
v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4;
|
||||||
v1 *= PRIME32_1;
|
v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4;
|
||||||
p+=4;
|
} while (p<=limit);
|
||||||
v2 += XXH_readLE32(p, endian) * PRIME32_2;
|
|
||||||
v2 = XXH_rotl32(v2, 13);
|
|
||||||
v2 *= PRIME32_1;
|
|
||||||
p+=4;
|
|
||||||
v3 += XXH_readLE32(p, endian) * PRIME32_2;
|
|
||||||
v3 = XXH_rotl32(v3, 13);
|
|
||||||
v3 *= PRIME32_1;
|
|
||||||
p+=4;
|
|
||||||
v4 += XXH_readLE32(p, endian) * PRIME32_2;
|
|
||||||
v4 = XXH_rotl32(v4, 13);
|
|
||||||
v4 *= PRIME32_1;
|
|
||||||
p+=4;
|
|
||||||
}
|
|
||||||
while (p<=limit);
|
|
||||||
|
|
||||||
state->v1 = v1;
|
state->v1 = v1;
|
||||||
state->v2 = v2;
|
state->v2 = v2;
|
||||||
@@ -698,8 +619,7 @@ FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void
|
|||||||
state->v4 = v4;
|
state->v4 = v4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p < bEnd)
|
if (p < bEnd) {
|
||||||
{
|
|
||||||
XXH_memcpy(state->mem32, p, bEnd-p);
|
XXH_memcpy(state->mem32, p, bEnd-p);
|
||||||
state->memsize = (int)(bEnd-p);
|
state->memsize = (int)(bEnd-p);
|
||||||
}
|
}
|
||||||
@@ -722,31 +642,26 @@ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void*
|
|||||||
FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian)
|
FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian)
|
||||||
{
|
{
|
||||||
const BYTE * p = (const BYTE*)state->mem32;
|
const BYTE * p = (const BYTE*)state->mem32;
|
||||||
const BYTE* bEnd = (const BYTE*)(state->mem32) + state->memsize;
|
const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize;
|
||||||
U32 h32;
|
U32 h32;
|
||||||
|
|
||||||
if (state->total_len >= 16)
|
if (state->total_len >= 16) {
|
||||||
{
|
|
||||||
h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
|
h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
|
||||||
}
|
} else {
|
||||||
else
|
h32 = state->seed + PRIME32_5;
|
||||||
{
|
|
||||||
h32 = state->seed + PRIME32_5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h32 += (U32) state->total_len;
|
h32 += (U32) state->total_len;
|
||||||
|
|
||||||
while (p+4<=bEnd)
|
while (p+4<=bEnd) {
|
||||||
{
|
|
||||||
h32 += XXH_readLE32(p, endian) * PRIME32_3;
|
h32 += XXH_readLE32(p, endian) * PRIME32_3;
|
||||||
h32 = XXH_rotl32(h32, 17) * PRIME32_4;
|
h32 = XXH_rotl32(h32, 17) * PRIME32_4;
|
||||||
p+=4;
|
p+=4;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (p<bEnd)
|
while (p<bEnd) {
|
||||||
{
|
|
||||||
h32 += (*p) * PRIME32_5;
|
h32 += (*p) * PRIME32_5;
|
||||||
h32 = XXH_rotl32(h32, 11) * PRIME32_1;
|
h32 = XXH_rotl32(h32, 11) * PRIME32_1;
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -771,6 +686,9 @@ XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* **** XXH64 **** */
|
||||||
|
|
||||||
FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian)
|
FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian)
|
||||||
{
|
{
|
||||||
const BYTE* p = (const BYTE*)input;
|
const BYTE* p = (const BYTE*)input;
|
||||||
@@ -782,67 +700,35 @@ FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void
|
|||||||
|
|
||||||
state->total_len += len;
|
state->total_len += len;
|
||||||
|
|
||||||
if (state->memsize + len < 32) /* fill in tmp buffer */
|
if (state->memsize + len < 32) { /* fill in tmp buffer */
|
||||||
{
|
|
||||||
XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
|
XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
|
||||||
state->memsize += (U32)len;
|
state->memsize += (U32)len;
|
||||||
return XXH_OK;
|
return XXH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->memsize) /* some data left from previous update */
|
if (state->memsize) { /* tmp buffer is full */
|
||||||
{
|
|
||||||
XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize);
|
XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize);
|
||||||
{
|
state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian));
|
||||||
const U64* p64 = state->mem64;
|
state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian));
|
||||||
state->v1 += XXH_readLE64(p64, endian) * PRIME64_2;
|
state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian));
|
||||||
state->v1 = XXH_rotl64(state->v1, 31);
|
state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian));
|
||||||
state->v1 *= PRIME64_1;
|
|
||||||
p64++;
|
|
||||||
state->v2 += XXH_readLE64(p64, endian) * PRIME64_2;
|
|
||||||
state->v2 = XXH_rotl64(state->v2, 31);
|
|
||||||
state->v2 *= PRIME64_1;
|
|
||||||
p64++;
|
|
||||||
state->v3 += XXH_readLE64(p64, endian) * PRIME64_2;
|
|
||||||
state->v3 = XXH_rotl64(state->v3, 31);
|
|
||||||
state->v3 *= PRIME64_1;
|
|
||||||
p64++;
|
|
||||||
state->v4 += XXH_readLE64(p64, endian) * PRIME64_2;
|
|
||||||
state->v4 = XXH_rotl64(state->v4, 31);
|
|
||||||
state->v4 *= PRIME64_1;
|
|
||||||
p64++;
|
|
||||||
}
|
|
||||||
p += 32-state->memsize;
|
p += 32-state->memsize;
|
||||||
state->memsize = 0;
|
state->memsize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p+32 <= bEnd)
|
if (p+32 <= bEnd) {
|
||||||
{
|
|
||||||
const BYTE* const limit = bEnd - 32;
|
const BYTE* const limit = bEnd - 32;
|
||||||
U64 v1 = state->v1;
|
U64 v1 = state->v1;
|
||||||
U64 v2 = state->v2;
|
U64 v2 = state->v2;
|
||||||
U64 v3 = state->v3;
|
U64 v3 = state->v3;
|
||||||
U64 v4 = state->v4;
|
U64 v4 = state->v4;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8;
|
||||||
v1 += XXH_readLE64(p, endian) * PRIME64_2;
|
v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8;
|
||||||
v1 = XXH_rotl64(v1, 31);
|
v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8;
|
||||||
v1 *= PRIME64_1;
|
v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8;
|
||||||
p+=8;
|
} while (p<=limit);
|
||||||
v2 += XXH_readLE64(p, endian) * PRIME64_2;
|
|
||||||
v2 = XXH_rotl64(v2, 31);
|
|
||||||
v2 *= PRIME64_1;
|
|
||||||
p+=8;
|
|
||||||
v3 += XXH_readLE64(p, endian) * PRIME64_2;
|
|
||||||
v3 = XXH_rotl64(v3, 31);
|
|
||||||
v3 *= PRIME64_1;
|
|
||||||
p+=8;
|
|
||||||
v4 += XXH_readLE64(p, endian) * PRIME64_2;
|
|
||||||
v4 = XXH_rotl64(v4, 31);
|
|
||||||
v4 *= PRIME64_1;
|
|
||||||
p+=8;
|
|
||||||
}
|
|
||||||
while (p<=limit);
|
|
||||||
|
|
||||||
state->v1 = v1;
|
state->v1 = v1;
|
||||||
state->v2 = v2;
|
state->v2 = v2;
|
||||||
@@ -850,8 +736,7 @@ FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void
|
|||||||
state->v4 = v4;
|
state->v4 = v4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p < bEnd)
|
if (p < bEnd) {
|
||||||
{
|
|
||||||
XXH_memcpy(state->mem64, p, bEnd-p);
|
XXH_memcpy(state->mem64, p, bEnd-p);
|
||||||
state->memsize = (int)(bEnd-p);
|
state->memsize = (int)(bEnd-p);
|
||||||
}
|
}
|
||||||
@@ -874,71 +759,42 @@ XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void*
|
|||||||
FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian)
|
FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian)
|
||||||
{
|
{
|
||||||
const BYTE * p = (const BYTE*)state->mem64;
|
const BYTE * p = (const BYTE*)state->mem64;
|
||||||
const BYTE* bEnd = (const BYTE*)state->mem64 + state->memsize;
|
const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize;
|
||||||
U64 h64;
|
U64 h64;
|
||||||
|
|
||||||
if (state->total_len >= 32)
|
if (state->total_len >= 32) {
|
||||||
{
|
U64 const v1 = state->v1;
|
||||||
U64 v1 = state->v1;
|
U64 const v2 = state->v2;
|
||||||
U64 v2 = state->v2;
|
U64 const v3 = state->v3;
|
||||||
U64 v3 = state->v3;
|
U64 const v4 = state->v4;
|
||||||
U64 v4 = state->v4;
|
|
||||||
|
|
||||||
h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
|
h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
|
||||||
|
h64 = XXH64_mergeRound(h64, v1);
|
||||||
v1 *= PRIME64_2;
|
h64 = XXH64_mergeRound(h64, v2);
|
||||||
v1 = XXH_rotl64(v1, 31);
|
h64 = XXH64_mergeRound(h64, v3);
|
||||||
v1 *= PRIME64_1;
|
h64 = XXH64_mergeRound(h64, v4);
|
||||||
h64 ^= v1;
|
} else {
|
||||||
h64 = h64*PRIME64_1 + PRIME64_4;
|
|
||||||
|
|
||||||
v2 *= PRIME64_2;
|
|
||||||
v2 = XXH_rotl64(v2, 31);
|
|
||||||
v2 *= PRIME64_1;
|
|
||||||
h64 ^= v2;
|
|
||||||
h64 = h64*PRIME64_1 + PRIME64_4;
|
|
||||||
|
|
||||||
v3 *= PRIME64_2;
|
|
||||||
v3 = XXH_rotl64(v3, 31);
|
|
||||||
v3 *= PRIME64_1;
|
|
||||||
h64 ^= v3;
|
|
||||||
h64 = h64*PRIME64_1 + PRIME64_4;
|
|
||||||
|
|
||||||
v4 *= PRIME64_2;
|
|
||||||
v4 = XXH_rotl64(v4, 31);
|
|
||||||
v4 *= PRIME64_1;
|
|
||||||
h64 ^= v4;
|
|
||||||
h64 = h64*PRIME64_1 + PRIME64_4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
h64 = state->seed + PRIME64_5;
|
h64 = state->seed + PRIME64_5;
|
||||||
}
|
}
|
||||||
|
|
||||||
h64 += (U64) state->total_len;
|
h64 += (U64) state->total_len;
|
||||||
|
|
||||||
while (p+8<=bEnd)
|
while (p+8<=bEnd) {
|
||||||
{
|
U64 const k1 = XXH64_round(0, XXH_readLE64(p, endian));
|
||||||
U64 k1 = XXH_readLE64(p, endian);
|
|
||||||
k1 *= PRIME64_2;
|
|
||||||
k1 = XXH_rotl64(k1,31);
|
|
||||||
k1 *= PRIME64_1;
|
|
||||||
h64 ^= k1;
|
h64 ^= k1;
|
||||||
h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
|
h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
|
||||||
p+=8;
|
p+=8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p+4<=bEnd)
|
if (p+4<=bEnd) {
|
||||||
{
|
|
||||||
h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1;
|
h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1;
|
||||||
h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
|
h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
|
||||||
p+=4;
|
p+=4;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (p<bEnd)
|
while (p<bEnd) {
|
||||||
{
|
|
||||||
h64 ^= (*p) * PRIME64_5;
|
h64 ^= (*p) * PRIME64_5;
|
||||||
h64 = XXH_rotl64(h64, 11) * PRIME64_1;
|
h64 = XXH_rotl64(h64, 11) * PRIME64_1;
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -963,3 +819,36 @@ XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************
|
||||||
|
* Canonical representation
|
||||||
|
****************************/
|
||||||
|
|
||||||
|
/*! Default XXH result types are basic unsigned 32 and 64 bits.
|
||||||
|
* The canonical representation follows human-readable write convention, aka big-endian (large digits first).
|
||||||
|
* These functions allow transformation of hash result into and from its canonical format.
|
||||||
|
* This way, hash values can be written into a file or buffer, and remain comparable across different systems and programs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)
|
||||||
|
{
|
||||||
|
XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));
|
||||||
|
if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
|
||||||
|
memcpy(dst, &hash, sizeof(*dst));
|
||||||
|
}
|
||||||
|
|
||||||
|
XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
|
||||||
|
{
|
||||||
|
XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));
|
||||||
|
if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);
|
||||||
|
memcpy(dst, &hash, sizeof(*dst));
|
||||||
|
}
|
||||||
|
|
||||||
|
XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
|
||||||
|
{
|
||||||
|
return XXH_readBE32(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)
|
||||||
|
{
|
||||||
|
return XXH_readBE64(src);
|
||||||
|
}
|
||||||
@@ -64,7 +64,8 @@ XXH64 13.8 GB/s 1.9 GB/s
|
|||||||
XXH32 6.8 GB/s 6.0 GB/s
|
XXH32 6.8 GB/s 6.0 GB/s
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#ifndef XXHASH_H_5627135585666179
|
||||||
|
#define XXHASH_H_5627135585666179 1
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -138,7 +139,7 @@ regular symbol name will be automatically translated by this header.
|
|||||||
* Version
|
* Version
|
||||||
***************************************/
|
***************************************/
|
||||||
#define XXH_VERSION_MAJOR 0
|
#define XXH_VERSION_MAJOR 0
|
||||||
#define XXH_VERSION_MINOR 5
|
#define XXH_VERSION_MINOR 6
|
||||||
#define XXH_VERSION_RELEASE 0
|
#define XXH_VERSION_RELEASE 0
|
||||||
#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
|
#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
|
||||||
XXH_PUBLIC_API unsigned XXH_versionNumber (void);
|
XXH_PUBLIC_API unsigned XXH_versionNumber (void);
|
||||||
@@ -147,9 +148,11 @@ XXH_PUBLIC_API unsigned XXH_versionNumber (void);
|
|||||||
/* ****************************
|
/* ****************************
|
||||||
* Simple Hash Functions
|
* Simple Hash Functions
|
||||||
******************************/
|
******************************/
|
||||||
|
typedef unsigned int XXH32_hash_t;
|
||||||
|
typedef unsigned long long XXH64_hash_t;
|
||||||
|
|
||||||
XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t length, unsigned int seed);
|
XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed);
|
||||||
XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t length, unsigned long long seed);
|
XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
XXH32() :
|
XXH32() :
|
||||||
@@ -165,23 +168,13 @@ XXH64() :
|
|||||||
|
|
||||||
|
|
||||||
/* ****************************
|
/* ****************************
|
||||||
* Advanced Hash Functions
|
* Streaming Hash Functions
|
||||||
******************************/
|
******************************/
|
||||||
typedef struct XXH32_state_s XXH32_state_t; /* incomplete */
|
typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */
|
||||||
typedef struct XXH64_state_s XXH64_state_t; /* incomplete */
|
typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
|
||||||
|
|
||||||
|
/*! Dynamic allocation of states
|
||||||
/*!Static allocation
|
Compatible with dynamic libraries */
|
||||||
For static linking only, do not use in the context of DLL ! */
|
|
||||||
typedef struct { long long ll[ 6]; } XXH32_stateBody_t;
|
|
||||||
typedef struct { long long ll[11]; } XXH64_stateBody_t;
|
|
||||||
|
|
||||||
#define XXH32_CREATESTATE_STATIC(name) XXH32_stateBody_t name##xxhbody; void* name##xxhvoid = &(name##xxhbody); XXH32_state_t* name = (XXH32_state_t*)(name##xxhvoid) /* no final ; */
|
|
||||||
#define XXH64_CREATESTATE_STATIC(name) XXH64_stateBody_t name##xxhbody; void* name##xxhvoid = &(name##xxhbody); XXH64_state_t* name = (XXH64_state_t*)(name##xxhvoid) /* no final ; */
|
|
||||||
|
|
||||||
|
|
||||||
/*!Dynamic allocation
|
|
||||||
To be preferred in the context of DLL */
|
|
||||||
|
|
||||||
XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);
|
XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);
|
||||||
XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
|
XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
|
||||||
@@ -194,11 +187,11 @@ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
|
|||||||
|
|
||||||
XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed);
|
XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed);
|
||||||
XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
|
XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
|
||||||
XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* statePtr);
|
XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr);
|
||||||
|
|
||||||
XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed);
|
XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed);
|
||||||
XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
|
XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
|
||||||
XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* statePtr);
|
XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
These functions generate the xxHash of an input provided in multiple segments,
|
These functions generate the xxHash of an input provided in multiple segments,
|
||||||
@@ -213,14 +206,68 @@ Obviously, input must be valid, hence allocated and read accessible.
|
|||||||
The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.
|
The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.
|
||||||
|
|
||||||
Finally, a hash value can be produced anytime, by using XXHnn_digest().
|
Finally, a hash value can be produced anytime, by using XXHnn_digest().
|
||||||
This function returns the nn-bits hash.
|
This function returns the nn-bits hash as an int or long long.
|
||||||
It's nonetheless possible to continue inserting input into the hash state
|
|
||||||
|
It's still possible to continue inserting input into the hash state after a digest,
|
||||||
and later on generate some new hashes, by calling again XXHnn_digest().
|
and later on generate some new hashes, by calling again XXHnn_digest().
|
||||||
|
|
||||||
When done, free XXH state space if it was allocated dynamically.
|
When done, free XXH state space if it was allocated dynamically.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************
|
||||||
|
* Canonical representation
|
||||||
|
****************************/
|
||||||
|
typedef struct { unsigned char digest[4]; } XXH32_canonical_t;
|
||||||
|
typedef struct { unsigned char digest[8]; } XXH64_canonical_t;
|
||||||
|
|
||||||
|
XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash);
|
||||||
|
XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);
|
||||||
|
|
||||||
|
XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
|
||||||
|
XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);
|
||||||
|
|
||||||
|
/*! Default result type for XXH functions are primitive unsigned 32 and 64 bits.
|
||||||
|
* The canonical representation uses human-readable write convention, aka big-endian (large digits first).
|
||||||
|
* These functions allow transformation of hash result into and from its canonical format.
|
||||||
|
* This way, hash values can be written into a file / memory, and remain comparable on different systems and programs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XXH_STATIC_LINKING_ONLY
|
||||||
|
|
||||||
|
/* This part contains definition which shall only be used with static linking.
|
||||||
|
The prototypes / types defined here are not guaranteed to remain stable.
|
||||||
|
They could change in a future version, becoming incompatible with a different version of the library */
|
||||||
|
|
||||||
|
struct XXH32_state_s {
|
||||||
|
unsigned long long total_len;
|
||||||
|
unsigned seed;
|
||||||
|
unsigned v1;
|
||||||
|
unsigned v2;
|
||||||
|
unsigned v3;
|
||||||
|
unsigned v4;
|
||||||
|
unsigned mem32[4]; /* buffer defined as U32 for alignment */
|
||||||
|
unsigned memsize;
|
||||||
|
}; /* typedef'd to XXH32_state_t */
|
||||||
|
|
||||||
|
struct XXH64_state_s {
|
||||||
|
unsigned long long total_len;
|
||||||
|
unsigned long long seed;
|
||||||
|
unsigned long long v1;
|
||||||
|
unsigned long long v2;
|
||||||
|
unsigned long long v3;
|
||||||
|
unsigned long long v4;
|
||||||
|
unsigned long long mem64[4]; /* buffer defined as U64 for alignment */
|
||||||
|
unsigned memsize;
|
||||||
|
}; /* typedef'd to XXH64_state_t */
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* XXHASH_H_5627135585666179 */
|
||||||
+36
-4
@@ -28,8 +28,8 @@
|
|||||||
You can contact the author at :
|
You can contact the author at :
|
||||||
- zstd homepage : http://www.zstd.net/
|
- zstd homepage : http://www.zstd.net/
|
||||||
*/
|
*/
|
||||||
#ifndef ZSTD_BUFFERED_H
|
#ifndef ZSTD_BUFFERED_H_23987
|
||||||
#define ZSTD_BUFFERED_H
|
#define ZSTD_BUFFERED_H_23987
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -38,7 +38,7 @@ extern "C" {
|
|||||||
/* *************************************
|
/* *************************************
|
||||||
* Dependencies
|
* Dependencies
|
||||||
***************************************/
|
***************************************/
|
||||||
#include <stddef.h> /* size_t */
|
#include <stddef.h> /* size_t */
|
||||||
|
|
||||||
|
|
||||||
/* ***************************************************************
|
/* ***************************************************************
|
||||||
@@ -160,8 +160,40 @@ ZSTDLIB_API size_t ZBUFF_recommendedDInSize(void);
|
|||||||
ZSTDLIB_API size_t ZBUFF_recommendedDOutSize(void);
|
ZSTDLIB_API size_t ZBUFF_recommendedDOutSize(void);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ZBUFF_STATIC_LINKING_ONLY
|
||||||
|
|
||||||
|
/* ====================================================================================
|
||||||
|
* The definitions in this section are considered experimental.
|
||||||
|
* They should never be used in association with a dynamic library, as they may change in the future.
|
||||||
|
* They are provided for advanced usages.
|
||||||
|
* Use them only in association with static linking.
|
||||||
|
* ==================================================================================== */
|
||||||
|
|
||||||
|
/*--- Dependency ---*/
|
||||||
|
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_parameters */
|
||||||
|
#include "zstd.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*--- External memory ---*/
|
||||||
|
/*! ZBUFF_createCCtx_advanced() :
|
||||||
|
* Create a ZBUFF compression context using external alloc and free functions */
|
||||||
|
ZSTDLIB_API ZBUFF_CCtx* ZBUFF_createCCtx_advanced(ZSTD_customMem customMem);
|
||||||
|
|
||||||
|
/*! ZBUFF_createDCtx_advanced() :
|
||||||
|
* Create a ZBUFF decompression context using external alloc and free functions */
|
||||||
|
ZSTDLIB_API ZBUFF_DCtx* ZBUFF_createDCtx_advanced(ZSTD_customMem customMem);
|
||||||
|
|
||||||
|
|
||||||
|
/*--- Advanced Streaming function ---*/
|
||||||
|
ZSTDLIB_API size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc,
|
||||||
|
const void* dict, size_t dictSize,
|
||||||
|
ZSTD_parameters params, U64 pledgedSrcSize);
|
||||||
|
|
||||||
|
#endif /* ZBUFF_STATIC_LINKING_ONLY */
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* ZSTD_BUFFERED_H */
|
#endif /* ZSTD_BUFFERED_H_23987 */
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
zstd - buffered version of compression library
|
|
||||||
experimental complementary API, for static linking only
|
|
||||||
Copyright (C) 2015-2016, 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 homepage : http://www.zstd.net
|
|
||||||
*/
|
|
||||||
#ifndef ZSTD_BUFFERED_STATIC_H
|
|
||||||
#define ZSTD_BUFFERED_STATIC_H
|
|
||||||
|
|
||||||
/* The objects defined into this file should be considered experimental.
|
|
||||||
* They are not labelled stable, as their prototype may change in the future.
|
|
||||||
* You can use them for tests, provide feedback, or if you can endure risk of future changes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* *************************************
|
|
||||||
* Includes
|
|
||||||
***************************************/
|
|
||||||
#include "zstd_static.h" /* ZSTD_parameters */
|
|
||||||
#include "zbuff.h"
|
|
||||||
#include "zstd_internal.h" /* MIN */
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
|
||||||
* Advanced Streaming functions
|
|
||||||
***************************************/
|
|
||||||
ZSTDLIB_API size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* cctx,
|
|
||||||
const void* dict, size_t dictSize,
|
|
||||||
ZSTD_parameters params, U64 pledgedSrcSize);
|
|
||||||
|
|
||||||
MEM_STATIC size_t ZBUFF_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
size_t length = MIN(dstCapacity, srcSize);
|
|
||||||
memcpy(dst, src, length);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ZSTD_BUFFERED_STATIC_H */
|
|
||||||
+295
-11
@@ -29,8 +29,8 @@
|
|||||||
You can contact the author at :
|
You can contact the author at :
|
||||||
- zstd source repository : https://github.com/Cyan4973/zstd
|
- zstd source repository : https://github.com/Cyan4973/zstd
|
||||||
*/
|
*/
|
||||||
#ifndef ZSTD_H
|
#ifndef ZSTD_H_235446
|
||||||
#define ZSTD_H
|
#define ZSTD_H_235446
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -60,8 +60,8 @@ extern "C" {
|
|||||||
* Version
|
* Version
|
||||||
***************************************/
|
***************************************/
|
||||||
#define ZSTD_VERSION_MAJOR 0
|
#define ZSTD_VERSION_MAJOR 0
|
||||||
#define ZSTD_VERSION_MINOR 6
|
#define ZSTD_VERSION_MINOR 7
|
||||||
#define ZSTD_VERSION_RELEASE 1
|
#define ZSTD_VERSION_RELEASE 0
|
||||||
|
|
||||||
#define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE
|
#define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE
|
||||||
#define ZSTD_QUOTE(str) #str
|
#define ZSTD_QUOTE(str) #str
|
||||||
@@ -126,12 +126,14 @@ ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); /*!< @return : error
|
|||||||
ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
|
||||||
/*-***********************
|
/*-************************
|
||||||
* Dictionary API
|
* Simple dictionary API
|
||||||
*************************/
|
***************************/
|
||||||
/*! ZSTD_compress_usingDict() :
|
/*! ZSTD_compress_usingDict() :
|
||||||
* Compression using a pre-defined Dictionary content (see dictBuilder).
|
* Compression using a pre-defined Dictionary content (see dictBuilder).
|
||||||
* Note : dict can be NULL, in which case, it's equivalent to ZSTD_compressCCtx() */
|
* Note 1 : This function load the dictionary, resulting in a significant startup time.
|
||||||
|
* Note 2 : `dict` must remain valid and unmodified during compression operation.
|
||||||
|
* Note 3 : `dict` can be `NULL`, in which case, it's equivalent to ZSTD_compressCCtx() */
|
||||||
ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
|
ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
@@ -140,16 +142,298 @@ ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
|
|||||||
|
|
||||||
/*! ZSTD_decompress_usingDict() :
|
/*! ZSTD_decompress_usingDict() :
|
||||||
* Decompression using a pre-defined Dictionary content (see dictBuilder).
|
* Decompression using a pre-defined Dictionary content (see dictBuilder).
|
||||||
* Dictionary must be identical to the one used during compression, otherwise regenerated data will be corrupted.
|
* Dictionary must be identical to the one used during compression.
|
||||||
* Note : dict can be NULL, in which case, it's equivalent to ZSTD_decompressDCtx() */
|
* Note 1 : This function load the dictionary, resulting in a significant startup time
|
||||||
|
* Note 2 : `dict` must remain valid and unmodified during compression operation.
|
||||||
|
* Note 3 : `dict` can be `NULL`, in which case, it's equivalent to ZSTD_decompressDCtx() */
|
||||||
ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
|
ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
const void* dict,size_t dictSize);
|
const void* dict,size_t dictSize);
|
||||||
|
|
||||||
|
|
||||||
|
/*-**************************
|
||||||
|
* Advanced Dictionary API
|
||||||
|
****************************/
|
||||||
|
/*! ZSTD_createCDict() :
|
||||||
|
* Create a digested dictionary, ready to start compression operation without startup delay.
|
||||||
|
* `dict` can be released after creation */
|
||||||
|
typedef struct ZSTD_CDict_s ZSTD_CDict;
|
||||||
|
ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel);
|
||||||
|
ZSTDLIB_API size_t ZSTD_freeCDict(ZSTD_CDict* CDict);
|
||||||
|
|
||||||
|
/*! ZSTD_compress_usingCDict() :
|
||||||
|
* Compression using a pre-digested Dictionary.
|
||||||
|
* Much faster than ZSTD_compress_usingDict() when same dictionary is used multiple times.
|
||||||
|
* Note that compression level is decided during dictionary creation */
|
||||||
|
ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t srcSize,
|
||||||
|
const ZSTD_CDict* cdict);
|
||||||
|
|
||||||
|
/*! ZSTD_createDDict() :
|
||||||
|
* Create a digested dictionary, ready to start decompression operation without startup delay.
|
||||||
|
* `dict` can be released after creation */
|
||||||
|
typedef struct ZSTD_DDict_s ZSTD_DDict;
|
||||||
|
ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize);
|
||||||
|
ZSTDLIB_API size_t ZSTD_freeDDict(ZSTD_DDict* ddict);
|
||||||
|
|
||||||
|
/*! ZSTD_decompress_usingDDict() :
|
||||||
|
* Decompression using a pre-digested Dictionary
|
||||||
|
* Much faster than ZSTD_decompress_usingDict() when same dictionary is used multiple times. */
|
||||||
|
ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t srcSize,
|
||||||
|
const ZSTD_DDict* ddict);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ZSTD_STATIC_LINKING_ONLY
|
||||||
|
|
||||||
|
/* ====================================================================================
|
||||||
|
* The definitions in this section are considered experimental.
|
||||||
|
* They should never be used in association with a dynamic library, as they may change in the future.
|
||||||
|
* They are provided for advanced usages.
|
||||||
|
* Use them only in association with static linking.
|
||||||
|
* ==================================================================================== */
|
||||||
|
|
||||||
|
/*--- Dependency ---*/
|
||||||
|
#include "mem.h" /* U32 */
|
||||||
|
|
||||||
|
|
||||||
|
/*--- Constants ---*/
|
||||||
|
#define ZSTD_MAGICNUMBER 0xFD2FB527 /* v0.7 */
|
||||||
|
#define ZSTD_MAGIC_SKIPPABLE_START 0x184D2A50U
|
||||||
|
|
||||||
|
#define ZSTD_WINDOWLOG_MAX ((U32)(MEM_32bits() ? 25 : 27))
|
||||||
|
#define ZSTD_WINDOWLOG_MIN 18
|
||||||
|
#define ZSTD_CHAINLOG_MAX (ZSTD_WINDOWLOG_MAX+1)
|
||||||
|
#define ZSTD_CHAINLOG_MIN 4
|
||||||
|
#define ZSTD_HASHLOG_MAX ZSTD_WINDOWLOG_MAX
|
||||||
|
#define ZSTD_HASHLOG_MIN 12
|
||||||
|
#define ZSTD_HASHLOG3_MAX 17
|
||||||
|
#define ZSTD_HASHLOG3_MIN 15
|
||||||
|
#define ZSTD_SEARCHLOG_MAX (ZSTD_WINDOWLOG_MAX-1)
|
||||||
|
#define ZSTD_SEARCHLOG_MIN 1
|
||||||
|
#define ZSTD_SEARCHLENGTH_MAX 7
|
||||||
|
#define ZSTD_SEARCHLENGTH_MIN 3
|
||||||
|
#define ZSTD_TARGETLENGTH_MIN 4
|
||||||
|
#define ZSTD_TARGETLENGTH_MAX 999
|
||||||
|
|
||||||
|
#define ZSTD_FRAMEHEADERSIZE_MAX 18 /* for static allocation */
|
||||||
|
static const size_t ZSTD_frameHeaderSize_min = 5;
|
||||||
|
static const size_t ZSTD_frameHeaderSize_max = ZSTD_FRAMEHEADERSIZE_MAX;
|
||||||
|
static const size_t ZSTD_skippableHeaderSize = 8; /* magic number + skippable frame length */
|
||||||
|
|
||||||
|
|
||||||
|
/*--- Types ---*/
|
||||||
|
typedef enum { ZSTD_fast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt } ZSTD_strategy; /*< from faster to stronger */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
U32 windowLog; /*< largest match distance : larger == more compression, more memory needed during decompression */
|
||||||
|
U32 chainLog; /*< fully searched segment : larger == more compression, slower, more memory (useless for fast) */
|
||||||
|
U32 hashLog; /*< dispatch table : larger == faster, more memory */
|
||||||
|
U32 searchLog; /*< nb of searches : larger == more compression, slower */
|
||||||
|
U32 searchLength; /*< match length searched : larger == faster decompression, sometimes less compression */
|
||||||
|
U32 targetLength; /*< acceptable match size for optimal parser (only) : larger == more compression, slower */
|
||||||
|
ZSTD_strategy strategy;
|
||||||
|
} ZSTD_compressionParameters;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
U32 contentSizeFlag; /*< 1: content size will be in frame header (if known). */
|
||||||
|
U32 checksumFlag; /*< 1: will generate a 22-bits checksum at end of frame, to be used for error detection by decompressor */
|
||||||
|
U32 noDictIDFlag; /*< 1: no dict ID will be saved into frame header (if dictionary compression) */
|
||||||
|
} ZSTD_frameParameters;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ZSTD_compressionParameters cParams;
|
||||||
|
ZSTD_frameParameters fParams;
|
||||||
|
} ZSTD_parameters;
|
||||||
|
|
||||||
|
/* custom memory allocation functions */
|
||||||
|
typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
|
||||||
|
typedef void (*ZSTD_freeFunction) (void* opaque, void* address);
|
||||||
|
typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
|
||||||
|
|
||||||
|
|
||||||
|
/*-*************************************
|
||||||
|
* Advanced compression functions
|
||||||
|
***************************************/
|
||||||
|
/*! ZSTD_createCCtx_advanced() :
|
||||||
|
* Create a ZSTD compression context using external alloc and free functions */
|
||||||
|
ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
|
||||||
|
|
||||||
|
/*! ZSTD_createCDict_advanced() :
|
||||||
|
* Create a ZSTD_CDict using external alloc and free, and customized compression parameters */
|
||||||
|
ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize,
|
||||||
|
ZSTD_parameters params, ZSTD_customMem customMem);
|
||||||
|
|
||||||
|
ZSTDLIB_API unsigned ZSTD_maxCLevel (void);
|
||||||
|
|
||||||
|
/*! ZSTD_getCParams() :
|
||||||
|
* @return ZSTD_compressionParameters structure for a selected compression level and srcSize.
|
||||||
|
* `srcSize` value is optional, select 0 if not known */
|
||||||
|
ZSTDLIB_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, U64 srcSize, size_t dictSize);
|
||||||
|
|
||||||
|
/*! ZSTD_checkParams() :
|
||||||
|
* Ensure param values remain within authorized range */
|
||||||
|
ZSTDLIB_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params);
|
||||||
|
|
||||||
|
/*! ZSTD_adjustParams() :
|
||||||
|
* optimize params for a given `srcSize` and `dictSize`.
|
||||||
|
* both values are optional, select `0` if unknown. */
|
||||||
|
ZSTDLIB_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, U64 srcSize, size_t dictSize);
|
||||||
|
|
||||||
|
/*! ZSTD_compress_advanced() :
|
||||||
|
* Same as ZSTD_compress_usingDict(), with fine-tune control of each compression parameter */
|
||||||
|
ZSTDLIB_API size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t srcSize,
|
||||||
|
const void* dict,size_t dictSize,
|
||||||
|
ZSTD_parameters params);
|
||||||
|
|
||||||
|
|
||||||
|
/*--- Advanced Decompression functions ---*/
|
||||||
|
|
||||||
|
/*! ZSTD_createDCtx_advanced() :
|
||||||
|
* Create a ZSTD decompression context using external alloc and free functions */
|
||||||
|
ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem);
|
||||||
|
|
||||||
|
|
||||||
|
/* ****************************************************************
|
||||||
|
* Streaming functions (direct mode - synchronous and buffer-less)
|
||||||
|
******************************************************************/
|
||||||
|
ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
|
||||||
|
ZSTDLIB_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
|
||||||
|
ZSTDLIB_API size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, U64 pledgedSrcSize);
|
||||||
|
ZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx);
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity);
|
||||||
|
|
||||||
|
/*
|
||||||
|
A ZSTD_CCtx object is required to track streaming operations.
|
||||||
|
Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource.
|
||||||
|
ZSTD_CCtx object can be re-used multiple times within successive compression operations.
|
||||||
|
|
||||||
|
Start by initializing a context.
|
||||||
|
Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression,
|
||||||
|
or ZSTD_compressBegin_advanced(), for finer parameter control.
|
||||||
|
It's also possible to duplicate a reference context which has already been initialized, using ZSTD_copyCCtx()
|
||||||
|
|
||||||
|
Then, consume your input using ZSTD_compressContinue().
|
||||||
|
ZSTD_compressContinue() presumes prior data is still accessible and unmodified (up to maximum distance size, see WindowLog).
|
||||||
|
The interface is synchronous, so input will be entirely consumed and produce associated compressed output.
|
||||||
|
You must ensure there is enough space in destination buffer to store compressed data under worst case scenario.
|
||||||
|
Worst case evaluation is provided by ZSTD_compressBound().
|
||||||
|
|
||||||
|
Finish a frame with ZSTD_compressEnd(), which will write the epilogue.
|
||||||
|
Without epilogue, frames will be considered unfinished (broken) by decoders.
|
||||||
|
|
||||||
|
You can then reuse ZSTD_CCtx to compress some new frame.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
U64 frameContentSize;
|
||||||
|
U32 windowSize;
|
||||||
|
U32 dictID;
|
||||||
|
U32 checksumFlag;
|
||||||
|
} ZSTD_frameParams;
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input */
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
|
||||||
|
ZSTDLIB_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
|
||||||
|
ZSTDLIB_API void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
|
||||||
|
ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Streaming decompression, direct mode (bufferless)
|
||||||
|
|
||||||
|
A ZSTD_DCtx object is required to track streaming operations.
|
||||||
|
Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
|
||||||
|
A ZSTD_DCtx object can be re-used multiple times.
|
||||||
|
|
||||||
|
First optional operation is to retrieve frame parameters, using ZSTD_getFrameParams(), which doesn't consume the input.
|
||||||
|
It can provide the minimum size of rolling buffer required to properly decompress data,
|
||||||
|
and optionally the final size of uncompressed content.
|
||||||
|
(Note : content size is an optional info that may not be present. 0 means : content size unknown)
|
||||||
|
Frame parameters are extracted from the beginning of compressed frame.
|
||||||
|
The amount of data to read is variable, from ZSTD_frameHeaderSize_min to ZSTD_frameHeaderSize_max (so if `srcSize` >= ZSTD_frameHeaderSize_max, it will always work)
|
||||||
|
If `srcSize` is too small for operation to succeed, function will return the minimum size it requires to produce a result.
|
||||||
|
Result : 0 when successful, it means the ZSTD_frameParams structure has been filled.
|
||||||
|
>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()
|
||||||
|
|
||||||
|
Start decompression, with ZSTD_decompressBegin() or ZSTD_decompressBegin_usingDict().
|
||||||
|
Alternatively, you can copy a prepared context, using ZSTD_copyDCtx().
|
||||||
|
|
||||||
|
Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively.
|
||||||
|
ZSTD_nextSrcSizeToDecompress() tells how much bytes to provide as 'srcSize' to ZSTD_decompressContinue().
|
||||||
|
ZSTD_decompressContinue() requires this exact amount of bytes, or it will fail.
|
||||||
|
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.
|
||||||
|
|
||||||
|
@result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity).
|
||||||
|
It can be zero, which is not an error; it just means ZSTD_decompressContinue() has decoded some header.
|
||||||
|
|
||||||
|
A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero.
|
||||||
|
Context can then be reset to start a new decompression.
|
||||||
|
|
||||||
|
Skippable frames allow the integration of user-defined data into a flow of concatenated frames.
|
||||||
|
Skippable frames will be ignored (skipped) by a decompressor. The format of skippable frame is following:
|
||||||
|
a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F
|
||||||
|
b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits
|
||||||
|
c) Frame Content - any content (User Data) of length equal to Frame Size
|
||||||
|
For skippable frames ZSTD_decompressContinue() always returns 0.
|
||||||
|
For skippable frames ZSTD_getFrameParams() returns fparamsPtr->windowLog==0 what means that a frame is skippable.
|
||||||
|
It also returns Frame Size as fparamsPtr->frameContentSize.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************************
|
||||||
|
* Block functions
|
||||||
|
****************************************/
|
||||||
|
/*! Block functions produce and decode raw zstd blocks, without frame metadata.
|
||||||
|
User will have to take in charge required information to regenerate data, such as compressed and content sizes.
|
||||||
|
|
||||||
|
A few rules to respect :
|
||||||
|
- Uncompressed block size must be <= ZSTD_BLOCKSIZE_MAX (128 KB)
|
||||||
|
- Compressing or decompressing requires a context structure
|
||||||
|
+ Use ZSTD_createCCtx() and ZSTD_createDCtx()
|
||||||
|
- It is necessary to init context before starting
|
||||||
|
+ compression : ZSTD_compressBegin()
|
||||||
|
+ decompression : ZSTD_decompressBegin()
|
||||||
|
+ variants _usingDict() are also allowed
|
||||||
|
+ copyCCtx() and copyDCtx() work too
|
||||||
|
- When a block is considered not compressible enough, ZSTD_compressBlock() result will be zero.
|
||||||
|
In which case, nothing is produced into `dst`.
|
||||||
|
+ User must test for such outcome and deal directly with uncompressed data
|
||||||
|
+ ZSTD_decompressBlock() doesn't accept uncompressed data as input !!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ZSTD_BLOCKSIZE_MAX (128 * 1024) /* define, for static allocation */
|
||||||
|
ZSTDLIB_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
ZSTDLIB_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
|
||||||
|
/*-*************************************
|
||||||
|
* Error management
|
||||||
|
***************************************/
|
||||||
|
#include "error_public.h"
|
||||||
|
/*! ZSTD_getErrorCode() :
|
||||||
|
convert a `size_t` function result into a `ZSTD_ErrorCode` enum type,
|
||||||
|
which can be used to compare directly with enum list published into "error_public.h" */
|
||||||
|
ZSTDLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult);
|
||||||
|
ZSTDLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ZSTD_STATIC_LINKING_ONLY */
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* ZSTD_H */
|
#endif /* ZSTD_H_235446 */
|
||||||
|
|||||||
@@ -33,8 +33,10 @@
|
|||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Dependencies
|
* Dependencies
|
||||||
***************************************/
|
***************************************/
|
||||||
|
#include <stdlib.h> /* malloc */
|
||||||
#include "error_private.h"
|
#include "error_private.h"
|
||||||
#include "zstd.h" /* declaration of ZSTD_isError, ZSTD_getErrorName */
|
#define ZSTD_STATIC_LINKING_ONLY
|
||||||
|
#include "zstd.h" /* declaration of ZSTD_isError, ZSTD_getErrorName, ZSTD_getErrorCode, ZSTD_getErrorString, ZSTD_versionNumber */
|
||||||
#include "zbuff.h" /* declaration of ZBUFF_isError, ZBUFF_getErrorName */
|
#include "zbuff.h" /* declaration of ZBUFF_isError, ZBUFF_getErrorName */
|
||||||
|
|
||||||
|
|
||||||
@@ -70,3 +72,20 @@ const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorName(c
|
|||||||
unsigned ZBUFF_isError(size_t errorCode) { return ERR_isError(errorCode); }
|
unsigned ZBUFF_isError(size_t errorCode) { return ERR_isError(errorCode); }
|
||||||
|
|
||||||
const char* ZBUFF_getErrorName(size_t errorCode) { return ERR_getErrorName(errorCode); }
|
const char* ZBUFF_getErrorName(size_t errorCode) { return ERR_getErrorName(errorCode); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void* ZSTD_defaultAllocFunction(void* opaque, size_t size)
|
||||||
|
{
|
||||||
|
void* address = malloc(size);
|
||||||
|
(void)opaque;
|
||||||
|
/* printf("alloc %p, %d opaque=%p \n", address, (int)size, opaque); */
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZSTD_defaultFreeFunction(void* opaque, void* address)
|
||||||
|
{
|
||||||
|
(void)opaque;
|
||||||
|
/* if (address) printf("free %p opaque=%p \n", address, opaque); */
|
||||||
|
free(address);
|
||||||
|
}
|
||||||
|
|||||||
+18
-35
@@ -37,7 +37,8 @@
|
|||||||
***************************************/
|
***************************************/
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "error_private.h"
|
#include "error_private.h"
|
||||||
#include "zstd_static.h"
|
#define ZSTD_STATIC_LINKING_ONLY
|
||||||
|
#include "zstd.h"
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
@@ -63,11 +64,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ZSTD_OPT_NUM (1<<12)
|
#define ZSTD_OPT_NUM (1<<12)
|
||||||
#define ZSTD_DICT_MAGIC 0xEC30A436
|
#define ZSTD_DICT_MAGIC 0xEC30A437 /* v0.7 */
|
||||||
|
|
||||||
#define ZSTD_REP_NUM 3
|
#define ZSTD_REP_NUM 3
|
||||||
#define ZSTD_REP_INIT ZSTD_REP_NUM
|
#define ZSTD_REP_INIT ZSTD_REP_NUM
|
||||||
#define ZSTD_REP_MOVE (ZSTD_REP_NUM-1)
|
#define ZSTD_REP_MOVE (ZSTD_REP_NUM-1)
|
||||||
|
static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
|
||||||
|
|
||||||
#define KB *(1 <<10)
|
#define KB *(1 <<10)
|
||||||
#define MB *(1 <<20)
|
#define MB *(1 <<20)
|
||||||
@@ -80,10 +82,11 @@
|
|||||||
#define BIT1 2
|
#define BIT1 2
|
||||||
#define BIT0 1
|
#define BIT0 1
|
||||||
|
|
||||||
#define ZSTD_WINDOWLOG_ABSOLUTEMIN 12
|
#define ZSTD_WINDOWLOG_ABSOLUTEMIN 10
|
||||||
static const size_t ZSTD_fcs_fieldSize[4] = { 0, 1, 2, 8 };
|
static const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };
|
||||||
|
static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
|
||||||
|
|
||||||
#define ZSTD_BLOCKHEADERSIZE 3 /* because C standard does not allow a static const value to be defined using another static const value .... :( */
|
#define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
|
||||||
static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
|
static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
|
||||||
typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t;
|
typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t;
|
||||||
|
|
||||||
@@ -91,17 +94,12 @@ typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t;
|
|||||||
#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */
|
#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */
|
||||||
|
|
||||||
#define HufLog 12
|
#define HufLog 12
|
||||||
|
typedef enum { lbt_huffman, lbt_repeat, lbt_raw, lbt_rle } litBlockType_t;
|
||||||
#define IS_HUF 0
|
|
||||||
#define IS_PCH 1
|
|
||||||
#define IS_RAW 2
|
|
||||||
#define IS_RLE 3
|
|
||||||
|
|
||||||
#define LONGNBSEQ 0x7F00
|
#define LONGNBSEQ 0x7F00
|
||||||
|
|
||||||
#define MINMATCH 3
|
#define MINMATCH 3
|
||||||
#define EQUAL_READ32 4
|
#define EQUAL_READ32 4
|
||||||
#define REPCODE_STARTVALUE 1
|
|
||||||
|
|
||||||
#define Litbits 8
|
#define Litbits 8
|
||||||
#define MaxLit ((1<<Litbits) - 1)
|
#define MaxLit ((1<<Litbits) - 1)
|
||||||
@@ -160,32 +158,12 @@ MEM_STATIC void ZSTD_wildcopy(void* dst, const void* src, size_t length)
|
|||||||
while (op < oend);
|
while (op < oend);
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_STATIC unsigned ZSTD_highbit(U32 val)
|
|
||||||
{
|
|
||||||
# if defined(_MSC_VER) /* Visual */
|
|
||||||
unsigned long r=0;
|
|
||||||
_BitScanReverse(&r, val);
|
|
||||||
return (unsigned)r;
|
|
||||||
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
|
|
||||||
return 31 - __builtin_clz(val);
|
|
||||||
# else /* Software version */
|
|
||||||
static const int DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
|
|
||||||
U32 v = val;
|
|
||||||
int r;
|
|
||||||
v |= v >> 1;
|
|
||||||
v |= v >> 2;
|
|
||||||
v |= v >> 4;
|
|
||||||
v |= v >> 8;
|
|
||||||
v |= v >> 16;
|
|
||||||
r = DeBruijnClz[(U32)(v * 0x07C4ACDDU) >> 27];
|
|
||||||
return r;
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-*******************************************
|
/*-*******************************************
|
||||||
* Private interfaces
|
* Private interfaces
|
||||||
*********************************************/
|
*********************************************/
|
||||||
|
typedef struct ZSTD_stats_s ZSTD_stats_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
U32 off;
|
U32 off;
|
||||||
U32 len;
|
U32 len;
|
||||||
@@ -202,12 +180,12 @@ typedef struct {
|
|||||||
#if ZSTD_OPT_DEBUG == 3
|
#if ZSTD_OPT_DEBUG == 3
|
||||||
#include ".debug/zstd_stats.h"
|
#include ".debug/zstd_stats.h"
|
||||||
#else
|
#else
|
||||||
typedef struct { U32 unused; } ZSTD_stats_t;
|
struct ZSTD_stats_s { U32 unused; };
|
||||||
MEM_STATIC void ZSTD_statsPrint(ZSTD_stats_t* stats, U32 searchLength) { (void)stats; (void)searchLength; }
|
MEM_STATIC void ZSTD_statsPrint(ZSTD_stats_t* stats, U32 searchLength) { (void)stats; (void)searchLength; }
|
||||||
MEM_STATIC void ZSTD_statsInit(ZSTD_stats_t* stats) { (void)stats; }
|
MEM_STATIC void ZSTD_statsInit(ZSTD_stats_t* stats) { (void)stats; }
|
||||||
MEM_STATIC void ZSTD_statsResetFreqs(ZSTD_stats_t* stats) { (void)stats; }
|
MEM_STATIC void ZSTD_statsResetFreqs(ZSTD_stats_t* stats) { (void)stats; }
|
||||||
MEM_STATIC void ZSTD_statsUpdatePrices(ZSTD_stats_t* stats, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) { (void)stats; (void)litLength; (void)literals; (void)offset; (void)matchLength; }
|
MEM_STATIC void ZSTD_statsUpdatePrices(ZSTD_stats_t* stats, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) { (void)stats; (void)litLength; (void)literals; (void)offset; (void)matchLength; }
|
||||||
#endif
|
#endif /* #if ZSTD_OPT_DEBUG == 3 */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void* buffer;
|
void* buffer;
|
||||||
@@ -250,6 +228,11 @@ typedef struct {
|
|||||||
|
|
||||||
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx);
|
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx);
|
||||||
void ZSTD_seqToCodes(const seqStore_t* seqStorePtr, size_t const nbSeq);
|
void ZSTD_seqToCodes(const seqStore_t* seqStorePtr, size_t const nbSeq);
|
||||||
|
int ZSTD_isSkipFrame(ZSTD_DCtx* dctx);
|
||||||
|
|
||||||
|
/* custom memory allocation functions */
|
||||||
|
void* ZSTD_defaultAllocFunction(void* opaque, size_t size);
|
||||||
|
void ZSTD_defaultFreeFunction(void* opaque, void* address);
|
||||||
|
static ZSTD_customMem const defaultCustomMem = { ZSTD_defaultAllocFunction, ZSTD_defaultFreeFunction, NULL };
|
||||||
|
|
||||||
#endif /* ZSTD_CCOMMON_H_MODULE */
|
#endif /* ZSTD_CCOMMON_H_MODULE */
|
||||||
|
|||||||
@@ -1,272 +0,0 @@
|
|||||||
/*
|
|
||||||
zstd - standard compression library
|
|
||||||
Header File for static linking only
|
|
||||||
Copyright (C) 2014-2016, 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 homepage : http://www.zstd.net
|
|
||||||
*/
|
|
||||||
#ifndef ZSTD_STATIC_H
|
|
||||||
#define ZSTD_STATIC_H
|
|
||||||
|
|
||||||
/* The prototypes defined within this file are considered experimental.
|
|
||||||
* They should not be used in the context DLL as they may change in the future.
|
|
||||||
* Prefer static linking if you need them, to control breaking version changes issues.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-*************************************
|
|
||||||
* Dependencies
|
|
||||||
***************************************/
|
|
||||||
#include "zstd.h"
|
|
||||||
#include "mem.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
|
||||||
* Constants
|
|
||||||
***************************************/
|
|
||||||
#define ZSTD_MAGICNUMBER 0xFD2FB526 /* v0.6 */
|
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
|
||||||
* Types
|
|
||||||
***************************************/
|
|
||||||
#define ZSTD_WINDOWLOG_MAX ((U32)(MEM_32bits() ? 25 : 27))
|
|
||||||
#define ZSTD_WINDOWLOG_MIN 18
|
|
||||||
#define ZSTD_CHAINLOG_MAX (ZSTD_WINDOWLOG_MAX+1)
|
|
||||||
#define ZSTD_CHAINLOG_MIN 4
|
|
||||||
#define ZSTD_HASHLOG_MAX ZSTD_WINDOWLOG_MAX
|
|
||||||
#define ZSTD_HASHLOG_MIN 12
|
|
||||||
#define ZSTD_HASHLOG3_MAX 17
|
|
||||||
#define ZSTD_HASHLOG3_MIN 15
|
|
||||||
#define ZSTD_SEARCHLOG_MAX (ZSTD_WINDOWLOG_MAX-1)
|
|
||||||
#define ZSTD_SEARCHLOG_MIN 1
|
|
||||||
#define ZSTD_SEARCHLENGTH_MAX 7
|
|
||||||
#define ZSTD_SEARCHLENGTH_MIN 3
|
|
||||||
#define ZSTD_TARGETLENGTH_MIN 4
|
|
||||||
#define ZSTD_TARGETLENGTH_MAX 999
|
|
||||||
|
|
||||||
/* from faster to stronger */
|
|
||||||
typedef enum { ZSTD_fast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt } ZSTD_strategy;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
U32 windowLog; /* largest match distance : larger == more compression, more memory needed during decompression */
|
|
||||||
U32 chainLog; /* fully searched segment : larger == more compression, slower, more memory (useless for fast) */
|
|
||||||
U32 hashLog; /* dispatch table : larger == faster, more memory */
|
|
||||||
U32 searchLog; /* nb of searches : larger == more compression, slower */
|
|
||||||
U32 searchLength; /* match length searched : larger == faster decompression, sometimes less compression */
|
|
||||||
U32 targetLength; /* acceptable match size for optimal parser (only) : larger == more compression, slower */
|
|
||||||
ZSTD_strategy strategy;
|
|
||||||
} ZSTD_compressionParameters;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
U32 contentSizeFlag; /* 1: content size will be in frame header (if known). */
|
|
||||||
} ZSTD_frameParameters;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
ZSTD_compressionParameters cParams;
|
|
||||||
ZSTD_frameParameters fParams;
|
|
||||||
} ZSTD_parameters;
|
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
|
||||||
* Advanced functions
|
|
||||||
***************************************/
|
|
||||||
ZSTDLIB_API unsigned ZSTD_maxCLevel (void);
|
|
||||||
|
|
||||||
/*! ZSTD_getCParams() :
|
|
||||||
* @return ZSTD_compressionParameters structure for a selected compression level and srcSize.
|
|
||||||
* `srcSize` value is optional, select 0 if not known */
|
|
||||||
ZSTDLIB_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, U64 srcSize, size_t dictSize);
|
|
||||||
|
|
||||||
/*! ZSTD_checkParams() :
|
|
||||||
* Ensure param values remain within authorized range */
|
|
||||||
ZSTDLIB_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params);
|
|
||||||
|
|
||||||
/*! ZSTD_adjustParams() :
|
|
||||||
* optimize params for a given `srcSize` and `dictSize`.
|
|
||||||
* both values are optional, select `0` if unknown. */
|
|
||||||
ZSTDLIB_API void ZSTD_adjustCParams(ZSTD_compressionParameters* params, U64 srcSize, size_t dictSize);
|
|
||||||
|
|
||||||
/*! ZSTD_compress_advanced() :
|
|
||||||
* Same as ZSTD_compress_usingDict(), with fine-tune control of each compression parameter */
|
|
||||||
ZSTDLIB_API size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
|
||||||
void* dst, size_t dstCapacity,
|
|
||||||
const void* src, size_t srcSize,
|
|
||||||
const void* dict,size_t dictSize,
|
|
||||||
ZSTD_parameters params);
|
|
||||||
|
|
||||||
/*! ZSTD_compress_usingPreparedDCtx() :
|
|
||||||
* Same as ZSTD_compress_usingDict, but using a reference context `preparedCCtx`, where dictionary has been loaded.
|
|
||||||
* It avoids reloading the dictionary each time.
|
|
||||||
* `preparedCCtx` must have been properly initialized using ZSTD_compressBegin_usingDict() or ZSTD_compressBegin_advanced().
|
|
||||||
* Requires 2 contexts : 1 for reference (preparedCCtx) which will not be modified, and 1 to run the compression operation (cctx) */
|
|
||||||
ZSTDLIB_API size_t ZSTD_compress_usingPreparedCCtx(
|
|
||||||
ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx,
|
|
||||||
void* dst, size_t dstCapacity,
|
|
||||||
const void* src, size_t srcSize);
|
|
||||||
|
|
||||||
/*- Advanced Decompression functions -*/
|
|
||||||
|
|
||||||
/*! ZSTD_decompress_usingPreparedDCtx() :
|
|
||||||
* Same as ZSTD_decompress_usingDict, but using a reference context `preparedDCtx`, where dictionary has been loaded.
|
|
||||||
* It avoids reloading the dictionary each time.
|
|
||||||
* `preparedDCtx` must have been properly initialized using ZSTD_decompressBegin_usingDict().
|
|
||||||
* Requires 2 contexts : 1 for reference (preparedDCtx), which will not be modified, and 1 to run the decompression operation (dctx) */
|
|
||||||
ZSTDLIB_API size_t ZSTD_decompress_usingPreparedDCtx(
|
|
||||||
ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx,
|
|
||||||
void* dst, size_t dstCapacity,
|
|
||||||
const void* src, size_t srcSize);
|
|
||||||
|
|
||||||
|
|
||||||
/* **************************************
|
|
||||||
* Streaming functions (direct mode)
|
|
||||||
****************************************/
|
|
||||||
ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
|
|
||||||
ZSTDLIB_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
|
|
||||||
ZSTDLIB_API size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, U64 pledgedSrcSize);
|
|
||||||
ZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx);
|
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
|
||||||
ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Streaming compression, synchronous mode (bufferless)
|
|
||||||
|
|
||||||
A ZSTD_CCtx object is required to track streaming operations.
|
|
||||||
Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage it.
|
|
||||||
ZSTD_CCtx object can be re-used multiple times within successive compression operations.
|
|
||||||
|
|
||||||
Start by initializing a context.
|
|
||||||
Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression,
|
|
||||||
or ZSTD_compressBegin_advanced(), for finer parameter control.
|
|
||||||
It's also possible to duplicate a reference context which has already been initialized, using ZSTD_copyCCtx()
|
|
||||||
|
|
||||||
Then, consume your input using ZSTD_compressContinue().
|
|
||||||
The interface is synchronous, so all input will be consumed and produce a compressed output.
|
|
||||||
You must ensure there is enough space in destination buffer to store compressed data under worst case scenario.
|
|
||||||
Worst case evaluation is provided by ZSTD_compressBound().
|
|
||||||
|
|
||||||
Finish a frame with ZSTD_compressEnd(), which will write the epilogue.
|
|
||||||
Without the epilogue, frames will be considered incomplete by decoder.
|
|
||||||
|
|
||||||
You can then reuse ZSTD_CCtx to compress some new frame.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct { U64 frameContentSize; U32 windowLog; } ZSTD_frameParams;
|
|
||||||
|
|
||||||
#define ZSTD_FRAMEHEADERSIZE_MAX 13 /* for static allocation */
|
|
||||||
static const size_t ZSTD_frameHeaderSize_min = 5;
|
|
||||||
static const size_t ZSTD_frameHeaderSize_max = ZSTD_FRAMEHEADERSIZE_MAX;
|
|
||||||
ZSTDLIB_API size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input */
|
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
|
|
||||||
ZSTDLIB_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
|
|
||||||
ZSTDLIB_API void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
|
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
|
|
||||||
ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Streaming decompression, direct mode (bufferless)
|
|
||||||
|
|
||||||
A ZSTD_DCtx object is required to track streaming operations.
|
|
||||||
Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
|
|
||||||
A ZSTD_DCtx object can be re-used multiple times.
|
|
||||||
|
|
||||||
First optional operation is to retrieve frame parameters, using ZSTD_getFrameParams(), which doesn't consume the input.
|
|
||||||
It can provide the minimum size of rolling buffer required to properly decompress data,
|
|
||||||
and optionally the final size of uncompressed content.
|
|
||||||
(Note : content size is an optional info that may not be present. 0 means : content size unknown)
|
|
||||||
Frame parameters are extracted from the beginning of compressed frame.
|
|
||||||
The amount of data to read is variable, from ZSTD_frameHeaderSize_min to ZSTD_frameHeaderSize_max (so if `srcSize` >= ZSTD_frameHeaderSize_max, it will always work)
|
|
||||||
If `srcSize` is too small for operation to succeed, function will return the minimum size it requires to produce a result.
|
|
||||||
Result : 0 when successful, it means the ZSTD_frameParams structure has been filled.
|
|
||||||
>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()
|
|
||||||
|
|
||||||
Start decompression, with ZSTD_decompressBegin() or ZSTD_decompressBegin_usingDict().
|
|
||||||
Alternatively, you can copy a prepared context, using ZSTD_copyDCtx().
|
|
||||||
|
|
||||||
Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively.
|
|
||||||
ZSTD_nextSrcSizeToDecompress() tells how much bytes to provide as 'srcSize' to ZSTD_decompressContinue().
|
|
||||||
ZSTD_decompressContinue() requires this exact amount of bytes, or it will fail.
|
|
||||||
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.
|
|
||||||
|
|
||||||
@result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity)
|
|
||||||
It can be zero, which is not an error; it just means ZSTD_decompressContinue() has decoded some header.
|
|
||||||
|
|
||||||
A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero.
|
|
||||||
Context can then be reset to start a new decompression.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* **************************************
|
|
||||||
* Block functions
|
|
||||||
****************************************/
|
|
||||||
/*! Block functions produce and decode raw zstd blocks, without frame metadata.
|
|
||||||
User will have to take in charge required information to regenerate data, such as compressed and content sizes.
|
|
||||||
|
|
||||||
A few rules to respect :
|
|
||||||
- Uncompressed block size must be <= ZSTD_BLOCKSIZE_MAX (128 KB)
|
|
||||||
- Compressing or decompressing requires a context structure
|
|
||||||
+ Use ZSTD_createCCtx() and ZSTD_createDCtx()
|
|
||||||
- It is necessary to init context before starting
|
|
||||||
+ compression : ZSTD_compressBegin()
|
|
||||||
+ decompression : ZSTD_decompressBegin()
|
|
||||||
+ variants _usingDict() are also allowed
|
|
||||||
+ copyCCtx() and copyDCtx() work too
|
|
||||||
- When a block is considered not compressible enough, ZSTD_compressBlock() result will be zero.
|
|
||||||
In which case, nothing is produced into `dst`.
|
|
||||||
+ User must test for such outcome and deal directly with uncompressed data
|
|
||||||
+ ZSTD_decompressBlock() doesn't accept uncompressed data as input !!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define ZSTD_BLOCKSIZE_MAX (128 * 1024) /* define, for static allocation */
|
|
||||||
ZSTDLIB_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
|
||||||
ZSTDLIB_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
|
||||||
* Error management
|
|
||||||
***************************************/
|
|
||||||
#include "error_public.h"
|
|
||||||
/*! ZSTD_getErrorCode() :
|
|
||||||
convert a `size_t` function result into a `ZSTD_ErrorCode` enum type,
|
|
||||||
which can be used to compare directly with enum list published into "error_public.h" */
|
|
||||||
ZSTDLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult);
|
|
||||||
ZSTDLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code);
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ZSTD_STATIC_H */
|
|
||||||
@@ -37,57 +37,50 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-*************************************
|
|
||||||
* Dependencies
|
|
||||||
***************************************/
|
|
||||||
//#include "zstd.h"
|
|
||||||
//#include "mem.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
|
||||||
* Constants
|
|
||||||
***************************************/
|
|
||||||
//#define ZSTD_MAGICNUMBER 0xFD2FB526 /* v0.6 */
|
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Types
|
* Types
|
||||||
***************************************/
|
***************************************/
|
||||||
typedef struct {
|
struct ZSTD_stats_s {
|
||||||
U32 priceOffset, priceOffCode, priceMatchLength, priceLiteral, priceLitLength, priceDumpsLength;
|
U32 priceOffset, priceOffCode, priceMatchLength, priceLiteral, priceLitLength;
|
||||||
U32 totalMatchSum, totalLitSum, totalSeqSum, totalRepSum;
|
U32 totalMatchSum, totalLitSum, totalSeqSum, totalRepSum;
|
||||||
U32 litSum, matchLengthSum, litLengthSum, offCodeSum;
|
U32 litSum, matchLengthSum, litLengthSum, offCodeSum;
|
||||||
U32 matchLengthFreq[1<<MLbits];
|
U32 matchLengthFreq[MaxML+1];
|
||||||
U32 litLengthFreq[1<<LLbits];
|
U32 litLengthFreq[MaxLL+1];
|
||||||
U32 litFreq[1<<Litbits];
|
U32 litFreq[1<<Litbits];
|
||||||
U32 offCodeFreq[1<<Offbits];
|
U32 offCodeFreq[MaxOff+1];
|
||||||
} ZSTD_stats_t;
|
};
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Advanced functions
|
* Stats functions
|
||||||
***************************************/
|
***************************************/
|
||||||
|
MEM_STATIC ZSTD_stats_t* ZSTD_statsAlloc() { return malloc(sizeof(ZSTD_stats_t)); }
|
||||||
|
MEM_STATIC void ZSTD_statsFree(struct ZSTD_stats_s* stats) { free(stats); }
|
||||||
|
|
||||||
MEM_STATIC void ZSTD_statsPrint(ZSTD_stats_t* stats, U32 searchLength)
|
MEM_STATIC void ZSTD_statsPrint(ZSTD_stats_t* stats, U32 searchLength)
|
||||||
{
|
{
|
||||||
stats->totalMatchSum += stats->totalSeqSum * ((searchLength == 3) ? 3 : 4);
|
stats->totalMatchSum += stats->totalSeqSum * ((searchLength == 3) ? 3 : 4);
|
||||||
printf("avgMatchL=%.2f avgLitL=%.2f match=%.1f%% lit=%.1f%% reps=%d seq=%d\n", (float)stats->totalMatchSum/stats->totalSeqSum, (float)stats->totalLitSum/stats->totalSeqSum, 100.0*stats->totalMatchSum/(stats->totalMatchSum+stats->totalLitSum), 100.0*stats->totalLitSum/(stats->totalMatchSum+stats->totalLitSum), stats->totalRepSum, stats->totalSeqSum);
|
printf("\navgMatchL=%.2f avgLitL=%.2f match=%.1f%% lit=%.1f%% reps=%d seq=%d\n", (float)stats->totalMatchSum/stats->totalSeqSum, (float)stats->totalLitSum/stats->totalSeqSum, 100.0*stats->totalMatchSum/(stats->totalMatchSum+stats->totalLitSum), 100.0*stats->totalLitSum/(stats->totalMatchSum+stats->totalLitSum), stats->totalRepSum, stats->totalSeqSum);
|
||||||
printf("SumBytes=%d Offset=%d OffCode=%d Match=%d Literal=%d LitLength=%d DumpsLength=%d\n", (stats->priceOffset+stats->priceOffCode+stats->priceMatchLength+stats->priceLiteral+stats->priceLitLength+stats->priceDumpsLength)/8, stats->priceOffset/8, stats->priceOffCode/8, stats->priceMatchLength/8, stats->priceLiteral/8, stats->priceLitLength/8, stats->priceDumpsLength/8);
|
printf("SumBytes=%d Offset=%d OffCode=%d Match=%d Literal=%d LitLength=%d\n", (stats->priceOffset+stats->priceOffCode+stats->priceMatchLength+stats->priceLiteral+stats->priceLitLength)/8, stats->priceOffset/8, stats->priceOffCode/8, stats->priceMatchLength/8, stats->priceLiteral/8, stats->priceLitLength/8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MEM_STATIC void ZSTD_statsInit(ZSTD_stats_t* stats)
|
MEM_STATIC void ZSTD_statsInit(ZSTD_stats_t* stats)
|
||||||
{
|
{
|
||||||
stats->totalLitSum = stats->totalMatchSum = stats->totalSeqSum = stats->totalRepSum = 1;
|
stats->totalLitSum = stats->totalMatchSum = stats->totalSeqSum = stats->totalRepSum = 1;
|
||||||
stats->priceOffset = stats->priceOffCode = stats->priceMatchLength = stats->priceLiteral = stats->priceLitLength = stats->priceDumpsLength = 0;
|
stats->priceOffset = stats->priceOffCode = stats->priceMatchLength = stats->priceLiteral = stats->priceLitLength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MEM_STATIC void ZSTD_statsResetFreqs(ZSTD_stats_t* stats)
|
MEM_STATIC void ZSTD_statsResetFreqs(ZSTD_stats_t* stats)
|
||||||
{
|
{
|
||||||
unsigned u;
|
unsigned u;
|
||||||
|
|
||||||
stats->litSum = (1<<Litbits);
|
stats->litSum = (2<<Litbits);
|
||||||
stats->litLengthSum = (1<<LLbits);
|
stats->litLengthSum = MaxLL+1;
|
||||||
stats->matchLengthSum = (1<<MLbits);
|
stats->matchLengthSum = MaxML+1;
|
||||||
stats->offCodeSum = (1<<Offbits);
|
stats->offCodeSum = (MaxOff+1);
|
||||||
|
|
||||||
for (u=0; u<=MaxLit; u++)
|
for (u=0; u<=MaxLit; u++)
|
||||||
stats->litFreq[u] = 1;
|
stats->litFreq[u] = 1;
|
||||||
@@ -99,62 +92,67 @@ MEM_STATIC void ZSTD_statsResetFreqs(ZSTD_stats_t* stats)
|
|||||||
stats->offCodeFreq[u] = 1;
|
stats->offCodeFreq[u] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MEM_STATIC void ZSTD_statsUpdatePrices(ZSTD_stats_t* stats, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength)
|
MEM_STATIC void ZSTD_statsUpdatePrices(ZSTD_stats_t* stats, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength)
|
||||||
{
|
{
|
||||||
/* offset */
|
|
||||||
BYTE offCode = offset ? (BYTE)ZSTD_highbit(offset+1) + 1 : 0;
|
|
||||||
stats->priceOffCode += ZSTD_highbit(stats->offCodeSum+1) - ZSTD_highbit(stats->offCodeFreq[offCode]+1);
|
|
||||||
stats->priceOffset += (offCode-1) + (!offCode);
|
|
||||||
|
|
||||||
/* match Length */
|
|
||||||
stats->priceDumpsLength += ((matchLength >= MaxML)<<3) + ((matchLength >= 255+MaxML)<<4) + ((matchLength>=(1<<15))<<3);
|
|
||||||
stats->priceMatchLength += ZSTD_highbit(stats->matchLengthSum+1) - ZSTD_highbit(stats->matchLengthFreq[(matchLength >= MaxML) ? MaxML : matchLength]+1);
|
|
||||||
|
|
||||||
if (litLength) {
|
|
||||||
/* literals */
|
|
||||||
U32 u;
|
|
||||||
stats->priceLiteral += litLength * ZSTD_highbit(stats->litSum+1);
|
|
||||||
for (u=0; u < litLength; u++)
|
|
||||||
stats->priceLiteral -= ZSTD_highbit(stats->litFreq[literals[u]]+1);
|
|
||||||
|
|
||||||
/* literal Length */
|
|
||||||
stats->priceDumpsLength += ((litLength >= MaxLL)<<3) + ((litLength >= 255+MaxLL)<<4) + ((litLength>=(1<<15))<<3);
|
|
||||||
stats->priceLitLength += ZSTD_highbit(stats->litLengthSum+1) - ZSTD_highbit(stats->litLengthFreq[(litLength >= MaxLL) ? MaxLL : litLength]+1);
|
|
||||||
} else {
|
|
||||||
stats->priceLitLength += ZSTD_highbit(stats->litLengthSum+1) - ZSTD_highbit(stats->litLengthFreq[0]+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (offset == 0) stats->totalRepSum++;
|
|
||||||
stats->totalSeqSum++;
|
|
||||||
stats->totalMatchSum += matchLength;
|
|
||||||
stats->totalLitSum += litLength;
|
|
||||||
|
|
||||||
U32 u;
|
U32 u;
|
||||||
/* literals */
|
/* literals */
|
||||||
|
stats->priceLiteral += litLength * ZSTD_highbit(stats->litSum+1);
|
||||||
|
for (u=0; u < litLength; u++)
|
||||||
|
stats->priceLiteral -= ZSTD_highbit(stats->litFreq[literals[u]]+1);
|
||||||
stats->litSum += litLength;
|
stats->litSum += litLength;
|
||||||
for (u=0; u < litLength; u++)
|
for (u=0; u < litLength; u++)
|
||||||
stats->litFreq[literals[u]]++;
|
stats->litFreq[literals[u]]++;
|
||||||
|
|
||||||
/* literal Length */
|
/* literal Length */
|
||||||
stats->litLengthSum++;
|
{ static const BYTE LL_Code[64] = { 0, 1, 2, 3, 4, 5, 6, 7,
|
||||||
if (litLength >= MaxLL)
|
8, 9, 10, 11, 12, 13, 14, 15,
|
||||||
stats->litLengthFreq[MaxLL]++;
|
16, 16, 17, 17, 18, 18, 19, 19,
|
||||||
else
|
20, 20, 20, 20, 21, 21, 21, 21,
|
||||||
stats->litLengthFreq[litLength]++;
|
22, 22, 22, 22, 22, 22, 22, 22,
|
||||||
|
23, 23, 23, 23, 23, 23, 23, 23,
|
||||||
|
24, 24, 24, 24, 24, 24, 24, 24,
|
||||||
|
24, 24, 24, 24, 24, 24, 24, 24 };
|
||||||
|
const BYTE LL_deltaCode = 19;
|
||||||
|
const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit(litLength) + LL_deltaCode : LL_Code[litLength];
|
||||||
|
if (litLength) {
|
||||||
|
stats->priceLitLength += LL_bits[llCode] + ZSTD_highbit(stats->litLengthSum+1) - ZSTD_highbit(stats->litLengthFreq[llCode]+1);
|
||||||
|
} else {
|
||||||
|
stats->priceLitLength += ZSTD_highbit(stats->litLengthSum+1) - ZSTD_highbit(stats->litLengthFreq[0]+1);
|
||||||
|
}
|
||||||
|
stats->litLengthFreq[llCode]++;
|
||||||
|
stats->litLengthSum++;
|
||||||
|
}
|
||||||
|
|
||||||
/* match offset */
|
/* match offset */
|
||||||
stats->offCodeSum++;
|
{ BYTE offCode = (BYTE)ZSTD_highbit(offset+1);
|
||||||
stats->offCodeFreq[offCode]++;
|
stats->priceOffCode += ZSTD_highbit(stats->offCodeSum+1) - ZSTD_highbit(stats->offCodeFreq[offCode]+1);
|
||||||
|
stats->priceOffset += offCode;
|
||||||
|
stats->offCodeSum++;
|
||||||
|
stats->offCodeFreq[offCode]++;
|
||||||
|
}
|
||||||
|
|
||||||
/* match Length */
|
/* match Length */
|
||||||
stats->matchLengthSum++;
|
{ static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||||
if (matchLength >= MaxML)
|
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||||
stats->matchLengthFreq[MaxML]++;
|
32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
|
||||||
else
|
38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
|
||||||
stats->matchLengthFreq[matchLength]++;
|
40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
|
||||||
}
|
41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
|
||||||
|
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
|
||||||
|
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
|
||||||
|
const BYTE ML_deltaCode = 36;
|
||||||
|
const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit(matchLength) + ML_deltaCode : ML_Code[matchLength];
|
||||||
|
stats->priceMatchLength += ML_bits[mlCode] + ZSTD_highbit(stats->matchLengthSum+1) - ZSTD_highbit(stats->matchLengthFreq[mlCode]+1);
|
||||||
|
stats->matchLengthFreq[mlCode]++;
|
||||||
|
stats->matchLengthSum++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset == 0) stats->totalRepSum++;
|
||||||
|
stats->totalSeqSum++;
|
||||||
|
stats->totalMatchSum += matchLength;
|
||||||
|
stats->totalLitSum += litLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
|
|||||||
@@ -57,7 +57,8 @@
|
|||||||
#include <string.h> /* memcpy, memset */
|
#include <string.h> /* memcpy, memset */
|
||||||
#include <stdio.h> /* printf (debug) */
|
#include <stdio.h> /* printf (debug) */
|
||||||
#include "bitstream.h"
|
#include "bitstream.h"
|
||||||
#include "fse_static.h"
|
#define FSE_STATIC_LINKING_ONLY
|
||||||
|
#include "fse.h"
|
||||||
|
|
||||||
|
|
||||||
/* **************************************************************
|
/* **************************************************************
|
||||||
@@ -111,8 +112,6 @@ size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned
|
|||||||
U32 highThreshold = tableSize-1;
|
U32 highThreshold = tableSize-1;
|
||||||
|
|
||||||
/* CTable header */
|
/* CTable header */
|
||||||
|
|
||||||
|
|
||||||
tableU16[-2] = (U16) tableLog;
|
tableU16[-2] = (U16) tableLog;
|
||||||
tableU16[-1] = (U16) maxSymbolValue;
|
tableU16[-1] = (U16) maxSymbolValue;
|
||||||
|
|
||||||
@@ -147,10 +146,10 @@ size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Build table */
|
/* Build table */
|
||||||
{ U32 u; for (u=0; u<tableSize; u++) {
|
{ U32 u; for (u=0; u<tableSize; u++) {
|
||||||
FSE_FUNCTION_TYPE s = tableSymbol[u]; /* note : static analyzer may not understand tableSymbol is properly initialized */
|
FSE_FUNCTION_TYPE s = tableSymbol[u]; /* note : static analyzer may not understand tableSymbol is properly initialized */
|
||||||
tableU16[cumul[s]++] = (U16) (tableSize+u); /* TableU16 : sorted by symbol order; gives next state value */
|
tableU16[cumul[s]++] = (U16) (tableSize+u); /* TableU16 : sorted by symbol order; gives next state value */
|
||||||
}}
|
} }
|
||||||
|
|
||||||
/* Build Symbol Transformation Table */
|
/* Build Symbol Transformation Table */
|
||||||
{ unsigned total = 0;
|
{ unsigned total = 0;
|
||||||
@@ -257,7 +256,7 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
|
|||||||
bitStream += count << bitCount;
|
bitStream += count << bitCount;
|
||||||
bitCount += nbBits;
|
bitCount += nbBits;
|
||||||
bitCount -= (count<max);
|
bitCount -= (count<max);
|
||||||
previous0 = (count==1);
|
previous0 = (count==1);
|
||||||
while (remaining<threshold) nbBits--, threshold>>=1;
|
while (remaining<threshold) nbBits--, threshold>>=1;
|
||||||
}
|
}
|
||||||
if (bitCount>16) {
|
if (bitCount>16) {
|
||||||
@@ -444,7 +443,7 @@ FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog)
|
|||||||
return (FSE_CTable*)malloc(size);
|
return (FSE_CTable*)malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSE_freeCTable (FSE_CTable* ct) { free(ct); }
|
void FSE_freeCTable (FSE_CTable* ct) { free(ct); }
|
||||||
|
|
||||||
/* provides the minimum logSize to safely represent a distribution */
|
/* provides the minimum logSize to safely represent a distribution */
|
||||||
static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
|
static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
|
||||||
@@ -455,9 +454,9 @@ static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
|
|||||||
return minBits;
|
return minBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)
|
unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus)
|
||||||
{
|
{
|
||||||
U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - 2;
|
U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;
|
||||||
U32 tableLog = maxTableLog;
|
U32 tableLog = maxTableLog;
|
||||||
U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
|
U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
|
||||||
if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
|
if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
|
||||||
@@ -468,6 +467,11 @@ unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS
|
|||||||
return tableLog;
|
return tableLog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)
|
||||||
|
{
|
||||||
|
return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Secondary normalization method.
|
/* Secondary normalization method.
|
||||||
To be used when primary method fails. */
|
To be used when primary method fails. */
|
||||||
|
|||||||
+89
-73
@@ -59,12 +59,13 @@
|
|||||||
/* **************************************************************
|
/* **************************************************************
|
||||||
* Includes
|
* Includes
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
#include <stdlib.h> /* malloc, free, qsort */
|
|
||||||
#include <string.h> /* memcpy, memset */
|
#include <string.h> /* memcpy, memset */
|
||||||
#include <stdio.h> /* printf (debug) */
|
#include <stdio.h> /* printf (debug) */
|
||||||
#include "huf_static.h"
|
|
||||||
#include "bitstream.h"
|
#include "bitstream.h"
|
||||||
|
#define FSE_STATIC_LINKING_ONLY /* FSE_optimalTableLog_internal */
|
||||||
#include "fse.h" /* header compression */
|
#include "fse.h" /* header compression */
|
||||||
|
#define HUF_STATIC_LINKING_ONLY
|
||||||
|
#include "huf.h"
|
||||||
|
|
||||||
|
|
||||||
/* **************************************************************
|
/* **************************************************************
|
||||||
@@ -73,6 +74,15 @@
|
|||||||
#define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
|
#define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************************************************
|
||||||
|
* Utils
|
||||||
|
****************************************************************/
|
||||||
|
unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)
|
||||||
|
{
|
||||||
|
return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *******************************************************
|
/* *******************************************************
|
||||||
* HUF : Huffman block compression
|
* HUF : Huffman block compression
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
@@ -94,14 +104,14 @@ typedef struct nodeElt_s {
|
|||||||
size_t HUF_writeCTable (void* dst, size_t maxDstSize,
|
size_t HUF_writeCTable (void* dst, size_t maxDstSize,
|
||||||
const HUF_CElt* CTable, U32 maxSymbolValue, U32 huffLog)
|
const HUF_CElt* CTable, U32 maxSymbolValue, U32 huffLog)
|
||||||
{
|
{
|
||||||
BYTE bitsToWeight[HUF_MAX_TABLELOG + 1];
|
BYTE bitsToWeight[HUF_TABLELOG_MAX + 1];
|
||||||
BYTE huffWeight[HUF_MAX_SYMBOL_VALUE + 1];
|
BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];
|
||||||
U32 n;
|
U32 n;
|
||||||
BYTE* op = (BYTE*)dst;
|
BYTE* op = (BYTE*)dst;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
/* check conditions */
|
/* check conditions */
|
||||||
if (maxSymbolValue > HUF_MAX_SYMBOL_VALUE + 1)
|
if (maxSymbolValue > HUF_SYMBOLVALUE_MAX + 1)
|
||||||
return ERROR(GENERIC);
|
return ERROR(GENERIC);
|
||||||
|
|
||||||
/* convert to weight */
|
/* convert to weight */
|
||||||
@@ -116,7 +126,7 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize,
|
|||||||
if (size >= 128) return ERROR(GENERIC); /* should never happen, since maxSymbolValue <= 255 */
|
if (size >= 128) return ERROR(GENERIC); /* should never happen, since maxSymbolValue <= 255 */
|
||||||
if ((size <= 1) || (size >= maxSymbolValue/2)) {
|
if ((size <= 1) || (size >= maxSymbolValue/2)) {
|
||||||
if (size==1) { /* RLE */
|
if (size==1) { /* RLE */
|
||||||
/* only possible case : serie of 1 (because there are at least 2) */
|
/* only possible case : series of 1 (because there are at least 2) */
|
||||||
/* can only be 2^n or (2^n-1), otherwise not an huffman tree */
|
/* can only be 2^n or (2^n-1), otherwise not an huffman tree */
|
||||||
BYTE code;
|
BYTE code;
|
||||||
switch(maxSymbolValue)
|
switch(maxSymbolValue)
|
||||||
@@ -159,19 +169,19 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize,
|
|||||||
|
|
||||||
size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, size_t srcSize)
|
size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
BYTE huffWeight[HUF_MAX_SYMBOL_VALUE + 1];
|
BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];
|
||||||
U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1]; /* large enough for values from 0 to 16 */
|
U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */
|
||||||
U32 tableLog = 0;
|
U32 tableLog = 0;
|
||||||
size_t readSize;
|
size_t readSize;
|
||||||
U32 nbSymbols = 0;
|
U32 nbSymbols = 0;
|
||||||
//memset(huffWeight, 0, sizeof(huffWeight)); /* is not necessary, even though some analyzer complain ... */
|
//memset(huffWeight, 0, sizeof(huffWeight)); /* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
/* get symbol weights */
|
/* get symbol weights */
|
||||||
readSize = HUF_readStats(huffWeight, HUF_MAX_SYMBOL_VALUE+1, rankVal, &nbSymbols, &tableLog, src, srcSize);
|
readSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize);
|
||||||
if (HUF_isError(readSize)) return readSize;
|
if (HUF_isError(readSize)) return readSize;
|
||||||
|
|
||||||
/* check result */
|
/* check result */
|
||||||
if (tableLog > HUF_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
|
if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
|
||||||
if (nbSymbols > maxSymbolValue+1) return ERROR(maxSymbolValue_tooSmall);
|
if (nbSymbols > maxSymbolValue+1) return ERROR(maxSymbolValue_tooSmall);
|
||||||
|
|
||||||
/* Prepare base value per rank */
|
/* Prepare base value per rank */
|
||||||
@@ -189,12 +199,12 @@ size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, si
|
|||||||
}}
|
}}
|
||||||
|
|
||||||
/* fill val */
|
/* fill val */
|
||||||
{ U16 nbPerRank[HUF_MAX_TABLELOG+1] = {0};
|
{ U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
|
||||||
U16 valPerRank[HUF_MAX_TABLELOG+1] = {0};
|
U16 valPerRank[HUF_TABLELOG_MAX+1] = {0};
|
||||||
{ U32 n; for (n=0; n<nbSymbols; n++) nbPerRank[CTable[n].nbBits]++; }
|
{ U32 n; for (n=0; n<nbSymbols; n++) nbPerRank[CTable[n].nbBits]++; }
|
||||||
/* determine stating value per rank */
|
/* determine stating value per rank */
|
||||||
{ U16 min = 0;
|
{ U16 min = 0;
|
||||||
U32 n; for (n=HUF_MAX_TABLELOG; n>0; n--) {
|
U32 n; for (n=HUF_TABLELOG_MAX; n>0; n--) {
|
||||||
valPerRank[n] = min; /* get starting value within each rank */
|
valPerRank[n] = min; /* get starting value within each rank */
|
||||||
min += nbPerRank[n];
|
min += nbPerRank[n];
|
||||||
min >>= 1;
|
min >>= 1;
|
||||||
@@ -229,7 +239,7 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
|
|||||||
|
|
||||||
/* repay normalized cost */
|
/* repay normalized cost */
|
||||||
{ U32 const noSymbol = 0xF0F0F0F0;
|
{ U32 const noSymbol = 0xF0F0F0F0;
|
||||||
U32 rankLast[HUF_MAX_TABLELOG+1];
|
U32 rankLast[HUF_TABLELOG_MAX+1];
|
||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
/* Get pos of last (smallest) symbol per rank */
|
/* Get pos of last (smallest) symbol per rank */
|
||||||
@@ -253,7 +263,7 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
|
|||||||
if (highTotal <= lowTotal) break;
|
if (highTotal <= lowTotal) break;
|
||||||
} }
|
} }
|
||||||
/* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */
|
/* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */
|
||||||
while ((nBitsToDecrease<=HUF_MAX_TABLELOG) && (rankLast[nBitsToDecrease] == noSymbol)) /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
|
while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol)) /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
|
||||||
nBitsToDecrease ++;
|
nBitsToDecrease ++;
|
||||||
totalCost -= 1 << (nBitsToDecrease-1);
|
totalCost -= 1 << (nBitsToDecrease-1);
|
||||||
if (rankLast[nBitsToDecrease-1] == noSymbol)
|
if (rankLast[nBitsToDecrease-1] == noSymbol)
|
||||||
@@ -312,10 +322,10 @@ static void HUF_sort(nodeElt* huffNode, const U32* count, U32 maxSymbolValue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define STARTNODE (HUF_MAX_SYMBOL_VALUE+1)
|
#define STARTNODE (HUF_SYMBOLVALUE_MAX+1)
|
||||||
size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits)
|
size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits)
|
||||||
{
|
{
|
||||||
nodeElt huffNode0[2*HUF_MAX_SYMBOL_VALUE+1 +1];
|
nodeElt huffNode0[2*HUF_SYMBOLVALUE_MAX+1 +1];
|
||||||
nodeElt* huffNode = huffNode0 + 1;
|
nodeElt* huffNode = huffNode0 + 1;
|
||||||
U32 n, nonNullRank;
|
U32 n, nonNullRank;
|
||||||
int lowS, lowN;
|
int lowS, lowN;
|
||||||
@@ -323,8 +333,8 @@ size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U3
|
|||||||
U32 nodeRoot;
|
U32 nodeRoot;
|
||||||
|
|
||||||
/* safety checks */
|
/* safety checks */
|
||||||
if (maxNbBits == 0) maxNbBits = HUF_DEFAULT_TABLELOG;
|
if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;
|
||||||
if (maxSymbolValue > HUF_MAX_SYMBOL_VALUE) return ERROR(GENERIC);
|
if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(GENERIC);
|
||||||
memset(huffNode0, 0, sizeof(huffNode0));
|
memset(huffNode0, 0, sizeof(huffNode0));
|
||||||
|
|
||||||
/* sort, decreasing order */
|
/* sort, decreasing order */
|
||||||
@@ -360,9 +370,9 @@ size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U3
|
|||||||
maxNbBits = HUF_setMaxHeight(huffNode, nonNullRank, maxNbBits);
|
maxNbBits = HUF_setMaxHeight(huffNode, nonNullRank, maxNbBits);
|
||||||
|
|
||||||
/* fill result into tree (val, nbBits) */
|
/* fill result into tree (val, nbBits) */
|
||||||
{ U16 nbPerRank[HUF_MAX_TABLELOG+1] = {0};
|
{ U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
|
||||||
U16 valPerRank[HUF_MAX_TABLELOG+1] = {0};
|
U16 valPerRank[HUF_TABLELOG_MAX+1] = {0};
|
||||||
if (maxNbBits > HUF_MAX_TABLELOG) return ERROR(GENERIC); /* check fit into table */
|
if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into table */
|
||||||
for (n=0; n<=nonNullRank; n++)
|
for (n=0; n<=nonNullRank; n++)
|
||||||
nbPerRank[huffNode[n].nbBits]++;
|
nbPerRank[huffNode[n].nbBits]++;
|
||||||
/* determine stating value per rank */
|
/* determine stating value per rank */
|
||||||
@@ -391,10 +401,10 @@ size_t HUF_compressBound(size_t size) { return HUF_COMPRESSBOUND(size); }
|
|||||||
#define HUF_FLUSHBITS(s) (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s))
|
#define HUF_FLUSHBITS(s) (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s))
|
||||||
|
|
||||||
#define HUF_FLUSHBITS_1(stream) \
|
#define HUF_FLUSHBITS_1(stream) \
|
||||||
if (sizeof((stream)->bitContainer)*8 < HUF_MAX_TABLELOG*2+7) HUF_FLUSHBITS(stream)
|
if (sizeof((stream)->bitContainer)*8 < HUF_TABLELOG_MAX*2+7) HUF_FLUSHBITS(stream)
|
||||||
|
|
||||||
#define HUF_FLUSHBITS_2(stream) \
|
#define HUF_FLUSHBITS_2(stream) \
|
||||||
if (sizeof((stream)->bitContainer)*8 < HUF_MAX_TABLELOG*4+7) HUF_FLUSHBITS(stream)
|
if (sizeof((stream)->bitContainer)*8 < HUF_TABLELOG_MAX*4+7) HUF_FLUSHBITS(stream)
|
||||||
|
|
||||||
size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
|
size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
|
||||||
{
|
{
|
||||||
@@ -441,44 +451,47 @@ size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, si
|
|||||||
|
|
||||||
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
|
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
|
||||||
{
|
{
|
||||||
size_t segmentSize = (srcSize+3)/4; /* first 3 segments */
|
size_t const segmentSize = (srcSize+3)/4; /* first 3 segments */
|
||||||
const BYTE* ip = (const BYTE*) src;
|
const BYTE* ip = (const BYTE*) src;
|
||||||
const BYTE* const iend = ip + srcSize;
|
const BYTE* const iend = ip + srcSize;
|
||||||
BYTE* const ostart = (BYTE*) dst;
|
BYTE* const ostart = (BYTE*) dst;
|
||||||
BYTE* const oend = ostart + dstSize;
|
BYTE* const oend = ostart + dstSize;
|
||||||
BYTE* op = ostart;
|
BYTE* op = ostart;
|
||||||
size_t errorCode;
|
|
||||||
|
|
||||||
if (dstSize < 6 + 1 + 1 + 1 + 8) return 0; /* minimum space to compress successfully */
|
if (dstSize < 6 + 1 + 1 + 1 + 8) return 0; /* minimum space to compress successfully */
|
||||||
if (srcSize < 12) return 0; /* no saving possible : too small input */
|
if (srcSize < 12) return 0; /* no saving possible : too small input */
|
||||||
op += 6; /* jumpTable */
|
op += 6; /* jumpTable */
|
||||||
|
|
||||||
errorCode = HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable);
|
{ size_t const cSize = HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable);
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (HUF_isError(cSize)) return cSize;
|
||||||
if (errorCode==0) return 0;
|
if (cSize==0) return 0;
|
||||||
MEM_writeLE16(ostart, (U16)errorCode);
|
MEM_writeLE16(ostart, (U16)cSize);
|
||||||
|
op += cSize;
|
||||||
|
}
|
||||||
|
|
||||||
ip += segmentSize;
|
ip += segmentSize;
|
||||||
op += errorCode;
|
{ size_t const cSize = HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable);
|
||||||
errorCode = HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable);
|
if (HUF_isError(cSize)) return cSize;
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (cSize==0) return 0;
|
||||||
if (errorCode==0) return 0;
|
MEM_writeLE16(ostart+2, (U16)cSize);
|
||||||
MEM_writeLE16(ostart+2, (U16)errorCode);
|
op += cSize;
|
||||||
|
}
|
||||||
|
|
||||||
ip += segmentSize;
|
ip += segmentSize;
|
||||||
op += errorCode;
|
{ size_t const cSize = HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable);
|
||||||
errorCode = HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable);
|
if (HUF_isError(cSize)) return cSize;
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (cSize==0) return 0;
|
||||||
if (errorCode==0) return 0;
|
MEM_writeLE16(ostart+4, (U16)cSize);
|
||||||
MEM_writeLE16(ostart+4, (U16)errorCode);
|
op += cSize;
|
||||||
|
}
|
||||||
|
|
||||||
ip += segmentSize;
|
ip += segmentSize;
|
||||||
op += errorCode;
|
{ size_t const cSize = HUF_compress1X_usingCTable(op, oend-op, ip, iend-ip, CTable);
|
||||||
errorCode = HUF_compress1X_usingCTable(op, oend-op, ip, iend-ip, CTable);
|
if (HUF_isError(cSize)) return cSize;
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (cSize==0) return 0;
|
||||||
if (errorCode==0) return 0;
|
op += cSize;
|
||||||
|
}
|
||||||
|
|
||||||
op += errorCode;
|
|
||||||
return op-ostart;
|
return op-ostart;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,43 +506,46 @@ static size_t HUF_compress_internal (
|
|||||||
BYTE* const oend = ostart + dstSize;
|
BYTE* const oend = ostart + dstSize;
|
||||||
BYTE* op = ostart;
|
BYTE* op = ostart;
|
||||||
|
|
||||||
U32 count[HUF_MAX_SYMBOL_VALUE+1];
|
U32 count[HUF_SYMBOLVALUE_MAX+1];
|
||||||
HUF_CElt CTable[HUF_MAX_SYMBOL_VALUE+1];
|
HUF_CElt CTable[HUF_SYMBOLVALUE_MAX+1];
|
||||||
size_t errorCode;
|
|
||||||
|
|
||||||
/* checks & inits */
|
/* checks & inits */
|
||||||
if (srcSize < 1) return 0; /* Uncompressed - note : 1 means rle, so first byte must be correct */
|
if (!srcSize) return 0; /* Uncompressed (note : 1 means rle, so first byte must be correct) */
|
||||||
if (dstSize < 1) return 0; /* not compressible within dst budget */
|
if (!dstSize) return 0; /* cannot fit within dst budget */
|
||||||
if (srcSize > 128 * 1024) return ERROR(srcSize_wrong); /* current block size limit */
|
if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); /* current block size limit */
|
||||||
if (huffLog > HUF_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
|
if (huffLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
|
||||||
if (!maxSymbolValue) maxSymbolValue = HUF_MAX_SYMBOL_VALUE;
|
if (!maxSymbolValue) maxSymbolValue = HUF_SYMBOLVALUE_MAX;
|
||||||
if (!huffLog) huffLog = HUF_DEFAULT_TABLELOG;
|
if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT;
|
||||||
|
|
||||||
/* Scan input and build symbol stats */
|
/* Scan input and build symbol stats */
|
||||||
errorCode = FSE_count (count, &maxSymbolValue, (const BYTE*)src, srcSize);
|
{ size_t const largest = FSE_count (count, &maxSymbolValue, (const BYTE*)src, srcSize);
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (HUF_isError(largest)) return largest;
|
||||||
if (errorCode == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; }
|
if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* rle */
|
||||||
if (errorCode <= (srcSize >> 7)+1) return 0; /* Heuristic : not compressible enough */
|
if (largest <= (srcSize >> 7)+1) return 0; /* Fast heuristic : not compressible enough */
|
||||||
|
}
|
||||||
|
|
||||||
/* Build Huffman Tree */
|
/* Build Huffman Tree */
|
||||||
errorCode = HUF_buildCTable (CTable, count, maxSymbolValue, huffLog);
|
huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
{ size_t const maxBits = HUF_buildCTable (CTable, count, maxSymbolValue, huffLog);
|
||||||
huffLog = (U32)errorCode;
|
if (HUF_isError(maxBits)) return maxBits;
|
||||||
|
huffLog = (U32)maxBits;
|
||||||
|
}
|
||||||
|
|
||||||
/* Write table description header */
|
/* Write table description header */
|
||||||
errorCode = HUF_writeCTable (op, dstSize, CTable, maxSymbolValue, huffLog);
|
{ size_t const hSize = HUF_writeCTable (op, dstSize, CTable, maxSymbolValue, huffLog);
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (HUF_isError(hSize)) return hSize;
|
||||||
if (errorCode + 12 >= srcSize) return 0; /* not useful to try compression */
|
if (hSize + 12 >= srcSize) return 0; /* not useful to try compression */
|
||||||
op += errorCode;
|
op += hSize;
|
||||||
|
}
|
||||||
|
|
||||||
/* Compress */
|
/* Compress */
|
||||||
if (singleStream)
|
{ size_t const cSize = (singleStream) ?
|
||||||
errorCode = HUF_compress1X_usingCTable(op, oend - op, src, srcSize, CTable); /* single segment */
|
HUF_compress1X_usingCTable(op, oend - op, src, srcSize, CTable) : /* single segment */
|
||||||
else
|
HUF_compress4X_usingCTable(op, oend - op, src, srcSize, CTable);
|
||||||
errorCode = HUF_compress4X_usingCTable(op, oend - op, src, srcSize, CTable);
|
if (HUF_isError(cSize)) return cSize;
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (cSize==0) return 0; /* uncompressible */
|
||||||
if (errorCode==0) return 0;
|
op += cSize;
|
||||||
op += errorCode;
|
}
|
||||||
|
|
||||||
/* check compressibility */
|
/* check compressibility */
|
||||||
if ((size_t)(op-ostart) >= srcSize-1)
|
if ((size_t)(op-ostart) >= srcSize-1)
|
||||||
@@ -556,5 +572,5 @@ size_t HUF_compress2 (void* dst, size_t dstSize,
|
|||||||
|
|
||||||
size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
return HUF_compress2(dst, maxDstSize, src, (U32)srcSize, 255, HUF_DEFAULT_TABLELOG);
|
return HUF_compress2(dst, maxDstSize, src, (U32)srcSize, 255, HUF_TABLELOG_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,9 +35,9 @@
|
|||||||
***************************************/
|
***************************************/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "error_private.h"
|
#include "error_private.h"
|
||||||
#include "zstd_internal.h" /* MIN, ZSTD_blockHeaderSize */
|
#include "zstd_internal.h" /* MIN, ZSTD_BLOCKHEADERSIZE, defaultCustomMem */
|
||||||
#include "zstd_static.h" /* ZSTD_BLOCKSIZE_MAX */
|
#define ZBUFF_STATIC_LINKING_ONLY
|
||||||
#include "zbuff_static.h"
|
#include "zbuff.h"
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
@@ -81,7 +81,7 @@ static size_t const ZBUFF_endFrameSize = ZSTD_BLOCKHEADERSIZE;
|
|||||||
|
|
||||||
typedef enum { ZBUFFcs_init, ZBUFFcs_load, ZBUFFcs_flush } ZBUFF_cStage;
|
typedef enum { ZBUFFcs_init, ZBUFFcs_load, ZBUFFcs_flush } ZBUFF_cStage;
|
||||||
|
|
||||||
/* *** Ressources *** */
|
/* *** Resources *** */
|
||||||
struct ZBUFF_CCtx_s {
|
struct ZBUFF_CCtx_s {
|
||||||
ZSTD_CCtx* zc;
|
ZSTD_CCtx* zc;
|
||||||
char* inBuff;
|
char* inBuff;
|
||||||
@@ -95,14 +95,30 @@ struct ZBUFF_CCtx_s {
|
|||||||
size_t outBuffContentSize;
|
size_t outBuffContentSize;
|
||||||
size_t outBuffFlushedSize;
|
size_t outBuffFlushedSize;
|
||||||
ZBUFF_cStage stage;
|
ZBUFF_cStage stage;
|
||||||
|
ZSTD_customMem customMem;
|
||||||
}; /* typedef'd tp ZBUFF_CCtx within "zstd_buffered.h" */
|
}; /* typedef'd tp ZBUFF_CCtx within "zstd_buffered.h" */
|
||||||
|
|
||||||
ZBUFF_CCtx* ZBUFF_createCCtx(void)
|
ZBUFF_CCtx* ZBUFF_createCCtx(void)
|
||||||
{
|
{
|
||||||
ZBUFF_CCtx* zbc = (ZBUFF_CCtx*)malloc(sizeof(ZBUFF_CCtx));
|
return ZBUFF_createCCtx_advanced(defaultCustomMem);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZBUFF_CCtx* ZBUFF_createCCtx_advanced(ZSTD_customMem customMem)
|
||||||
|
{
|
||||||
|
ZBUFF_CCtx* zbc;
|
||||||
|
|
||||||
|
if (!customMem.customAlloc && !customMem.customFree)
|
||||||
|
customMem = defaultCustomMem;
|
||||||
|
|
||||||
|
if (!customMem.customAlloc || !customMem.customFree)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
zbc = (ZBUFF_CCtx*)customMem.customAlloc(customMem.opaque, sizeof(ZBUFF_CCtx));
|
||||||
if (zbc==NULL) return NULL;
|
if (zbc==NULL) return NULL;
|
||||||
memset(zbc, 0, sizeof(*zbc));
|
memset(zbc, 0, sizeof(ZBUFF_CCtx));
|
||||||
zbc->zc = ZSTD_createCCtx();
|
memcpy(&zbc->customMem, &customMem, sizeof(ZSTD_customMem));
|
||||||
|
zbc->zc = ZSTD_createCCtx_advanced(customMem);
|
||||||
|
if (zbc->zc == NULL) { ZBUFF_freeCCtx(zbc); return NULL; }
|
||||||
return zbc;
|
return zbc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,9 +126,9 @@ size_t ZBUFF_freeCCtx(ZBUFF_CCtx* zbc)
|
|||||||
{
|
{
|
||||||
if (zbc==NULL) return 0; /* support free on NULL */
|
if (zbc==NULL) return 0; /* support free on NULL */
|
||||||
ZSTD_freeCCtx(zbc->zc);
|
ZSTD_freeCCtx(zbc->zc);
|
||||||
free(zbc->inBuff);
|
if (zbc->inBuff) zbc->customMem.customFree(zbc->customMem.opaque, zbc->inBuff);
|
||||||
free(zbc->outBuff);
|
if (zbc->outBuff) zbc->customMem.customFree(zbc->customMem.opaque, zbc->outBuff);
|
||||||
free(zbc);
|
zbc->customMem.customFree(zbc->customMem.opaque, zbc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,16 +143,16 @@ size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc,
|
|||||||
{ size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
|
{ size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
|
||||||
if (zbc->inBuffSize < neededInBuffSize) {
|
if (zbc->inBuffSize < neededInBuffSize) {
|
||||||
zbc->inBuffSize = neededInBuffSize;
|
zbc->inBuffSize = neededInBuffSize;
|
||||||
free(zbc->inBuff); /* should not be necessary */
|
zbc->customMem.customFree(zbc->customMem.opaque, zbc->inBuff); /* should not be necessary */
|
||||||
zbc->inBuff = (char*)malloc(neededInBuffSize);
|
zbc->inBuff = (char*)zbc->customMem.customAlloc(zbc->customMem.opaque, neededInBuffSize);
|
||||||
if (zbc->inBuff == NULL) return ERROR(memory_allocation);
|
if (zbc->inBuff == NULL) return ERROR(memory_allocation);
|
||||||
}
|
}
|
||||||
zbc->blockSize = MIN(ZSTD_BLOCKSIZE_MAX, neededInBuffSize/2);
|
zbc->blockSize = MIN(ZSTD_BLOCKSIZE_MAX, neededInBuffSize);
|
||||||
}
|
}
|
||||||
if (zbc->outBuffSize < ZSTD_compressBound(zbc->blockSize)+1) {
|
if (zbc->outBuffSize < ZSTD_compressBound(zbc->blockSize)+1) {
|
||||||
zbc->outBuffSize = ZSTD_compressBound(zbc->blockSize)+1;
|
zbc->outBuffSize = ZSTD_compressBound(zbc->blockSize)+1;
|
||||||
free(zbc->outBuff); /* should not be necessary */
|
zbc->customMem.customFree(zbc->customMem.opaque, zbc->outBuff); /* should not be necessary */
|
||||||
zbc->outBuff = (char*)malloc(zbc->outBuffSize);
|
zbc->outBuff = (char*)zbc->customMem.customAlloc(zbc->customMem.opaque, zbc->outBuffSize);
|
||||||
if (zbc->outBuff == NULL) return ERROR(memory_allocation);
|
if (zbc->outBuff == NULL) return ERROR(memory_allocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,9 +171,8 @@ size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc,
|
|||||||
size_t ZBUFF_compressInitDictionary(ZBUFF_CCtx* zbc, const void* dict, size_t dictSize, int compressionLevel)
|
size_t ZBUFF_compressInitDictionary(ZBUFF_CCtx* zbc, const void* dict, size_t dictSize, int compressionLevel)
|
||||||
{
|
{
|
||||||
ZSTD_parameters params;
|
ZSTD_parameters params;
|
||||||
|
memset(¶ms, 0, sizeof(params));
|
||||||
params.cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
|
params.cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
|
||||||
params.fParams.contentSizeFlag = 0;
|
|
||||||
ZSTD_adjustCParams(¶ms.cParams, 0, dictSize);
|
|
||||||
return ZBUFF_compressInit_advanced(zbc, dict, dictSize, params, 0);
|
return ZBUFF_compressInit_advanced(zbc, dict, dictSize, params, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,6 +182,15 @@ size_t ZBUFF_compressInit(ZBUFF_CCtx* zbc, int compressionLevel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* internal util function */
|
||||||
|
MEM_STATIC size_t ZBUFF_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
size_t const length = MIN(dstCapacity, srcSize);
|
||||||
|
memcpy(dst, src, length);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *** Compression *** */
|
/* *** Compression *** */
|
||||||
|
|
||||||
static size_t ZBUFF_compressContinue_generic(ZBUFF_CCtx* zbc,
|
static size_t ZBUFF_compressContinue_generic(ZBUFF_CCtx* zbc,
|
||||||
|
|||||||
+430
-209
@@ -51,12 +51,15 @@
|
|||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Dependencies
|
* Dependencies
|
||||||
***************************************/
|
***************************************/
|
||||||
#include <stdlib.h> /* malloc */
|
#include <string.h> /* memset */
|
||||||
#include <string.h> /* memset */
|
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "fse_static.h"
|
#define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
|
||||||
#include "huf_static.h"
|
#include "xxhash.h" /* XXH_reset, update, digest */
|
||||||
#include "zstd_internal.h"
|
#define FSE_STATIC_LINKING_ONLY
|
||||||
|
#include "fse.h"
|
||||||
|
#define HUF_STATIC_LINKING_ONLY
|
||||||
|
#include "huf.h"
|
||||||
|
#include "zstd_internal.h" /* includes zstd.h */
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
@@ -70,6 +73,27 @@ static const U32 g_searchStrength = 8; /* control skip over incompressible dat
|
|||||||
***************************************/
|
***************************************/
|
||||||
size_t ZSTD_compressBound(size_t srcSize) { return FSE_compressBound(srcSize) + 12; }
|
size_t ZSTD_compressBound(size_t srcSize) { return FSE_compressBound(srcSize) + 12; }
|
||||||
|
|
||||||
|
static U32 ZSTD_highbit32(U32 val)
|
||||||
|
{
|
||||||
|
# if defined(_MSC_VER) /* Visual */
|
||||||
|
unsigned long r=0;
|
||||||
|
_BitScanReverse(&r, val);
|
||||||
|
return (unsigned)r;
|
||||||
|
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
|
||||||
|
return 31 - __builtin_clz(val);
|
||||||
|
# else /* Software version */
|
||||||
|
static const int DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
|
||||||
|
U32 v = val;
|
||||||
|
int r;
|
||||||
|
v |= v >> 1;
|
||||||
|
v |= v >> 2;
|
||||||
|
v |= v >> 4;
|
||||||
|
v |= v >> 8;
|
||||||
|
v |= v >> 16;
|
||||||
|
r = DeBruijnClz[(U32)(v * 0x07C4ACDDU) >> 27];
|
||||||
|
return r;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Sequence storage
|
* Sequence storage
|
||||||
@@ -99,10 +123,16 @@ struct ZSTD_CCtx_s
|
|||||||
U32 hashLog3; /* dispatch table : larger == faster, more memory */
|
U32 hashLog3; /* dispatch table : larger == faster, more memory */
|
||||||
U32 loadedDictEnd;
|
U32 loadedDictEnd;
|
||||||
U32 stage; /* 0: created; 1: init,dictLoad; 2:started */
|
U32 stage; /* 0: created; 1: init,dictLoad; 2:started */
|
||||||
|
U32 rep[ZSTD_REP_NUM];
|
||||||
|
U32 savedRep[ZSTD_REP_NUM];
|
||||||
|
U32 dictID;
|
||||||
ZSTD_parameters params;
|
ZSTD_parameters params;
|
||||||
void* workSpace;
|
void* workSpace;
|
||||||
size_t workSpaceSize;
|
size_t workSpaceSize;
|
||||||
size_t blockSize;
|
size_t blockSize;
|
||||||
|
U64 frameContentSize;
|
||||||
|
XXH64_state_t xxhState;
|
||||||
|
ZSTD_customMem customMem;
|
||||||
|
|
||||||
seqStore_t seqStore; /* sequences storage ptrs */
|
seqStore_t seqStore; /* sequences storage ptrs */
|
||||||
U32* hashTable;
|
U32* hashTable;
|
||||||
@@ -117,13 +147,31 @@ struct ZSTD_CCtx_s
|
|||||||
|
|
||||||
ZSTD_CCtx* ZSTD_createCCtx(void)
|
ZSTD_CCtx* ZSTD_createCCtx(void)
|
||||||
{
|
{
|
||||||
return (ZSTD_CCtx*) calloc(1, sizeof(ZSTD_CCtx));
|
return ZSTD_createCCtx_advanced(defaultCustomMem);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
|
||||||
|
{
|
||||||
|
ZSTD_CCtx* ctx;
|
||||||
|
|
||||||
|
if (!customMem.customAlloc && !customMem.customFree)
|
||||||
|
customMem = defaultCustomMem;
|
||||||
|
|
||||||
|
if (!customMem.customAlloc || !customMem.customFree)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ctx = (ZSTD_CCtx*) customMem.customAlloc(customMem.opaque, sizeof(ZSTD_CCtx));
|
||||||
|
if (!ctx) return NULL;
|
||||||
|
memset(ctx, 0, sizeof(ZSTD_CCtx));
|
||||||
|
memcpy(&ctx->customMem, &customMem, sizeof(ZSTD_customMem));
|
||||||
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
|
size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
|
||||||
{
|
{
|
||||||
free(cctx->workSpace);
|
if (cctx==NULL) return 0; /* support free on NULL */
|
||||||
free(cctx);
|
if (cctx->workSpace) cctx->customMem.customFree(cctx->customMem.opaque, cctx->workSpace);
|
||||||
|
cctx->customMem.customFree(cctx->customMem.opaque, cctx);
|
||||||
return 0; /* reserved as a potential error code in the future */
|
return 0; /* reserved as a potential error code in the future */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,8 +202,6 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static unsigned ZSTD_highbit(U32 val);
|
|
||||||
|
|
||||||
/** ZSTD_checkCParams_advanced() :
|
/** ZSTD_checkCParams_advanced() :
|
||||||
temporary work-around, while the compressor compatibility remains limited regarding windowLog < 18 */
|
temporary work-around, while the compressor compatibility remains limited regarding windowLog < 18 */
|
||||||
size_t ZSTD_checkCParams_advanced(ZSTD_compressionParameters cParams, U64 srcSize)
|
size_t ZSTD_checkCParams_advanced(ZSTD_compressionParameters cParams, U64 srcSize)
|
||||||
@@ -169,30 +215,32 @@ size_t ZSTD_checkCParams_advanced(ZSTD_compressionParameters cParams, U64 srcSiz
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** ZSTD_adjustParams() :
|
/** ZSTD_adjustCParams() :
|
||||||
optimize params for q given input (`srcSize` and `dictSize`).
|
optimize cPar for a given input (`srcSize` and `dictSize`).
|
||||||
mostly downsizing to reduce memory consumption and initialization.
|
mostly downsizing to reduce memory consumption and initialization.
|
||||||
Both `srcSize` and `dictSize` are optional (use 0 if unknown),
|
Both `srcSize` and `dictSize` are optional (use 0 if unknown),
|
||||||
but if both are 0, no optimization can be done.
|
but if both are 0, no optimization can be done.
|
||||||
Note : params is considered validated at this stage. Use ZSTD_checkParams() to ensure that. */
|
Note : cPar is considered validated at this stage. Use ZSTD_checkParams() to ensure that. */
|
||||||
void ZSTD_adjustCParams(ZSTD_compressionParameters* params, U64 srcSize, size_t dictSize)
|
ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, U64 srcSize, size_t dictSize)
|
||||||
{
|
{
|
||||||
if (srcSize+dictSize == 0) return; /* no size information available : no adjustment */
|
if (srcSize+dictSize == 0) return cPar; /* no size information available : no adjustment */
|
||||||
|
|
||||||
/* resize params, to use less memory when necessary */
|
/* resize params, to use less memory when necessary */
|
||||||
{ U32 const minSrcSize = (srcSize==0) ? 500 : 0;
|
{ U32 const minSrcSize = (srcSize==0) ? 500 : 0;
|
||||||
U64 const rSize = srcSize + dictSize + minSrcSize;
|
U64 const rSize = srcSize + dictSize + minSrcSize;
|
||||||
if (rSize < ((U64)1<<ZSTD_WINDOWLOG_MAX)) {
|
if (rSize < ((U64)1<<ZSTD_WINDOWLOG_MAX)) {
|
||||||
U32 const srcLog = ZSTD_highbit((U32)(rSize)-1) + 1;
|
U32 const srcLog = ZSTD_highbit32((U32)(rSize)-1) + 1;
|
||||||
if (params->windowLog > srcLog) params->windowLog = srcLog;
|
if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;
|
||||||
} }
|
} }
|
||||||
if (params->hashLog > params->windowLog) params->hashLog = params->windowLog;
|
if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog;
|
||||||
{ U32 const btPlus = (params->strategy == ZSTD_btlazy2) || (params->strategy == ZSTD_btopt);
|
{ U32 const btPlus = (cPar.strategy == ZSTD_btlazy2) || (cPar.strategy == ZSTD_btopt);
|
||||||
U32 const maxChainLog = params->windowLog+btPlus;
|
U32 const maxChainLog = cPar.windowLog+btPlus;
|
||||||
if (params->chainLog > maxChainLog) params->chainLog = maxChainLog; } /* <= ZSTD_CHAINLOG_MAX */
|
if (cPar.chainLog > maxChainLog) cPar.chainLog = maxChainLog; } /* <= ZSTD_CHAINLOG_MAX */
|
||||||
|
|
||||||
if (params->windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) params->windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */
|
if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */
|
||||||
if ((params->hashLog < ZSTD_HASHLOG_MIN) && ((U32)params->strategy >= (U32)ZSTD_btlazy2)) params->hashLog = ZSTD_HASHLOG_MIN; /* required to ensure collision resistance in bt */
|
if ((cPar.hashLog < ZSTD_HASHLOG_MIN) && ( (U32)cPar.strategy >= (U32)ZSTD_btlazy2)) cPar.hashLog = ZSTD_HASHLOG_MIN; /* required to ensure collision resistance in bt */
|
||||||
|
|
||||||
|
return cPar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -200,6 +248,7 @@ size_t ZSTD_sizeofCCtx(ZSTD_compressionParameters cParams) /* hidden interface
|
|||||||
{
|
{
|
||||||
ZSTD_CCtx* zc = ZSTD_createCCtx();
|
ZSTD_CCtx* zc = ZSTD_createCCtx();
|
||||||
ZSTD_parameters params;
|
ZSTD_parameters params;
|
||||||
|
memset(¶ms, 0, sizeof(params));
|
||||||
params.cParams = cParams;
|
params.cParams = cParams;
|
||||||
params.fParams.contentSizeFlag = 1;
|
params.fParams.contentSizeFlag = 1;
|
||||||
ZSTD_compressBegin_advanced(zc, NULL, 0, params, 0);
|
ZSTD_compressBegin_advanced(zc, NULL, 0, params, 0);
|
||||||
@@ -211,7 +260,7 @@ size_t ZSTD_sizeofCCtx(ZSTD_compressionParameters cParams) /* hidden interface
|
|||||||
/*! ZSTD_resetCCtx_advanced() :
|
/*! ZSTD_resetCCtx_advanced() :
|
||||||
note : 'params' is expected to be validated */
|
note : 'params' is expected to be validated */
|
||||||
static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
||||||
ZSTD_parameters params, U32 reset)
|
ZSTD_parameters params, U64 frameContentSize, U32 reset)
|
||||||
{ /* note : params considered validated here */
|
{ /* note : params considered validated here */
|
||||||
const size_t blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params.cParams.windowLog);
|
const size_t blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params.cParams.windowLog);
|
||||||
const U32 divider = (params.cParams.searchLength==3) ? 3 : 4;
|
const U32 divider = (params.cParams.searchLength==3) ? 3 : 4;
|
||||||
@@ -219,7 +268,10 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
|||||||
const size_t tokenSpace = blockSize + 11*maxNbSeq;
|
const size_t tokenSpace = blockSize + 11*maxNbSeq;
|
||||||
const size_t chainSize = (params.cParams.strategy == ZSTD_fast) ? 0 : (1 << params.cParams.chainLog);
|
const size_t chainSize = (params.cParams.strategy == ZSTD_fast) ? 0 : (1 << params.cParams.chainLog);
|
||||||
const size_t hSize = ((size_t)1) << params.cParams.hashLog;
|
const size_t hSize = ((size_t)1) << params.cParams.hashLog;
|
||||||
const size_t h3Size = (zc->hashLog3) ? 1 << zc->hashLog3 : 0;
|
const U32 hashLog3 = (params.cParams.searchLength>3) ? 0 :
|
||||||
|
( (!frameContentSize || frameContentSize >= 8192) ? ZSTD_HASHLOG3_MAX :
|
||||||
|
((frameContentSize >= 2048) ? ZSTD_HASHLOG3_MIN + 1 : ZSTD_HASHLOG3_MIN) );
|
||||||
|
const size_t h3Size = ((size_t)1) << hashLog3;
|
||||||
const size_t tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
|
const size_t tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
|
||||||
|
|
||||||
/* Check if workSpace is large enough, alloc a new one if needed */
|
/* Check if workSpace is large enough, alloc a new one if needed */
|
||||||
@@ -228,17 +280,19 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
|||||||
size_t const neededSpace = tableSpace + (256*sizeof(U32)) /* huffTable */ + tokenSpace
|
size_t const neededSpace = tableSpace + (256*sizeof(U32)) /* huffTable */ + tokenSpace
|
||||||
+ ((params.cParams.strategy == ZSTD_btopt) ? optSpace : 0);
|
+ ((params.cParams.strategy == ZSTD_btopt) ? optSpace : 0);
|
||||||
if (zc->workSpaceSize < neededSpace) {
|
if (zc->workSpaceSize < neededSpace) {
|
||||||
free(zc->workSpace);
|
zc->customMem.customFree(zc->customMem.opaque, zc->workSpace);
|
||||||
zc->workSpace = malloc(neededSpace);
|
zc->workSpace = zc->customMem.customAlloc(zc->customMem.opaque, neededSpace);
|
||||||
if (zc->workSpace == NULL) return ERROR(memory_allocation);
|
if (zc->workSpace == NULL) return ERROR(memory_allocation);
|
||||||
zc->workSpaceSize = neededSpace;
|
zc->workSpaceSize = neededSpace;
|
||||||
} }
|
} }
|
||||||
|
|
||||||
if (reset) memset(zc->workSpace, 0, tableSpace ); /* reset only tables */
|
if (reset) memset(zc->workSpace, 0, tableSpace ); /* reset only tables */
|
||||||
zc->hashTable3 = (U32*)(zc->workSpace);
|
XXH64_reset(&zc->xxhState, 0);
|
||||||
zc->hashTable = zc->hashTable3 + h3Size;
|
zc->hashLog3 = hashLog3;
|
||||||
|
zc->hashTable = (U32*)(zc->workSpace);
|
||||||
zc->chainTable = zc->hashTable + hSize;
|
zc->chainTable = zc->hashTable + hSize;
|
||||||
zc->seqStore.buffer = zc->chainTable + chainSize;
|
zc->hashTable3 = zc->chainTable + chainSize;
|
||||||
|
zc->seqStore.buffer = zc->hashTable3 + h3Size;
|
||||||
zc->hufTable = (HUF_CElt*)zc->seqStore.buffer;
|
zc->hufTable = (HUF_CElt*)zc->seqStore.buffer;
|
||||||
zc->flagStaticTables = 0;
|
zc->flagStaticTables = 0;
|
||||||
zc->seqStore.buffer = ((U32*)(zc->seqStore.buffer)) + 256;
|
zc->seqStore.buffer = ((U32*)(zc->seqStore.buffer)) + 256;
|
||||||
@@ -251,6 +305,8 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
|||||||
zc->lowLimit = 0;
|
zc->lowLimit = 0;
|
||||||
zc->params = params;
|
zc->params = params;
|
||||||
zc->blockSize = blockSize;
|
zc->blockSize = blockSize;
|
||||||
|
zc->frameContentSize = frameContentSize;
|
||||||
|
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) zc->rep[i] = repStartValue[i]; }
|
||||||
|
|
||||||
if (params.cParams.strategy == ZSTD_btopt) {
|
if (params.cParams.strategy == ZSTD_btopt) {
|
||||||
zc->seqStore.litFreq = (U32*)(zc->seqStore.buffer);
|
zc->seqStore.litFreq = (U32*)(zc->seqStore.buffer);
|
||||||
@@ -271,6 +327,7 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
|||||||
zc->seqStore.litStart = zc->seqStore.offCodeStart + maxNbSeq;
|
zc->seqStore.litStart = zc->seqStore.offCodeStart + maxNbSeq;
|
||||||
|
|
||||||
zc->stage = 1;
|
zc->stage = 1;
|
||||||
|
zc->dictID = 0;
|
||||||
zc->loadedDictEnd = 0;
|
zc->loadedDictEnd = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -285,19 +342,19 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx)
|
|||||||
{
|
{
|
||||||
if (srcCCtx->stage!=1) return ERROR(stage_wrong);
|
if (srcCCtx->stage!=1) return ERROR(stage_wrong);
|
||||||
|
|
||||||
dstCCtx->hashLog3 = srcCCtx->hashLog3; /* must be before ZSTD_resetCCtx_advanced */
|
memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
|
||||||
ZSTD_resetCCtx_advanced(dstCCtx, srcCCtx->params, 0);
|
ZSTD_resetCCtx_advanced(dstCCtx, srcCCtx->params, srcCCtx->frameContentSize, 0);
|
||||||
dstCCtx->params.fParams.contentSizeFlag = 0; /* content size different from the one set during srcCCtx init */
|
dstCCtx->params.fParams.contentSizeFlag = 0; /* content size different from the one set during srcCCtx init */
|
||||||
|
|
||||||
/* copy tables */
|
/* copy tables */
|
||||||
{ const size_t chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
|
{ const size_t chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
|
||||||
const size_t hSize = ((size_t)1) << srcCCtx->params.cParams.hashLog;
|
const size_t hSize = ((size_t)1) << srcCCtx->params.cParams.hashLog;
|
||||||
const size_t h3Size = (srcCCtx->hashLog3) ? 1 << srcCCtx->hashLog3 : 0;
|
const size_t h3Size = (size_t)1 << srcCCtx->hashLog3;
|
||||||
const size_t tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
|
const size_t tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
|
||||||
memcpy(dstCCtx->workSpace, srcCCtx->workSpace, tableSpace);
|
memcpy(dstCCtx->workSpace, srcCCtx->workSpace, tableSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy dictionary pointers */
|
/* copy dictionary offsets */
|
||||||
dstCCtx->nextToUpdate = srcCCtx->nextToUpdate;
|
dstCCtx->nextToUpdate = srcCCtx->nextToUpdate;
|
||||||
dstCCtx->nextToUpdate3= srcCCtx->nextToUpdate3;
|
dstCCtx->nextToUpdate3= srcCCtx->nextToUpdate3;
|
||||||
dstCCtx->nextSrc = srcCCtx->nextSrc;
|
dstCCtx->nextSrc = srcCCtx->nextSrc;
|
||||||
@@ -306,6 +363,7 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx)
|
|||||||
dstCCtx->dictLimit = srcCCtx->dictLimit;
|
dstCCtx->dictLimit = srcCCtx->dictLimit;
|
||||||
dstCCtx->lowLimit = srcCCtx->lowLimit;
|
dstCCtx->lowLimit = srcCCtx->lowLimit;
|
||||||
dstCCtx->loadedDictEnd= srcCCtx->loadedDictEnd;
|
dstCCtx->loadedDictEnd= srcCCtx->loadedDictEnd;
|
||||||
|
dstCCtx->dictID = srcCCtx->dictID;
|
||||||
|
|
||||||
/* copy entropy tables */
|
/* copy entropy tables */
|
||||||
dstCCtx->flagStaticTables = srcCCtx->flagStaticTables;
|
dstCCtx->flagStaticTables = srcCCtx->flagStaticTables;
|
||||||
@@ -353,8 +411,9 @@ static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
|
|||||||
/* Frame format description
|
/* Frame format description
|
||||||
Frame Header - [ Block Header - Block ] - Frame End
|
Frame Header - [ Block Header - Block ] - Frame End
|
||||||
1) Frame Header
|
1) Frame Header
|
||||||
- 4 bytes - Magic Number : ZSTD_MAGICNUMBER (defined within zstd_static.h)
|
- 4 bytes : Magic Number : ZSTD_MAGICNUMBER (defined within zstd_static.h)
|
||||||
- 1 byte - Frame Descriptor
|
- 1 byte : Frame Header Descriptor
|
||||||
|
- 1-13 bytes : Optional fields
|
||||||
2) Block Header
|
2) Block Header
|
||||||
- 3 bytes, starting with a 2-bits descriptor
|
- 3 bytes, starting with a 2-bits descriptor
|
||||||
Uncompressed, Compressed, Frame End, unused
|
Uncompressed, Compressed, Frame End, unused
|
||||||
@@ -367,13 +426,38 @@ static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
|
|||||||
|
|
||||||
/* Frame descriptor
|
/* Frame descriptor
|
||||||
|
|
||||||
1 byte, using :
|
// old
|
||||||
|
1 byte - Alloc :
|
||||||
bit 0-3 : windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN (see zstd_internal.h)
|
bit 0-3 : windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN (see zstd_internal.h)
|
||||||
bit 4 : minmatch 4(0) or 3(1)
|
bit 4 : reserved for windowLog (must be zero)
|
||||||
bit 5 : reserved (must be zero)
|
bit 5 : reserved (must be zero)
|
||||||
bit 6-7 : Frame content size : unknown, 1 byte, 2 bytes, 8 bytes
|
bit 6-7 : Frame content size : unknown, 1 byte, 2 bytes, 8 bytes
|
||||||
|
|
||||||
Optional : content size (0, 1, 2 or 8 bytes)
|
1 byte - checker :
|
||||||
|
bit 0-1 : dictID (0, 1, 2 or 4 bytes)
|
||||||
|
bit 2-7 : reserved (must be zero)
|
||||||
|
|
||||||
|
|
||||||
|
// new
|
||||||
|
1 byte - FrameHeaderDescription :
|
||||||
|
bit 0-1 : dictID (0, 1, 2 or 4 bytes)
|
||||||
|
bit 2-4 : reserved (must be zero)
|
||||||
|
bit 5 : SkippedWindowLog (if 1, WindowLog byte is not present)
|
||||||
|
bit 6-7 : FrameContentFieldsize (0, 2, 4, or 8)
|
||||||
|
if (SkippedWindowLog && !FrameContentFieldsize) FrameContentFieldsize=1;
|
||||||
|
|
||||||
|
Optional : WindowLog (0 or 1 byte)
|
||||||
|
bit 0-2 : octal Fractional (1/8th)
|
||||||
|
bit 3-7 : Power of 2, with 0 = 1 KB (up to 2 TB)
|
||||||
|
|
||||||
|
Optional : dictID (0, 1, 2 or 4 bytes)
|
||||||
|
Automatic adaptation
|
||||||
|
0 : no dictID
|
||||||
|
1 : 1 - 255
|
||||||
|
2 : 256 - 65535
|
||||||
|
4 : all other values
|
||||||
|
|
||||||
|
Optional : content size (0, 1, 2, 4 or 8 bytes)
|
||||||
0 : unknown
|
0 : unknown
|
||||||
1 : 0-255 bytes
|
1 : 0-255 bytes
|
||||||
2 : 256 - 65535+256
|
2 : 256 - 65535+256
|
||||||
@@ -494,15 +578,15 @@ static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void
|
|||||||
switch(flSize)
|
switch(flSize)
|
||||||
{
|
{
|
||||||
case 1: /* 2 - 1 - 5 */
|
case 1: /* 2 - 1 - 5 */
|
||||||
ostart[0] = (BYTE)((IS_RAW<<6) + (0<<5) + srcSize);
|
ostart[0] = (BYTE)((lbt_raw<<6) + (0<<5) + srcSize);
|
||||||
break;
|
break;
|
||||||
case 2: /* 2 - 2 - 12 */
|
case 2: /* 2 - 2 - 12 */
|
||||||
ostart[0] = (BYTE)((IS_RAW<<6) + (2<<4) + (srcSize >> 8));
|
ostart[0] = (BYTE)((lbt_raw<<6) + (2<<4) + (srcSize >> 8));
|
||||||
ostart[1] = (BYTE)srcSize;
|
ostart[1] = (BYTE)srcSize;
|
||||||
break;
|
break;
|
||||||
default: /*note : should not be necessary : flSize is within {1,2,3} */
|
default: /*note : should not be necessary : flSize is within {1,2,3} */
|
||||||
case 3: /* 2 - 2 - 20 */
|
case 3: /* 2 - 2 - 20 */
|
||||||
ostart[0] = (BYTE)((IS_RAW<<6) + (3<<4) + (srcSize >> 16));
|
ostart[0] = (BYTE)((lbt_raw<<6) + (3<<4) + (srcSize >> 16));
|
||||||
ostart[1] = (BYTE)(srcSize>>8);
|
ostart[1] = (BYTE)(srcSize>>8);
|
||||||
ostart[2] = (BYTE)srcSize;
|
ostart[2] = (BYTE)srcSize;
|
||||||
break;
|
break;
|
||||||
@@ -522,15 +606,15 @@ static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, cons
|
|||||||
switch(flSize)
|
switch(flSize)
|
||||||
{
|
{
|
||||||
case 1: /* 2 - 1 - 5 */
|
case 1: /* 2 - 1 - 5 */
|
||||||
ostart[0] = (BYTE)((IS_RLE<<6) + (0<<5) + srcSize);
|
ostart[0] = (BYTE)((lbt_rle<<6) + (0<<5) + srcSize);
|
||||||
break;
|
break;
|
||||||
case 2: /* 2 - 2 - 12 */
|
case 2: /* 2 - 2 - 12 */
|
||||||
ostart[0] = (BYTE)((IS_RLE<<6) + (2<<4) + (srcSize >> 8));
|
ostart[0] = (BYTE)((lbt_rle<<6) + (2<<4) + (srcSize >> 8));
|
||||||
ostart[1] = (BYTE)srcSize;
|
ostart[1] = (BYTE)srcSize;
|
||||||
break;
|
break;
|
||||||
default: /*note : should not be necessary : flSize is necessarily within {1,2,3} */
|
default: /*note : should not be necessary : flSize is necessarily within {1,2,3} */
|
||||||
case 3: /* 2 - 2 - 20 */
|
case 3: /* 2 - 2 - 20 */
|
||||||
ostart[0] = (BYTE)((IS_RLE<<6) + (3<<4) + (srcSize >> 16));
|
ostart[0] = (BYTE)((lbt_rle<<6) + (3<<4) + (srcSize >> 16));
|
||||||
ostart[1] = (BYTE)(srcSize>>8);
|
ostart[1] = (BYTE)(srcSize>>8);
|
||||||
ostart[2] = (BYTE)srcSize;
|
ostart[2] = (BYTE)srcSize;
|
||||||
break;
|
break;
|
||||||
@@ -551,7 +635,7 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
|
|||||||
size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
|
size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
|
||||||
BYTE* const ostart = (BYTE*)dst;
|
BYTE* const ostart = (BYTE*)dst;
|
||||||
U32 singleStream = srcSize < 256;
|
U32 singleStream = srcSize < 256;
|
||||||
U32 hType = IS_HUF;
|
litBlockType_t hType = lbt_huffman;
|
||||||
size_t cLitSize;
|
size_t cLitSize;
|
||||||
|
|
||||||
|
|
||||||
@@ -563,7 +647,7 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
|
|||||||
|
|
||||||
if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall); /* not enough space for compression */
|
if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall); /* not enough space for compression */
|
||||||
if (zc->flagStaticTables && (lhSize==3)) {
|
if (zc->flagStaticTables && (lhSize==3)) {
|
||||||
hType = IS_PCH;
|
hType = lbt_repeat;
|
||||||
singleStream = 1;
|
singleStream = 1;
|
||||||
cLitSize = HUF_compress1X_usingCTable(ostart+lhSize, dstCapacity-lhSize, src, srcSize, zc->hufTable);
|
cLitSize = HUF_compress1X_usingCTable(ostart+lhSize, dstCapacity-lhSize, src, srcSize, zc->hufTable);
|
||||||
} else {
|
} else {
|
||||||
@@ -620,7 +704,7 @@ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr, size_t const nbSeq)
|
|||||||
size_t u;
|
size_t u;
|
||||||
for (u=0; u<nbSeq; u++) {
|
for (u=0; u<nbSeq; u++) {
|
||||||
U32 const ll = llTable[u];
|
U32 const ll = llTable[u];
|
||||||
llCodeTable[u] = (ll>63) ? (BYTE)ZSTD_highbit(ll) + LL_deltaCode : LL_Code[ll];
|
llCodeTable[u] = (ll>63) ? (BYTE)ZSTD_highbit32(ll) + LL_deltaCode : LL_Code[ll];
|
||||||
}
|
}
|
||||||
if (seqStorePtr->longLengthID==1)
|
if (seqStorePtr->longLengthID==1)
|
||||||
llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
|
llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
|
||||||
@@ -630,7 +714,7 @@ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr, size_t const nbSeq)
|
|||||||
{ const U32* const offsetTable = seqStorePtr->offsetStart;
|
{ const U32* const offsetTable = seqStorePtr->offsetStart;
|
||||||
BYTE* const ofCodeTable = seqStorePtr->offCodeStart;
|
BYTE* const ofCodeTable = seqStorePtr->offCodeStart;
|
||||||
size_t u;
|
size_t u;
|
||||||
for (u=0; u<nbSeq; u++) ofCodeTable[u] = (BYTE)ZSTD_highbit(offsetTable[u]);
|
for (u=0; u<nbSeq; u++) ofCodeTable[u] = (BYTE)ZSTD_highbit32(offsetTable[u]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ML codes */
|
/* ML codes */
|
||||||
@@ -648,7 +732,7 @@ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr, size_t const nbSeq)
|
|||||||
size_t u;
|
size_t u;
|
||||||
for (u=0; u<nbSeq; u++) {
|
for (u=0; u<nbSeq; u++) {
|
||||||
U32 const ml = mlTable[u];
|
U32 const ml = mlTable[u];
|
||||||
mlCodeTable[u] = (ml>127) ? (BYTE)ZSTD_highbit(ml) + ML_deltaCode : ML_Code[ml];
|
mlCodeTable[u] = (ml>127) ? (BYTE)ZSTD_highbit32(ml) + ML_deltaCode : ML_Code[ml];
|
||||||
}
|
}
|
||||||
if (seqStorePtr->longLengthID==2)
|
if (seqStorePtr->longLengthID==2)
|
||||||
mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
|
mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
|
||||||
@@ -837,6 +921,9 @@ _check_compressibility:
|
|||||||
size_t const maxCSize = srcSize - minGain;
|
size_t const maxCSize = srcSize - minGain;
|
||||||
if ((size_t)(op-ostart) >= maxCSize) return 0; }
|
if ((size_t)(op-ostart) >= maxCSize) return 0; }
|
||||||
|
|
||||||
|
/* confirm repcodes */
|
||||||
|
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) zc->rep[i] = zc->savedRep[i]; }
|
||||||
|
|
||||||
return op - ostart;
|
return op - ostart;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -846,17 +933,17 @@ _check_compressibility:
|
|||||||
`offsetCode` : distance to match, or 0 == repCode.
|
`offsetCode` : distance to match, or 0 == repCode.
|
||||||
`matchCode` : matchLength - MINMATCH
|
`matchCode` : matchLength - MINMATCH
|
||||||
*/
|
*/
|
||||||
MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offsetCode, size_t matchCode)
|
MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, size_t offsetCode, size_t matchCode)
|
||||||
{
|
{
|
||||||
#if 0 /* for debug */
|
#if 0 /* for debug */
|
||||||
static const BYTE* g_start = NULL;
|
static const BYTE* g_start = NULL;
|
||||||
const U32 pos = (U32)(literals - g_start);
|
const U32 pos = (U32)(literals - g_start);
|
||||||
if (g_start==NULL) g_start = literals;
|
if (g_start==NULL) g_start = literals;
|
||||||
if ((pos > 2587900) && (pos < 2588050))
|
//if ((pos > 1) && (pos < 50000))
|
||||||
printf("Cpos %6u :%5u literals & match %3u bytes at distance %6u \n",
|
printf("Cpos %6u :%5u literals & match %3u bytes at distance %6u \n",
|
||||||
pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode);
|
pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode);
|
||||||
#endif
|
#endif
|
||||||
ZSTD_statsUpdatePrices(&seqStorePtr->stats, litLength, literals, offsetCode, matchCode);
|
ZSTD_statsUpdatePrices(&seqStorePtr->stats, litLength, (const BYTE*)literals, offsetCode, matchCode); /* debug only */
|
||||||
|
|
||||||
/* copy Literals */
|
/* copy Literals */
|
||||||
ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
|
ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
|
||||||
@@ -942,7 +1029,7 @@ static size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLim
|
|||||||
const BYTE* const pStart = pIn;
|
const BYTE* const pStart = pIn;
|
||||||
|
|
||||||
while ((pIn<pInLimit-(sizeof(size_t)-1))) {
|
while ((pIn<pInLimit-(sizeof(size_t)-1))) {
|
||||||
size_t diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
|
size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
|
||||||
if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }
|
if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }
|
||||||
pIn += ZSTD_NbCommonBytes(diff);
|
pIn += ZSTD_NbCommonBytes(diff);
|
||||||
return (size_t)(pIn - pStart);
|
return (size_t)(pIn - pStart);
|
||||||
@@ -959,10 +1046,8 @@ static size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLim
|
|||||||
*/
|
*/
|
||||||
static size_t ZSTD_count_2segments(const BYTE* ip, const BYTE* match, const BYTE* iEnd, const BYTE* mEnd, const BYTE* iStart)
|
static size_t ZSTD_count_2segments(const BYTE* ip, const BYTE* match, const BYTE* iEnd, const BYTE* mEnd, const BYTE* iStart)
|
||||||
{
|
{
|
||||||
size_t matchLength;
|
const BYTE* const vEnd = MIN( ip + (mEnd - match), iEnd);
|
||||||
const BYTE* vEnd = ip + (mEnd - match);
|
size_t matchLength = ZSTD_count(ip, match, vEnd);
|
||||||
if (vEnd > iEnd) vEnd = iEnd;
|
|
||||||
matchLength = ZSTD_count(ip, match, vEnd);
|
|
||||||
if (match + matchLength == mEnd)
|
if (match + matchLength == mEnd)
|
||||||
matchLength += ZSTD_count(ip+matchLength, iStart, iEnd);
|
matchLength += ZSTD_count(ip+matchLength, iStart, iEnd);
|
||||||
return matchLength;
|
return matchLength;
|
||||||
@@ -1025,43 +1110,47 @@ static void ZSTD_fillHashTable (ZSTD_CCtx* zc, const void* end, const U32 mls)
|
|||||||
|
|
||||||
|
|
||||||
FORCE_INLINE
|
FORCE_INLINE
|
||||||
void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
|
void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
const U32 mls)
|
const U32 mls)
|
||||||
{
|
{
|
||||||
U32* const hashTable = zc->hashTable;
|
U32* const hashTable = cctx->hashTable;
|
||||||
const U32 hBits = zc->params.cParams.hashLog;
|
const U32 hBits = cctx->params.cParams.hashLog;
|
||||||
seqStore_t* seqStorePtr = &(zc->seqStore);
|
seqStore_t* seqStorePtr = &(cctx->seqStore);
|
||||||
const BYTE* const base = zc->base;
|
const BYTE* const base = cctx->base;
|
||||||
const BYTE* const istart = (const BYTE*)src;
|
const BYTE* const istart = (const BYTE*)src;
|
||||||
const BYTE* ip = istart;
|
const BYTE* ip = istart;
|
||||||
const BYTE* anchor = istart;
|
const BYTE* anchor = istart;
|
||||||
const U32 lowIndex = zc->dictLimit;
|
const U32 lowestIndex = cctx->dictLimit;
|
||||||
const BYTE* const lowest = base + lowIndex;
|
const BYTE* const lowest = base + lowestIndex;
|
||||||
const BYTE* const iend = istart + srcSize;
|
const BYTE* const iend = istart + srcSize;
|
||||||
const BYTE* const ilimit = iend - 8;
|
const BYTE* const ilimit = iend - 8;
|
||||||
size_t offset_2=REPCODE_STARTVALUE, offset_1=REPCODE_STARTVALUE;
|
size_t offset_1=cctx->rep[0], offset_2=cctx->rep[1];
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
ZSTD_resetSeqStore(seqStorePtr);
|
ZSTD_resetSeqStore(seqStorePtr);
|
||||||
if (ip < lowest+REPCODE_STARTVALUE) ip = lowest+REPCODE_STARTVALUE;
|
ip += (ip==lowest);
|
||||||
|
{ U32 const maxRep = (U32)(ip-lowest);
|
||||||
|
if (offset_1 > maxRep) offset_1 = 0;
|
||||||
|
if (offset_2 > maxRep) offset_2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Main Search Loop */
|
/* Main Search Loop */
|
||||||
while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
|
while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
|
||||||
size_t mlCode;
|
size_t mlCode;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
const size_t h = ZSTD_hashPtr(ip, hBits, mls);
|
size_t const h = ZSTD_hashPtr(ip, hBits, mls);
|
||||||
const U32 matchIndex = hashTable[h];
|
U32 const current = (U32)(ip-base);
|
||||||
|
U32 const matchIndex = hashTable[h];
|
||||||
const BYTE* match = base + matchIndex;
|
const BYTE* match = base + matchIndex;
|
||||||
const U32 current = (U32)(ip-base);
|
|
||||||
hashTable[h] = current; /* update hash table */
|
hashTable[h] = current; /* update hash table */
|
||||||
|
|
||||||
if (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)) { /* note : by construction, offset_1 <= current */
|
if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { /* note : by construction, offset_1 <= current */
|
||||||
mlCode = ZSTD_count(ip+1+EQUAL_READ32, ip+1+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
|
mlCode = ZSTD_count(ip+1+EQUAL_READ32, ip+1+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
|
||||||
ip++;
|
ip++;
|
||||||
ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mlCode-MINMATCH);
|
ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mlCode-MINMATCH);
|
||||||
} else {
|
} else {
|
||||||
if ( (matchIndex <= lowIndex) ||
|
if ( (matchIndex <= lowestIndex) ||
|
||||||
(MEM_read32(match) != MEM_read32(ip)) ) {
|
(MEM_read32(match) != MEM_read32(ip)) ) {
|
||||||
ip += ((ip-anchor) >> g_searchStrength) + 1;
|
ip += ((ip-anchor) >> g_searchStrength) + 1;
|
||||||
continue;
|
continue;
|
||||||
@@ -1085,7 +1174,8 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
|
|||||||
hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
|
hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
|
||||||
/* check immediate repcode */
|
/* check immediate repcode */
|
||||||
while ( (ip <= ilimit)
|
while ( (ip <= ilimit)
|
||||||
&& (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) {
|
&& ( (offset_2>0)
|
||||||
|
& (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
|
||||||
/* store sequence */
|
/* store sequence */
|
||||||
size_t const rlCode = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_2, iend) + EQUAL_READ32;
|
size_t const rlCode = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_2, iend) + EQUAL_READ32;
|
||||||
{ size_t const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
|
{ size_t const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
|
||||||
@@ -1096,6 +1186,10 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
|
|||||||
continue; /* faster when present ... (?) */
|
continue; /* faster when present ... (?) */
|
||||||
} } }
|
} } }
|
||||||
|
|
||||||
|
/* save reps for next block */
|
||||||
|
cctx->savedRep[0] = offset_1 ? (U32)offset_1 : (U32)(iend-base);
|
||||||
|
cctx->savedRep[1] = offset_2 ? (U32)offset_2 : (U32)(iend-base);
|
||||||
|
|
||||||
/* Last Literals */
|
/* Last Literals */
|
||||||
{ size_t const lastLLSize = iend - anchor;
|
{ size_t const lastLLSize = iend - anchor;
|
||||||
memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
||||||
@@ -1135,22 +1229,20 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
const BYTE* const istart = (const BYTE*)src;
|
const BYTE* const istart = (const BYTE*)src;
|
||||||
const BYTE* ip = istart;
|
const BYTE* ip = istart;
|
||||||
const BYTE* anchor = istart;
|
const BYTE* anchor = istart;
|
||||||
const U32 lowLimit = ctx->lowLimit;
|
const U32 lowestIndex = ctx->lowLimit;
|
||||||
const BYTE* const dictStart = dictBase + lowLimit;
|
const BYTE* const dictStart = dictBase + lowestIndex;
|
||||||
const U32 dictLimit = ctx->dictLimit;
|
const U32 dictLimit = ctx->dictLimit;
|
||||||
const BYTE* const lowPrefixPtr = base + dictLimit;
|
const BYTE* const lowPrefixPtr = base + dictLimit;
|
||||||
const BYTE* const dictEnd = dictBase + dictLimit;
|
const BYTE* const dictEnd = dictBase + dictLimit;
|
||||||
const BYTE* const iend = istart + srcSize;
|
const BYTE* const iend = istart + srcSize;
|
||||||
const BYTE* const ilimit = iend - 8;
|
const BYTE* const ilimit = iend - 8;
|
||||||
|
U32 offset_1=ctx->rep[0], offset_2=ctx->rep[1];
|
||||||
U32 offset_2=REPCODE_STARTVALUE, offset_1=REPCODE_STARTVALUE;
|
|
||||||
|
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
ZSTD_resetSeqStore(seqStorePtr);
|
ZSTD_resetSeqStore(seqStorePtr);
|
||||||
/* skip first position to avoid read overflow during repcode match check */
|
/* skip first position to avoid read overflow during repcode match check */
|
||||||
hashTable[ZSTD_hashPtr(ip+0, hBits, mls)] = (U32)(ip-base+0);
|
hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip-base);
|
||||||
ip += REPCODE_STARTVALUE;
|
ip++;
|
||||||
|
|
||||||
/* Main Search Loop */
|
/* Main Search Loop */
|
||||||
while (ip < ilimit) { /* < instead of <=, because (ip+1) */
|
while (ip < ilimit) { /* < instead of <=, because (ip+1) */
|
||||||
@@ -1166,14 +1258,14 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
U32 offset;
|
U32 offset;
|
||||||
hashTable[h] = current; /* update hash table */
|
hashTable[h] = current; /* update hash table */
|
||||||
|
|
||||||
if ( ((repIndex >= dictLimit) || (repIndex <= dictLimit-4))
|
if ( (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
|
||||||
&& (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
|
&& (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
|
||||||
const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
|
const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
|
||||||
mlCode = ZSTD_count_2segments(ip+1+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repMatchEnd, lowPrefixPtr) + EQUAL_READ32;
|
mlCode = ZSTD_count_2segments(ip+1+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repMatchEnd, lowPrefixPtr) + EQUAL_READ32;
|
||||||
ip++;
|
ip++;
|
||||||
ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mlCode-MINMATCH);
|
ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mlCode-MINMATCH);
|
||||||
} else {
|
} else {
|
||||||
if ( (matchIndex < lowLimit) ||
|
if ( (matchIndex < lowestIndex) ||
|
||||||
(MEM_read32(match) != MEM_read32(ip)) ) {
|
(MEM_read32(match) != MEM_read32(ip)) ) {
|
||||||
ip += ((ip-anchor) >> g_searchStrength) + 1;
|
ip += ((ip-anchor) >> g_searchStrength) + 1;
|
||||||
continue;
|
continue;
|
||||||
@@ -1201,8 +1293,8 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
U32 const current2 = (U32)(ip-base);
|
U32 const current2 = (U32)(ip-base);
|
||||||
U32 const repIndex2 = current2 - offset_2;
|
U32 const repIndex2 = current2 - offset_2;
|
||||||
const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
|
const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
|
||||||
if ( ((repIndex2 <= dictLimit-4) || (repIndex2 >= dictLimit))
|
if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */
|
||||||
&& (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
|
&& (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
|
||||||
const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
|
const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
|
||||||
size_t repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
|
size_t repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
|
||||||
U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
|
U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
|
||||||
@@ -1215,6 +1307,9 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
break;
|
break;
|
||||||
} } }
|
} } }
|
||||||
|
|
||||||
|
/* save reps for next block */
|
||||||
|
ctx->savedRep[0] = offset_1; ctx->savedRep[1] = offset_2;
|
||||||
|
|
||||||
/* Last Literals */
|
/* Last Literals */
|
||||||
{ size_t const lastLLSize = iend - anchor;
|
{ size_t const lastLLSize = iend - anchor;
|
||||||
memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
||||||
@@ -1398,7 +1493,7 @@ static size_t ZSTD_insertBtAndFindBestMatch (
|
|||||||
if (matchLength > bestLength) {
|
if (matchLength > bestLength) {
|
||||||
if (matchLength > matchEndIdx - matchIndex)
|
if (matchLength > matchEndIdx - matchIndex)
|
||||||
matchEndIdx = matchIndex + (U32)matchLength;
|
matchEndIdx = matchIndex + (U32)matchLength;
|
||||||
if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit(current-matchIndex+1) - ZSTD_highbit((U32)offsetPtr[0]+1)) )
|
if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
|
||||||
bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;
|
bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;
|
||||||
if (ip+matchLength == iend) /* equal : no way to know if inf or sup */
|
if (ip+matchLength == iend) /* equal : no way to know if inf or sup */
|
||||||
break; /* drop, to guarantee consistency (miss a little bit of compression) */
|
break; /* drop, to guarantee consistency (miss a little bit of compression) */
|
||||||
@@ -1642,15 +1737,19 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|||||||
typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
|
typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
|
||||||
size_t* offsetPtr,
|
size_t* offsetPtr,
|
||||||
U32 maxNbAttempts, U32 matchLengthSearch);
|
U32 maxNbAttempts, U32 matchLengthSearch);
|
||||||
searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS;
|
searchMax_f const searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS;
|
||||||
|
U32 rep[ZSTD_REP_INIT];
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
U32 rep[ZSTD_REP_INIT];
|
ip += (ip==base);
|
||||||
{ U32 i ; for (i=0; i<ZSTD_REP_INIT; i++) rep[i]=REPCODE_STARTVALUE; }
|
|
||||||
|
|
||||||
ctx->nextToUpdate3 = ctx->nextToUpdate;
|
ctx->nextToUpdate3 = ctx->nextToUpdate;
|
||||||
ZSTD_resetSeqStore(seqStorePtr);
|
ZSTD_resetSeqStore(seqStorePtr);
|
||||||
if ((ip-base) < REPCODE_STARTVALUE) ip = base + REPCODE_STARTVALUE;
|
{ U32 i;
|
||||||
|
U32 const maxRep = (U32)(ip-base);
|
||||||
|
for (i=0; i<ZSTD_REP_INIT; i++) {
|
||||||
|
rep[i]=ctx->rep[i];
|
||||||
|
if (rep[i]>maxRep) rep[i]=0;
|
||||||
|
} }
|
||||||
|
|
||||||
/* Match Loop */
|
/* Match Loop */
|
||||||
while (ip < ilimit) {
|
while (ip < ilimit) {
|
||||||
@@ -1659,7 +1758,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|||||||
const BYTE* start=ip+1;
|
const BYTE* start=ip+1;
|
||||||
|
|
||||||
/* check repCode */
|
/* check repCode */
|
||||||
if (MEM_read32(ip+1) == MEM_read32(ip+1 - rep[0])) {
|
if ((rep[0]>0) & (MEM_read32(ip+1) == MEM_read32(ip+1 - rep[0]))) {
|
||||||
/* repcode : we take it */
|
/* repcode : we take it */
|
||||||
matchLength = ZSTD_count(ip+1+EQUAL_READ32, ip+1+EQUAL_READ32-rep[0], iend) + EQUAL_READ32;
|
matchLength = ZSTD_count(ip+1+EQUAL_READ32, ip+1+EQUAL_READ32-rep[0], iend) + EQUAL_READ32;
|
||||||
if (depth==0) goto _storeSequence;
|
if (depth==0) goto _storeSequence;
|
||||||
@@ -1681,17 +1780,17 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|||||||
if (depth>=1)
|
if (depth>=1)
|
||||||
while (ip<ilimit) {
|
while (ip<ilimit) {
|
||||||
ip ++;
|
ip ++;
|
||||||
if ((offset) && (MEM_read32(ip) == MEM_read32(ip - rep[0]))) {
|
if ((offset) && ((rep[0]>0) & (MEM_read32(ip) == MEM_read32(ip - rep[0])))) {
|
||||||
size_t const mlRep = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-rep[0], iend) + EQUAL_READ32;
|
size_t const mlRep = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-rep[0], iend) + EQUAL_READ32;
|
||||||
int const gain2 = (int)(mlRep * 3);
|
int const gain2 = (int)(mlRep * 3);
|
||||||
int const gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1);
|
int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
|
||||||
if ((mlRep >= EQUAL_READ32) && (gain2 > gain1))
|
if ((mlRep >= EQUAL_READ32) && (gain2 > gain1))
|
||||||
matchLength = mlRep, offset = 0, start = ip;
|
matchLength = mlRep, offset = 0, start = ip;
|
||||||
}
|
}
|
||||||
{ size_t offset2=99999999;
|
{ size_t offset2=99999999;
|
||||||
size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
||||||
int const gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */
|
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
|
||||||
int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4);
|
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
|
||||||
if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
|
if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
|
||||||
matchLength = ml2, offset = offset2, start = ip;
|
matchLength = ml2, offset = offset2, start = ip;
|
||||||
continue; /* search a better one */
|
continue; /* search a better one */
|
||||||
@@ -1700,17 +1799,17 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|||||||
/* let's find an even better one */
|
/* let's find an even better one */
|
||||||
if ((depth==2) && (ip<ilimit)) {
|
if ((depth==2) && (ip<ilimit)) {
|
||||||
ip ++;
|
ip ++;
|
||||||
if ((offset) && (MEM_read32(ip) == MEM_read32(ip - rep[0]))) {
|
if ((offset) && ((rep[0]>0) & (MEM_read32(ip) == MEM_read32(ip - rep[0])))) {
|
||||||
size_t const ml2 = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-rep[0], iend) + EQUAL_READ32;
|
size_t const ml2 = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-rep[0], iend) + EQUAL_READ32;
|
||||||
int const gain2 = (int)(ml2 * 4);
|
int const gain2 = (int)(ml2 * 4);
|
||||||
int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1);
|
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
|
||||||
if ((ml2 >= EQUAL_READ32) && (gain2 > gain1))
|
if ((ml2 >= EQUAL_READ32) && (gain2 > gain1))
|
||||||
matchLength = ml2, offset = 0, start = ip;
|
matchLength = ml2, offset = 0, start = ip;
|
||||||
}
|
}
|
||||||
{ size_t offset2=99999999;
|
{ size_t offset2=99999999;
|
||||||
size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
||||||
int const gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */
|
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
|
||||||
int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7);
|
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
|
||||||
if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
|
if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
|
||||||
matchLength = ml2, offset = offset2, start = ip;
|
matchLength = ml2, offset = offset2, start = ip;
|
||||||
continue;
|
continue;
|
||||||
@@ -1734,7 +1833,8 @@ _storeSequence:
|
|||||||
|
|
||||||
/* check immediate repcode */
|
/* check immediate repcode */
|
||||||
while ( (ip <= ilimit)
|
while ( (ip <= ilimit)
|
||||||
&& (MEM_read32(ip) == MEM_read32(ip - rep[1])) ) {
|
&& ((rep[1]>0)
|
||||||
|
& (MEM_read32(ip) == MEM_read32(ip - rep[1])) )) {
|
||||||
/* store sequence */
|
/* store sequence */
|
||||||
matchLength = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-rep[1], iend) + EQUAL_READ32;
|
matchLength = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-rep[1], iend) + EQUAL_READ32;
|
||||||
offset = rep[1]; rep[1] = rep[0]; rep[0] = (U32)offset; /* swap repcodes */
|
offset = rep[1]; rep[1] = rep[0]; rep[0] = (U32)offset; /* swap repcodes */
|
||||||
@@ -1744,6 +1844,13 @@ _storeSequence:
|
|||||||
continue; /* faster when present ... (?) */
|
continue; /* faster when present ... (?) */
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
/* Save reps for next block */
|
||||||
|
{ int i;
|
||||||
|
for (i=0; i<ZSTD_REP_NUM; i++) {
|
||||||
|
if (!rep[i]) rep[i] = (U32)(iend - ctx->base); /* in case some zero are left */
|
||||||
|
ctx->savedRep[i] = rep[i];
|
||||||
|
} }
|
||||||
|
|
||||||
/* Last Literals */
|
/* Last Literals */
|
||||||
{ size_t const lastLLSize = iend - anchor;
|
{ size_t const lastLLSize = iend - anchor;
|
||||||
memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
||||||
@@ -1787,6 +1894,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
const BYTE* const ilimit = iend - 8;
|
const BYTE* const ilimit = iend - 8;
|
||||||
const BYTE* const base = ctx->base;
|
const BYTE* const base = ctx->base;
|
||||||
const U32 dictLimit = ctx->dictLimit;
|
const U32 dictLimit = ctx->dictLimit;
|
||||||
|
const U32 lowestIndex = ctx->lowLimit;
|
||||||
const BYTE* const prefixStart = base + dictLimit;
|
const BYTE* const prefixStart = base + dictLimit;
|
||||||
const BYTE* const dictBase = ctx->dictBase;
|
const BYTE* const dictBase = ctx->dictBase;
|
||||||
const BYTE* const dictEnd = dictBase + dictLimit;
|
const BYTE* const dictEnd = dictBase + dictLimit;
|
||||||
@@ -1802,11 +1910,11 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
U32 rep[ZSTD_REP_INIT];
|
U32 rep[ZSTD_REP_INIT];
|
||||||
{ U32 i; for (i=0; i<ZSTD_REP_INIT; i++) rep[i]=REPCODE_STARTVALUE; }
|
{ U32 i; for (i=0; i<ZSTD_REP_INIT; i++) rep[i]=ctx->rep[i]; }
|
||||||
|
|
||||||
ctx->nextToUpdate3 = ctx->nextToUpdate;
|
ctx->nextToUpdate3 = ctx->nextToUpdate;
|
||||||
ZSTD_resetSeqStore(seqStorePtr);
|
ZSTD_resetSeqStore(seqStorePtr);
|
||||||
if ((ip - prefixStart) < REPCODE_STARTVALUE) ip += REPCODE_STARTVALUE;
|
ip += (ip == prefixStart);
|
||||||
|
|
||||||
/* Match Loop */
|
/* Match Loop */
|
||||||
while (ip < ilimit) {
|
while (ip < ilimit) {
|
||||||
@@ -1816,11 +1924,10 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
U32 current = (U32)(ip-base);
|
U32 current = (U32)(ip-base);
|
||||||
|
|
||||||
/* check repCode */
|
/* check repCode */
|
||||||
{
|
{ const U32 repIndex = (U32)(current+1 - rep[0]);
|
||||||
const U32 repIndex = (U32)(current+1 - rep[0]);
|
|
||||||
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
||||||
const BYTE* const repMatch = repBase + repIndex;
|
const BYTE* const repMatch = repBase + repIndex;
|
||||||
if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */
|
if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
|
||||||
if (MEM_read32(ip+1) == MEM_read32(repMatch)) {
|
if (MEM_read32(ip+1) == MEM_read32(repMatch)) {
|
||||||
/* repcode detected we should take it */
|
/* repcode detected we should take it */
|
||||||
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
||||||
@@ -1850,13 +1957,13 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
const U32 repIndex = (U32)(current - rep[0]);
|
const U32 repIndex = (U32)(current - rep[0]);
|
||||||
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
||||||
const BYTE* const repMatch = repBase + repIndex;
|
const BYTE* const repMatch = repBase + repIndex;
|
||||||
if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */
|
if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
|
||||||
if (MEM_read32(ip) == MEM_read32(repMatch)) {
|
if (MEM_read32(ip) == MEM_read32(repMatch)) {
|
||||||
/* repcode detected */
|
/* repcode detected */
|
||||||
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
||||||
size_t const repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
|
size_t const repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
|
||||||
int const gain2 = (int)(repLength * 3);
|
int const gain2 = (int)(repLength * 3);
|
||||||
int const gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1);
|
int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
|
||||||
if ((repLength >= EQUAL_READ32) && (gain2 > gain1))
|
if ((repLength >= EQUAL_READ32) && (gain2 > gain1))
|
||||||
matchLength = repLength, offset = 0, start = ip;
|
matchLength = repLength, offset = 0, start = ip;
|
||||||
} }
|
} }
|
||||||
@@ -1864,8 +1971,8 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
/* search match, depth 1 */
|
/* search match, depth 1 */
|
||||||
{ size_t offset2=99999999;
|
{ size_t offset2=99999999;
|
||||||
size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
||||||
int const gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */
|
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
|
||||||
int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4);
|
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
|
||||||
if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
|
if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
|
||||||
matchLength = ml2, offset = offset2, start = ip;
|
matchLength = ml2, offset = offset2, start = ip;
|
||||||
continue; /* search a better one */
|
continue; /* search a better one */
|
||||||
@@ -1880,13 +1987,13 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
const U32 repIndex = (U32)(current - rep[0]);
|
const U32 repIndex = (U32)(current - rep[0]);
|
||||||
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
||||||
const BYTE* const repMatch = repBase + repIndex;
|
const BYTE* const repMatch = repBase + repIndex;
|
||||||
if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */
|
if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
|
||||||
if (MEM_read32(ip) == MEM_read32(repMatch)) {
|
if (MEM_read32(ip) == MEM_read32(repMatch)) {
|
||||||
/* repcode detected */
|
/* repcode detected */
|
||||||
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
||||||
size_t repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
|
size_t repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
|
||||||
int gain2 = (int)(repLength * 4);
|
int gain2 = (int)(repLength * 4);
|
||||||
int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1);
|
int gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
|
||||||
if ((repLength >= EQUAL_READ32) && (gain2 > gain1))
|
if ((repLength >= EQUAL_READ32) && (gain2 > gain1))
|
||||||
matchLength = repLength, offset = 0, start = ip;
|
matchLength = repLength, offset = 0, start = ip;
|
||||||
} }
|
} }
|
||||||
@@ -1894,8 +2001,8 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
/* search match, depth 2 */
|
/* search match, depth 2 */
|
||||||
{ size_t offset2=99999999;
|
{ size_t offset2=99999999;
|
||||||
size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
||||||
int const gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */
|
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
|
||||||
int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7);
|
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
|
||||||
if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
|
if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
|
||||||
matchLength = ml2, offset = offset2, start = ip;
|
matchLength = ml2, offset = offset2, start = ip;
|
||||||
continue;
|
continue;
|
||||||
@@ -1905,7 +2012,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
|
|
||||||
/* catch up */
|
/* catch up */
|
||||||
if (offset) {
|
if (offset) {
|
||||||
U32 matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));
|
U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));
|
||||||
const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex;
|
const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex;
|
||||||
const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart;
|
const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart;
|
||||||
while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */
|
while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */
|
||||||
@@ -1924,7 +2031,7 @@ _storeSequence:
|
|||||||
const U32 repIndex = (U32)((ip-base) - rep[1]);
|
const U32 repIndex = (U32)((ip-base) - rep[1]);
|
||||||
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
||||||
const BYTE* const repMatch = repBase + repIndex;
|
const BYTE* const repMatch = repBase + repIndex;
|
||||||
if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */
|
if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
|
||||||
if (MEM_read32(ip) == MEM_read32(repMatch)) {
|
if (MEM_read32(ip) == MEM_read32(repMatch)) {
|
||||||
/* repcode detected we should take it */
|
/* repcode detected we should take it */
|
||||||
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
||||||
@@ -1938,6 +2045,9 @@ _storeSequence:
|
|||||||
break;
|
break;
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
/* Save reps for next block */
|
||||||
|
ctx->savedRep[0] = rep[0]; ctx->savedRep[1] = rep[1]; ctx->savedRep[2] = rep[2];
|
||||||
|
|
||||||
/* Last Literals */
|
/* Last Literals */
|
||||||
{ size_t const lastLLSize = iend - anchor;
|
{ size_t const lastLLSize = iend - anchor;
|
||||||
memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
||||||
@@ -2010,35 +2120,37 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCa
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static size_t ZSTD_compress_generic (ZSTD_CCtx* zc,
|
static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t srcSize)
|
const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
size_t blockSize = zc->blockSize;
|
size_t blockSize = cctx->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;
|
||||||
BYTE* op = ostart;
|
BYTE* op = ostart;
|
||||||
const U32 maxDist = 1 << zc->params.cParams.windowLog;
|
const U32 maxDist = 1 << cctx->params.cParams.windowLog;
|
||||||
ZSTD_stats_t* stats = &zc->seqStore.stats;
|
ZSTD_stats_t* stats = &cctx->seqStore.stats;
|
||||||
|
|
||||||
ZSTD_statsInit(stats);
|
ZSTD_statsInit(stats);
|
||||||
|
|
||||||
|
if (cctx->params.fParams.checksumFlag)
|
||||||
|
XXH64_update(&cctx->xxhState, src, srcSize);
|
||||||
|
|
||||||
while (remaining) {
|
while (remaining) {
|
||||||
size_t cSize;
|
size_t cSize;
|
||||||
ZSTD_statsResetFreqs(stats);
|
ZSTD_statsResetFreqs(stats); /* debug only */
|
||||||
|
|
||||||
if (dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE) return ERROR(dstSize_tooSmall); /* not enough space to store compressed block */
|
if (dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE) return ERROR(dstSize_tooSmall); /* not enough space to store compressed block */
|
||||||
if (remaining < blockSize) blockSize = remaining;
|
if (remaining < blockSize) blockSize = remaining;
|
||||||
|
|
||||||
if ((U32)(ip+blockSize - zc->base) > zc->loadedDictEnd + maxDist) {
|
if ((U32)(ip+blockSize - cctx->base) > cctx->loadedDictEnd + maxDist) {
|
||||||
/* enforce maxDist */
|
/* enforce maxDist */
|
||||||
U32 const newLowLimit = (U32)(ip+blockSize - zc->base) - maxDist;
|
U32 const newLowLimit = (U32)(ip+blockSize - cctx->base) - maxDist;
|
||||||
if (zc->lowLimit < newLowLimit) zc->lowLimit = newLowLimit;
|
if (cctx->lowLimit < newLowLimit) cctx->lowLimit = newLowLimit;
|
||||||
if (zc->dictLimit < zc->lowLimit) zc->dictLimit = zc->lowLimit;
|
if (cctx->dictLimit < cctx->lowLimit) cctx->dictLimit = cctx->lowLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
cSize = ZSTD_compressBlock_internal(zc, op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize, ip, blockSize);
|
cSize = ZSTD_compressBlock_internal(cctx, op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize, ip, blockSize);
|
||||||
if (ZSTD_isError(cSize)) return cSize;
|
if (ZSTD_isError(cSize)) return cSize;
|
||||||
|
|
||||||
if (cSize == 0) { /* block is not compressible */
|
if (cSize == 0) { /* block is not compressible */
|
||||||
@@ -2058,33 +2170,47 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* zc,
|
|||||||
op += cSize;
|
op += cSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZSTD_statsPrint(stats, zc->params.cParams.searchLength);
|
ZSTD_statsPrint(stats, cctx->params.cParams.searchLength);
|
||||||
return op-ostart;
|
return op-ostart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
|
static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
|
||||||
ZSTD_parameters params, U64 pledgedSrcSize)
|
ZSTD_parameters params, U64 pledgedSrcSize, U32 dictID)
|
||||||
{ BYTE* const op = (BYTE*)dst;
|
{ BYTE* const op = (BYTE*)dst;
|
||||||
U32 const fcsId = params.fParams.contentSizeFlag ?
|
U32 const dictIDSizeCode = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */
|
||||||
(pledgedSrcSize>0) + (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) : /* 0-3 */
|
U32 const checksumFlag = params.fParams.checksumFlag>0;
|
||||||
|
U32 const windowSize = 1U << params.cParams.windowLog;
|
||||||
|
U32 const directModeFlag = params.fParams.contentSizeFlag && (windowSize > (pledgedSrcSize-1));
|
||||||
|
BYTE const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
|
||||||
|
U32 const fcsCode = params.fParams.contentSizeFlag ?
|
||||||
|
(pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : /* 0-3 */
|
||||||
0;
|
0;
|
||||||
BYTE const fdescriptor = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) /* windowLog : 4 KB - 128 MB */
|
BYTE const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (directModeFlag<<5) + (fcsCode<<6) );
|
||||||
| (fcsId << 6) );
|
size_t pos;
|
||||||
size_t const hSize = ZSTD_frameHeaderSize_min + ZSTD_fcs_fieldSize[fcsId];
|
|
||||||
if (hSize > dstCapacity) return ERROR(dstSize_tooSmall);
|
if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall);
|
||||||
|
|
||||||
MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
|
MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
|
||||||
op[4] = fdescriptor;
|
op[4] = frameHeaderDecriptionByte; pos=5;
|
||||||
switch(fcsId)
|
if (!directModeFlag) op[pos++] = windowLogByte;
|
||||||
|
switch(dictIDSizeCode)
|
||||||
{
|
{
|
||||||
default: /* impossible */
|
default: /* impossible */
|
||||||
case 0 : break;
|
case 0 : break;
|
||||||
case 1 : op[5] = (BYTE)(pledgedSrcSize); break;
|
case 1 : op[pos] = (BYTE)(dictID); pos++; break;
|
||||||
case 2 : MEM_writeLE16(op+5, (U16)(pledgedSrcSize-256)); break;
|
case 2 : MEM_writeLE16(op+pos, (U16)(dictID)); pos+=2; break;
|
||||||
case 3 : MEM_writeLE64(op+5, (U64)(pledgedSrcSize)); break;
|
case 3 : MEM_writeLE32(op+pos, dictID); pos+=4; break;
|
||||||
}
|
}
|
||||||
return hSize;
|
switch(fcsCode)
|
||||||
|
{
|
||||||
|
default: /* impossible */
|
||||||
|
case 0 : if (directModeFlag) op[pos++] = (BYTE)(pledgedSrcSize); break;
|
||||||
|
case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;
|
||||||
|
case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;
|
||||||
|
case 3 : MEM_writeLE64(op+pos, (U64)(pledgedSrcSize)); pos+=8; break;
|
||||||
|
}
|
||||||
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2098,7 +2224,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* zc,
|
|||||||
|
|
||||||
if (zc->stage==0) return ERROR(stage_wrong);
|
if (zc->stage==0) return ERROR(stage_wrong);
|
||||||
if (frame && (zc->stage==1)) { /* copy saved header */
|
if (frame && (zc->stage==1)) { /* copy saved header */
|
||||||
fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, zc->params, srcSize);
|
fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, zc->params, zc->frameContentSize, zc->dictID);
|
||||||
if (ZSTD_isError(fhSize)) return fhSize;
|
if (ZSTD_isError(fhSize)) return fhSize;
|
||||||
dstCapacity -= fhSize;
|
dstCapacity -= fhSize;
|
||||||
dst = (char*)dst + fhSize;
|
dst = (char*)dst + fhSize;
|
||||||
@@ -2209,60 +2335,74 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
|
|||||||
/* Dictionary format :
|
/* Dictionary format :
|
||||||
Magic == ZSTD_DICT_MAGIC (4 bytes)
|
Magic == ZSTD_DICT_MAGIC (4 bytes)
|
||||||
HUF_writeCTable(256)
|
HUF_writeCTable(256)
|
||||||
|
FSE_writeNCount(ml)
|
||||||
|
FSE_writeNCount(off)
|
||||||
|
FSE_writeNCount(ll)
|
||||||
|
RepOffsets
|
||||||
Dictionary content
|
Dictionary content
|
||||||
*/
|
*/
|
||||||
/*! ZSTD_loadDictEntropyStats() :
|
/*! ZSTD_loadDictEntropyStats() :
|
||||||
@return : size read from dictionary */
|
@return : size read from dictionary
|
||||||
static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* zc, const void* dict, size_t dictSize)
|
note : magic number supposed already checked */
|
||||||
|
static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
|
||||||
{
|
{
|
||||||
/* note : magic number already checked */
|
const BYTE* dictPtr = (const BYTE*)dict;
|
||||||
size_t offcodeHeaderSize, matchlengthHeaderSize, litlengthHeaderSize, errorCode;
|
const BYTE* const dictEnd = dictPtr + dictSize;
|
||||||
short offcodeNCount[MaxOff+1];
|
|
||||||
unsigned offcodeMaxValue = MaxOff, offcodeLog = OffFSELog;
|
|
||||||
short matchlengthNCount[MaxML+1];
|
|
||||||
unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
|
|
||||||
short litlengthNCount[MaxLL+1];
|
|
||||||
unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
|
|
||||||
|
|
||||||
size_t const hufHeaderSize = HUF_readCTable(zc->hufTable, 255, dict, dictSize);
|
{ size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dict, dictSize);
|
||||||
if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
|
if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
zc->flagStaticTables = 1;
|
dictPtr += hufHeaderSize;
|
||||||
dict = (const char*)dict + hufHeaderSize;
|
}
|
||||||
dictSize -= hufHeaderSize;
|
|
||||||
|
|
||||||
offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
|
{ short offcodeNCount[MaxOff+1];
|
||||||
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
unsigned offcodeMaxValue = MaxOff, offcodeLog = OffFSELog;
|
||||||
errorCode = FSE_buildCTable(zc->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog);
|
size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
|
||||||
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
|
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
dict = (const char*)dict + offcodeHeaderSize;
|
{ size_t const errorCode = FSE_buildCTable(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog);
|
||||||
dictSize -= offcodeHeaderSize;
|
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
|
dictPtr += offcodeHeaderSize;
|
||||||
|
}
|
||||||
|
|
||||||
matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
|
{ short matchlengthNCount[MaxML+1];
|
||||||
if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
|
||||||
errorCode = FSE_buildCTable(zc->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
|
size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
|
||||||
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
|
if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
dict = (const char*)dict + matchlengthHeaderSize;
|
{ size_t const errorCode = FSE_buildCTable(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
|
||||||
dictSize -= matchlengthHeaderSize;
|
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
|
dictPtr += matchlengthHeaderSize;
|
||||||
|
}
|
||||||
|
|
||||||
litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
|
{ short litlengthNCount[MaxLL+1];
|
||||||
if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
|
||||||
errorCode = FSE_buildCTable(zc->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog);
|
size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
|
||||||
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
|
if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
{ size_t const errorCode = FSE_buildCTable(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog);
|
||||||
|
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
|
dictPtr += litlengthHeaderSize;
|
||||||
|
}
|
||||||
|
|
||||||
return hufHeaderSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
|
if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
|
||||||
|
cctx->rep[0] = MEM_readLE32(dictPtr+0); if (cctx->rep[0] >= dictSize) return ERROR(dictionary_corrupted);
|
||||||
|
cctx->rep[1] = MEM_readLE32(dictPtr+4); if (cctx->rep[1] >= dictSize) return ERROR(dictionary_corrupted);
|
||||||
|
cctx->rep[2] = MEM_readLE32(dictPtr+8); if (cctx->rep[2] >= dictSize) return ERROR(dictionary_corrupted);
|
||||||
|
dictPtr += 12;
|
||||||
|
|
||||||
|
cctx->flagStaticTables = 1;
|
||||||
|
return dictPtr - (const BYTE*)dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** ZSTD_compress_insertDictionary() :
|
/** ZSTD_compress_insertDictionary() :
|
||||||
* @return : 0, or an error code */
|
* @return : 0, or an error code */
|
||||||
static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* dict, size_t dictSize)
|
static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* dict, size_t dictSize)
|
||||||
{
|
{
|
||||||
if ((dict==NULL) || (dictSize<=4)) return 0;
|
if ((dict==NULL) || (dictSize<=8)) return 0;
|
||||||
|
|
||||||
/* default : dict is pure content */
|
/* default : dict is pure content */
|
||||||
if (MEM_readLE32(dict) != ZSTD_DICT_MAGIC) return ZSTD_loadDictionaryContent(zc, dict, dictSize);
|
if (MEM_readLE32(dict) != ZSTD_DICT_MAGIC) return ZSTD_loadDictionaryContent(zc, dict, dictSize);
|
||||||
|
zc->dictID = zc->params.fParams.noDictIDFlag ? 0 : MEM_readLE32((const char*)dict+4);
|
||||||
|
|
||||||
/* known magic number : dict is parsed for entropy stats and content */
|
/* known magic number : dict is parsed for entropy stats and content */
|
||||||
{ size_t const eSize = ZSTD_loadDictEntropyStats(zc, (const char*)dict+4 /* skip magic */, dictSize-4) + 4;
|
{ size_t const eSize = ZSTD_loadDictEntropyStats(zc, (const char*)dict+8 /* skip dictHeader */, dictSize-8) + 8;
|
||||||
if (ZSTD_isError(eSize)) return eSize;
|
if (ZSTD_isError(eSize)) return eSize;
|
||||||
return ZSTD_loadDictionaryContent(zc, (const char*)dict+eSize, dictSize-eSize);
|
return ZSTD_loadDictionaryContent(zc, (const char*)dict+eSize, dictSize-eSize);
|
||||||
}
|
}
|
||||||
@@ -2275,11 +2415,8 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* zc,
|
|||||||
const void* dict, size_t dictSize,
|
const void* dict, size_t dictSize,
|
||||||
ZSTD_parameters params, U64 pledgedSrcSize)
|
ZSTD_parameters params, U64 pledgedSrcSize)
|
||||||
{
|
{
|
||||||
{ U32 const hashLog3 = (pledgedSrcSize || pledgedSrcSize >= 8192) ? ZSTD_HASHLOG3_MAX : ((pledgedSrcSize >= 2048) ? ZSTD_HASHLOG3_MIN + 1 : ZSTD_HASHLOG3_MIN);
|
size_t const resetError = ZSTD_resetCCtx_advanced(zc, params, pledgedSrcSize, 1);
|
||||||
zc->hashLog3 = (params.cParams.searchLength==3) ? hashLog3 : 0; }
|
if (ZSTD_isError(resetError)) return resetError;
|
||||||
|
|
||||||
{ size_t const resetError = ZSTD_resetCCtx_advanced(zc, params, 1);
|
|
||||||
if (ZSTD_isError(resetError)) return resetError; }
|
|
||||||
|
|
||||||
return ZSTD_compress_insertDictionary(zc, dict, dictSize);
|
return ZSTD_compress_insertDictionary(zc, dict, dictSize);
|
||||||
}
|
}
|
||||||
@@ -2287,7 +2424,7 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* zc,
|
|||||||
|
|
||||||
/*! ZSTD_compressBegin_advanced() :
|
/*! ZSTD_compressBegin_advanced() :
|
||||||
* @return : 0, or an error code */
|
* @return : 0, or an error code */
|
||||||
size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* zc,
|
size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
|
||||||
const void* dict, size_t dictSize,
|
const void* dict, size_t dictSize,
|
||||||
ZSTD_parameters params, U64 pledgedSrcSize)
|
ZSTD_parameters params, U64 pledgedSrcSize)
|
||||||
{
|
{
|
||||||
@@ -2295,18 +2432,17 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* zc,
|
|||||||
{ size_t const errorCode = ZSTD_checkCParams_advanced(params.cParams, pledgedSrcSize);
|
{ size_t const errorCode = ZSTD_checkCParams_advanced(params.cParams, pledgedSrcSize);
|
||||||
if (ZSTD_isError(errorCode)) return errorCode; }
|
if (ZSTD_isError(errorCode)) return errorCode; }
|
||||||
|
|
||||||
return ZSTD_compressBegin_internal(zc, dict, dictSize, params, pledgedSrcSize);
|
return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, pledgedSrcSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* zc, const void* dict, size_t dictSize, int compressionLevel)
|
size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
|
||||||
{
|
{
|
||||||
ZSTD_parameters params;
|
ZSTD_parameters params;
|
||||||
|
memset(¶ms, 0, sizeof(params));
|
||||||
params.cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
|
params.cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
|
||||||
params.fParams.contentSizeFlag = 0;
|
ZSTD_LOG_BLOCK("%p: ZSTD_compressBegin_usingDict compressionLevel=%d\n", cctx->base, compressionLevel);
|
||||||
ZSTD_adjustCParams(¶ms.cParams, 0, dictSize);
|
return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, 0);
|
||||||
ZSTD_LOG_BLOCK("%p: ZSTD_compressBegin_usingDict compressionLevel=%d\n", zc->base, compressionLevel);
|
|
||||||
return ZSTD_compressBegin_internal(zc, dict, dictSize, params, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2320,35 +2456,44 @@ size_t ZSTD_compressBegin(ZSTD_CCtx* zc, int compressionLevel)
|
|||||||
/*! 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* zc, void* dst, size_t dstCapacity)
|
size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
|
||||||
{
|
{
|
||||||
BYTE* op = (BYTE*)dst;
|
BYTE* op = (BYTE*)dst;
|
||||||
size_t fhSize = 0;
|
size_t fhSize = 0;
|
||||||
|
|
||||||
/* not even init ! */
|
/* not even init ! */
|
||||||
if (zc->stage==0) return ERROR(stage_wrong);
|
if (cctx->stage==0) return ERROR(stage_wrong);
|
||||||
|
|
||||||
/* special case : empty frame */
|
/* special case : empty frame */
|
||||||
if (zc->stage==1) {
|
if (cctx->stage==1) {
|
||||||
fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, zc->params, 0);
|
fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->params, 0, 0);
|
||||||
if (ZSTD_isError(fhSize)) return fhSize;
|
if (ZSTD_isError(fhSize)) return fhSize;
|
||||||
dstCapacity -= fhSize;
|
dstCapacity -= fhSize;
|
||||||
op += fhSize;
|
op += fhSize;
|
||||||
zc->stage = 2;
|
cctx->stage = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* frame epilogue */
|
/* frame epilogue */
|
||||||
if (dstCapacity < 3) return ERROR(dstSize_tooSmall);
|
if (dstCapacity < 3) return ERROR(dstSize_tooSmall);
|
||||||
op[0] = (BYTE)(bt_end << 6);
|
{ U32 const checksum = cctx->params.fParams.checksumFlag ?
|
||||||
op[1] = 0;
|
(U32)((XXH64_digest(&cctx->xxhState) >> 11) & ((1<<22)-1)) :
|
||||||
op[2] = 0;
|
0;
|
||||||
|
op[0] = (BYTE)((bt_end<<6) + (checksum>>16));
|
||||||
|
op[1] = (BYTE)(checksum>>8);
|
||||||
|
op[2] = (BYTE)checksum;
|
||||||
|
}
|
||||||
|
|
||||||
zc->stage = 0; /* return to "created by not init" status */
|
cctx->stage = 0; /* return to "created but not init" status */
|
||||||
return 3+fhSize;
|
return 3+fhSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_compress_usingPreparedCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx,
|
/*! ZSTD_compress_usingPreparedCCtx() :
|
||||||
|
* Same as ZSTD_compress_usingDict, but using a reference context `preparedCCtx`, where dictionary has been loaded.
|
||||||
|
* It avoids reloading the dictionary each time.
|
||||||
|
* `preparedCCtx` must have been properly initialized using ZSTD_compressBegin_usingDict() or ZSTD_compressBegin_advanced().
|
||||||
|
* Requires 2 contexts : 1 for reference (preparedCCtx) which will not be modified, and 1 to run the compression operation (cctx) */
|
||||||
|
static size_t ZSTD_compress_usingPreparedCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx,
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t srcSize)
|
const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
@@ -2406,10 +2551,10 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
|||||||
size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, const void* dict, size_t dictSize, int compressionLevel)
|
size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, const void* dict, size_t dictSize, int compressionLevel)
|
||||||
{
|
{
|
||||||
ZSTD_parameters params;
|
ZSTD_parameters params;
|
||||||
|
memset(¶ms, 0, sizeof(params));
|
||||||
ZSTD_LOG_BLOCK("%p: ZSTD_compress_usingDict srcSize=%d dictSize=%d compressionLevel=%d\n", ctx->base, (int)srcSize, (int)dictSize, compressionLevel);
|
ZSTD_LOG_BLOCK("%p: ZSTD_compress_usingDict srcSize=%d dictSize=%d compressionLevel=%d\n", ctx->base, (int)srcSize, (int)dictSize, compressionLevel);
|
||||||
params.cParams = ZSTD_getCParams(compressionLevel, srcSize, dictSize);
|
params.cParams = ZSTD_getCParams(compressionLevel, srcSize, dictSize);
|
||||||
params.fParams.contentSizeFlag = 1;
|
params.fParams.contentSizeFlag = 1;
|
||||||
ZSTD_adjustCParams(¶ms.cParams, srcSize, dictSize);
|
|
||||||
return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
|
return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2424,15 +2569,91 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS
|
|||||||
size_t result;
|
size_t result;
|
||||||
ZSTD_CCtx ctxBody;
|
ZSTD_CCtx ctxBody;
|
||||||
memset(&ctxBody, 0, sizeof(ctxBody));
|
memset(&ctxBody, 0, sizeof(ctxBody));
|
||||||
|
memcpy(&ctxBody.customMem, &defaultCustomMem, sizeof(ZSTD_customMem));
|
||||||
result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel);
|
result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel);
|
||||||
free(ctxBody.workSpace); /* can't free ctxBody, since it's on stack; just free heap content */
|
ctxBody.customMem.customFree(ctxBody.customMem.opaque, ctxBody.workSpace); /* can't free ctxBody, since it's on stack; just free heap content */
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ===== Dictionary API ===== */
|
||||||
|
|
||||||
|
struct ZSTD_CDict_s {
|
||||||
|
void* dictContent;
|
||||||
|
size_t dictContentSize;
|
||||||
|
ZSTD_CCtx* refContext;
|
||||||
|
}; /* typedef'd tp ZSTD_CDict within zstd.h */
|
||||||
|
|
||||||
|
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, ZSTD_parameters params, ZSTD_customMem customMem)
|
||||||
|
{
|
||||||
|
if (!customMem.customAlloc && !customMem.customFree)
|
||||||
|
customMem = defaultCustomMem;
|
||||||
|
|
||||||
|
if (!customMem.customAlloc || !customMem.customFree)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
{ ZSTD_CDict* const cdict = (ZSTD_CDict*) customMem.customAlloc(customMem.opaque, sizeof(*cdict));
|
||||||
|
void* const dictContent = customMem.customAlloc(customMem.opaque, dictSize);
|
||||||
|
ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
|
||||||
|
|
||||||
|
if (!dictContent || !cdict || !cctx) {
|
||||||
|
customMem.customFree(customMem.opaque, dictContent);
|
||||||
|
customMem.customFree(customMem.opaque, cdict);
|
||||||
|
customMem.customFree(customMem.opaque, cctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(dictContent, dict, dictSize);
|
||||||
|
{ size_t const errorCode = ZSTD_compressBegin_advanced(cctx, dictContent, dictSize, params, 0);
|
||||||
|
if (ZSTD_isError(errorCode)) {
|
||||||
|
customMem.customFree(customMem.opaque, dictContent);
|
||||||
|
customMem.customFree(customMem.opaque, cdict);
|
||||||
|
customMem.customFree(customMem.opaque, cctx);
|
||||||
|
return NULL;
|
||||||
|
} }
|
||||||
|
|
||||||
|
cdict->dictContent = dictContent;
|
||||||
|
cdict->dictContentSize = dictSize;
|
||||||
|
cdict->refContext = cctx;
|
||||||
|
return cdict;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)
|
||||||
|
{
|
||||||
|
ZSTD_customMem const allocator = { NULL, NULL, NULL };
|
||||||
|
ZSTD_parameters params;
|
||||||
|
memset(¶ms, 0, sizeof(params));
|
||||||
|
params.cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
|
||||||
|
params.fParams.contentSizeFlag = 1;
|
||||||
|
return ZSTD_createCDict_advanced(dict, dictSize, params, allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
|
||||||
|
{
|
||||||
|
ZSTD_freeFunction const cFree = cdict->refContext->customMem.customFree;
|
||||||
|
void* const opaque = cdict->refContext->customMem.opaque;
|
||||||
|
ZSTD_freeCCtx(cdict->refContext);
|
||||||
|
cFree(opaque, cdict->dictContent);
|
||||||
|
cFree(opaque, cdict);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t srcSize,
|
||||||
|
const ZSTD_CDict* cdict)
|
||||||
|
{
|
||||||
|
return ZSTD_compress_usingPreparedCCtx(cctx, cdict->refContext,
|
||||||
|
dst, dstCapacity,
|
||||||
|
src, srcSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-===== Pre-defined compression levels =====-*/
|
/*-===== Pre-defined compression levels =====-*/
|
||||||
|
|
||||||
#define ZSTD_DEFAULT_CLEVEL 5
|
#define ZSTD_DEFAULT_CLEVEL 1
|
||||||
#define ZSTD_MAX_CLEVEL 22
|
#define ZSTD_MAX_CLEVEL 22
|
||||||
unsigned ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
|
unsigned ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
|
||||||
|
|
||||||
@@ -2543,17 +2764,16 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! ZSTD_getParams() :
|
/*! ZSTD_getCParams() :
|
||||||
* @return ZSTD_parameters structure for a selected compression level and srcSize.
|
* @return ZSTD_compressionParameters structure for a selected compression level, `srcSize` and `dictSize`.
|
||||||
* `srcSize` value is optional, select 0 if not known */
|
* Size values are optional, provide 0 if not known or unused */
|
||||||
ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, U64 srcSize, size_t dictSize)
|
ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, U64 srcSize, size_t dictSize)
|
||||||
{
|
{
|
||||||
ZSTD_compressionParameters cp;
|
ZSTD_compressionParameters cp;
|
||||||
size_t const addedSize = srcSize ? 0 : 500;
|
size_t const addedSize = srcSize ? 0 : 500;
|
||||||
U64 const rSize = srcSize+dictSize ? srcSize+dictSize+addedSize : (U64)-1;
|
U64 const rSize = srcSize+dictSize ? srcSize+dictSize+addedSize : (U64)-1;
|
||||||
U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB); /* intentional underflow for srcSizeHint == 0 */
|
U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB); /* intentional underflow for srcSizeHint == 0 */
|
||||||
if (compressionLevel < 0) compressionLevel = ZSTD_DEFAULT_CLEVEL;
|
if (compressionLevel <= 0) compressionLevel = ZSTD_DEFAULT_CLEVEL; /* 0 == default; no negative compressionLevel yet */
|
||||||
if (compressionLevel==0) compressionLevel = 1;
|
|
||||||
if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
|
if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
|
||||||
cp = ZSTD_defaultCParameters[tableID][compressionLevel];
|
cp = ZSTD_defaultCParameters[tableID][compressionLevel];
|
||||||
if (MEM_32bits()) { /* auto-correction, for 32-bits mode */
|
if (MEM_32bits()) { /* auto-correction, for 32-bits mode */
|
||||||
@@ -2561,5 +2781,6 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, U64 srcSize, si
|
|||||||
if (cp.chainLog > ZSTD_CHAINLOG_MAX) cp.chainLog = ZSTD_CHAINLOG_MAX;
|
if (cp.chainLog > ZSTD_CHAINLOG_MAX) cp.chainLog = ZSTD_CHAINLOG_MAX;
|
||||||
if (cp.hashLog > ZSTD_HASHLOG_MAX) cp.hashLog = ZSTD_HASHLOG_MAX;
|
if (cp.hashLog > ZSTD_HASHLOG_MAX) cp.hashLog = ZSTD_HASHLOG_MAX;
|
||||||
}
|
}
|
||||||
|
cp = ZSTD_adjustCParams(cp, srcSize, dictSize);
|
||||||
return cp;
|
return cp;
|
||||||
}
|
}
|
||||||
|
|||||||
+144
-133
@@ -41,10 +41,10 @@
|
|||||||
***************************************/
|
***************************************/
|
||||||
FORCE_INLINE void ZSTD_setLog2Prices(seqStore_t* ssPtr)
|
FORCE_INLINE void ZSTD_setLog2Prices(seqStore_t* ssPtr)
|
||||||
{
|
{
|
||||||
ssPtr->log2matchLengthSum = ZSTD_highbit(ssPtr->matchLengthSum+1);
|
ssPtr->log2matchLengthSum = ZSTD_highbit32(ssPtr->matchLengthSum+1);
|
||||||
ssPtr->log2litLengthSum = ZSTD_highbit(ssPtr->litLengthSum+1);
|
ssPtr->log2litLengthSum = ZSTD_highbit32(ssPtr->litLengthSum+1);
|
||||||
ssPtr->log2litSum = ZSTD_highbit(ssPtr->litSum+1);
|
ssPtr->log2litSum = ZSTD_highbit32(ssPtr->litSum+1);
|
||||||
ssPtr->log2offCodeSum = ZSTD_highbit(ssPtr->offCodeSum+1);
|
ssPtr->log2offCodeSum = ZSTD_highbit32(ssPtr->offCodeSum+1);
|
||||||
ssPtr->factor = 1 + ((ssPtr->litSum>>5) / ssPtr->litLengthSum) + ((ssPtr->litSum<<1) / (ssPtr->litSum + ssPtr->matchSum));
|
ssPtr->factor = 1 + ((ssPtr->litSum>>5) / ssPtr->litLengthSum) + ((ssPtr->litSum<<1) / (ssPtr->litSum + ssPtr->matchSum));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ FORCE_INLINE U32 ZSTD_getLiteralPrice(seqStore_t* ssPtr, U32 litLength, const BY
|
|||||||
U32 price, u;
|
U32 price, u;
|
||||||
|
|
||||||
if (litLength == 0)
|
if (litLength == 0)
|
||||||
return ssPtr->log2litLengthSum - ZSTD_highbit(ssPtr->litLengthFreq[0]+1);
|
return ssPtr->log2litLengthSum - ZSTD_highbit32(ssPtr->litLengthFreq[0]+1);
|
||||||
|
|
||||||
/* literals */
|
/* literals */
|
||||||
if (ssPtr->cachedLiterals == literals) {
|
if (ssPtr->cachedLiterals == literals) {
|
||||||
@@ -114,13 +114,13 @@ FORCE_INLINE U32 ZSTD_getLiteralPrice(seqStore_t* ssPtr, U32 litLength, const BY
|
|||||||
const BYTE* literals2 = ssPtr->cachedLiterals + ssPtr->cachedLitLength;
|
const BYTE* literals2 = ssPtr->cachedLiterals + ssPtr->cachedLitLength;
|
||||||
price = ssPtr->cachedPrice + additional * ssPtr->log2litSum;
|
price = ssPtr->cachedPrice + additional * ssPtr->log2litSum;
|
||||||
for (u=0; u < additional; u++)
|
for (u=0; u < additional; u++)
|
||||||
price -= ZSTD_highbit(ssPtr->litFreq[literals2[u]]+1);
|
price -= ZSTD_highbit32(ssPtr->litFreq[literals2[u]]+1);
|
||||||
ssPtr->cachedPrice = price;
|
ssPtr->cachedPrice = price;
|
||||||
ssPtr->cachedLitLength = litLength;
|
ssPtr->cachedLitLength = litLength;
|
||||||
} else {
|
} else {
|
||||||
price = litLength * ssPtr->log2litSum;
|
price = litLength * ssPtr->log2litSum;
|
||||||
for (u=0; u < litLength; u++)
|
for (u=0; u < litLength; u++)
|
||||||
price -= ZSTD_highbit(ssPtr->litFreq[literals[u]]+1);
|
price -= ZSTD_highbit32(ssPtr->litFreq[literals[u]]+1);
|
||||||
|
|
||||||
if (litLength >= 12) {
|
if (litLength >= 12) {
|
||||||
ssPtr->cachedLiterals = literals;
|
ssPtr->cachedLiterals = literals;
|
||||||
@@ -139,8 +139,8 @@ FORCE_INLINE U32 ZSTD_getLiteralPrice(seqStore_t* ssPtr, U32 litLength, const BY
|
|||||||
24, 24, 24, 24, 24, 24, 24, 24,
|
24, 24, 24, 24, 24, 24, 24, 24,
|
||||||
24, 24, 24, 24, 24, 24, 24, 24 };
|
24, 24, 24, 24, 24, 24, 24, 24 };
|
||||||
const BYTE LL_deltaCode = 19;
|
const BYTE LL_deltaCode = 19;
|
||||||
const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit(litLength) + LL_deltaCode : LL_Code[litLength];
|
const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
|
||||||
price += LL_bits[llCode] + ssPtr->log2litLengthSum - ZSTD_highbit(ssPtr->litLengthFreq[llCode]+1);
|
price += LL_bits[llCode] + ssPtr->log2litLengthSum - ZSTD_highbit32(ssPtr->litLengthFreq[llCode]+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return price;
|
return price;
|
||||||
@@ -150,8 +150,8 @@ FORCE_INLINE U32 ZSTD_getLiteralPrice(seqStore_t* ssPtr, U32 litLength, const BY
|
|||||||
FORCE_INLINE U32 ZSTD_getPrice(seqStore_t* seqStorePtr, U32 litLength, const BYTE* literals, U32 offset, U32 matchLength)
|
FORCE_INLINE U32 ZSTD_getPrice(seqStore_t* seqStorePtr, U32 litLength, const BYTE* literals, U32 offset, U32 matchLength)
|
||||||
{
|
{
|
||||||
/* offset */
|
/* offset */
|
||||||
BYTE offCode = (BYTE)ZSTD_highbit(offset+1);
|
BYTE offCode = (BYTE)ZSTD_highbit32(offset+1);
|
||||||
U32 price = offCode + seqStorePtr->log2offCodeSum - ZSTD_highbit(seqStorePtr->offCodeFreq[offCode]+1);
|
U32 price = offCode + seqStorePtr->log2offCodeSum - ZSTD_highbit32(seqStorePtr->offCodeFreq[offCode]+1);
|
||||||
|
|
||||||
/* match Length */
|
/* match Length */
|
||||||
{ static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
{ static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||||
@@ -163,8 +163,8 @@ FORCE_INLINE U32 ZSTD_getPrice(seqStore_t* seqStorePtr, U32 litLength, const BYT
|
|||||||
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
|
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
|
||||||
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
|
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
|
||||||
const BYTE ML_deltaCode = 36;
|
const BYTE ML_deltaCode = 36;
|
||||||
const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit(matchLength) + ML_deltaCode : ML_Code[matchLength];
|
const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
|
||||||
price += ML_bits[mlCode] + seqStorePtr->log2matchLengthSum - ZSTD_highbit(seqStorePtr->matchLengthFreq[mlCode]+1);
|
price += ML_bits[mlCode] + seqStorePtr->log2matchLengthSum - ZSTD_highbit32(seqStorePtr->matchLengthFreq[mlCode]+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return price + ZSTD_getLiteralPrice(seqStorePtr, litLength, literals) + seqStorePtr->factor;
|
return price + ZSTD_getLiteralPrice(seqStorePtr, litLength, literals) + seqStorePtr->factor;
|
||||||
@@ -190,13 +190,13 @@ MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const B
|
|||||||
24, 24, 24, 24, 24, 24, 24, 24,
|
24, 24, 24, 24, 24, 24, 24, 24,
|
||||||
24, 24, 24, 24, 24, 24, 24, 24 };
|
24, 24, 24, 24, 24, 24, 24, 24 };
|
||||||
const BYTE LL_deltaCode = 19;
|
const BYTE LL_deltaCode = 19;
|
||||||
const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit(litLength) + LL_deltaCode : LL_Code[litLength];
|
const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
|
||||||
seqStorePtr->litLengthFreq[llCode]++;
|
seqStorePtr->litLengthFreq[llCode]++;
|
||||||
seqStorePtr->litLengthSum++;
|
seqStorePtr->litLengthSum++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* match offset */
|
/* match offset */
|
||||||
{ BYTE offCode = (BYTE)ZSTD_highbit(offset+1);
|
{ BYTE offCode = (BYTE)ZSTD_highbit32(offset+1);
|
||||||
seqStorePtr->offCodeSum++;
|
seqStorePtr->offCodeSum++;
|
||||||
seqStorePtr->offCodeFreq[offCode]++;
|
seqStorePtr->offCodeFreq[offCode]++;
|
||||||
}
|
}
|
||||||
@@ -211,7 +211,7 @@ MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const B
|
|||||||
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
|
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
|
||||||
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
|
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
|
||||||
const BYTE ML_deltaCode = 36;
|
const BYTE ML_deltaCode = 36;
|
||||||
const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit(matchLength) + ML_deltaCode : ML_Code[matchLength];
|
const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
|
||||||
seqStorePtr->matchLengthFreq[mlCode]++;
|
seqStorePtr->matchLengthFreq[mlCode]++;
|
||||||
seqStorePtr->matchLengthSum++;
|
seqStorePtr->matchLengthSum++;
|
||||||
}
|
}
|
||||||
@@ -461,15 +461,14 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
ZSTD_optimal_t* opt = seqStorePtr->priceTable;
|
ZSTD_optimal_t* opt = seqStorePtr->priceTable;
|
||||||
ZSTD_match_t* matches = seqStorePtr->matchTable;
|
ZSTD_match_t* matches = seqStorePtr->matchTable;
|
||||||
const BYTE* inr;
|
const BYTE* inr;
|
||||||
|
U32 offset, rep[ZSTD_REP_INIT];
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
U32 offset, rep[ZSTD_REP_INIT];
|
|
||||||
{ U32 i; for (i=0; i<ZSTD_REP_INIT; i++) rep[i]=REPCODE_STARTVALUE; }
|
|
||||||
|
|
||||||
ctx->nextToUpdate3 = ctx->nextToUpdate;
|
ctx->nextToUpdate3 = ctx->nextToUpdate;
|
||||||
ZSTD_resetSeqStore(seqStorePtr);
|
ZSTD_resetSeqStore(seqStorePtr);
|
||||||
ZSTD_rescaleFreqs(seqStorePtr);
|
ZSTD_rescaleFreqs(seqStorePtr);
|
||||||
if ((ip-prefixStart) < REPCODE_STARTVALUE) ip = prefixStart + REPCODE_STARTVALUE;
|
ip += (ip==prefixStart);
|
||||||
|
{ U32 i; for (i=0; i<ZSTD_REP_INIT; i++) rep[i]=ctx->rep[i]; }
|
||||||
|
|
||||||
ZSTD_LOG_BLOCK("%d: COMPBLOCK_OPT_GENERIC srcSz=%d maxSrch=%d mls=%d sufLen=%d\n", (int)(ip-base), (int)srcSize, maxSearches, mls, sufficient_len);
|
ZSTD_LOG_BLOCK("%d: COMPBLOCK_OPT_GENERIC srcSz=%d maxSrch=%d mls=%d sufLen=%d\n", (int)(ip-base), (int)srcSize, maxSearches, mls, sufficient_len);
|
||||||
|
|
||||||
@@ -482,23 +481,24 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
litlen = (U32)(ip - anchor);
|
litlen = (U32)(ip - anchor);
|
||||||
|
|
||||||
/* check repCode */
|
/* check repCode */
|
||||||
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++)
|
{ U32 i;
|
||||||
if (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(ip - rep[i], minMatch)) {
|
for (i=0; i<ZSTD_REP_NUM; i++) {
|
||||||
/* repcode : we take it */
|
if ((rep[i]<(U32)(ip-prefixStart))
|
||||||
mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-rep[i], iend) + minMatch;
|
&& (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(ip - rep[i], minMatch))) {
|
||||||
ZSTD_LOG_PARSER("%d: start try REP rep[%d]=%d mlen=%d\n", (int)(ip-base), i, (int)rep[i], (int)mlen);
|
mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-rep[i], iend) + minMatch;
|
||||||
if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {
|
ZSTD_LOG_PARSER("%d: start try REP rep[%d]=%d mlen=%d\n", (int)(ip-base), i, (int)rep[i], (int)mlen);
|
||||||
best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
|
if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {
|
||||||
goto _storeSequence;
|
best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
|
||||||
}
|
goto _storeSequence;
|
||||||
best_off = (i<=1 && ip == anchor) ? 1-i : i;
|
}
|
||||||
do {
|
best_off = (i<=1 && ip == anchor) ? 1-i : i;
|
||||||
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH);
|
do {
|
||||||
if (mlen > last_pos || price < opt[mlen].price)
|
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH);
|
||||||
SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */
|
if (mlen > last_pos || price < opt[mlen].price)
|
||||||
mlen--;
|
SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */
|
||||||
} while (mlen >= minMatch);
|
mlen--;
|
||||||
} }
|
} while (mlen >= minMatch);
|
||||||
|
} } }
|
||||||
|
|
||||||
match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, ip, iend, maxSearches, mls, matches, minMatch);
|
match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, ip, iend, maxSearches, mls, matches, minMatch);
|
||||||
|
|
||||||
@@ -516,15 +516,15 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
/* set prices using matches at position = 0 */
|
/* set prices using matches at position = 0 */
|
||||||
best_mlen = (last_pos) ? last_pos : minMatch;
|
best_mlen = (last_pos) ? last_pos : minMatch;
|
||||||
for (u = 0; u < match_num; u++) {
|
for (u = 0; u < match_num; u++) {
|
||||||
mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
|
mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
|
||||||
best_mlen = matches[u].len;
|
best_mlen = matches[u].len;
|
||||||
ZSTD_LOG_PARSER("%d: start Found mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(ip-base), matches[u].len, matches[u].off, (int)best_mlen, (int)last_pos);
|
ZSTD_LOG_PARSER("%d: start Found mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(ip-base), matches[u].len, matches[u].off, (int)best_mlen, (int)last_pos);
|
||||||
while (mlen <= best_mlen) {
|
while (mlen <= best_mlen) {
|
||||||
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off, mlen - MINMATCH);
|
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off, mlen - MINMATCH);
|
||||||
if (mlen > last_pos || price < opt[mlen].price)
|
if (mlen > last_pos || price < opt[mlen].price)
|
||||||
SET_PRICE(mlen, mlen, matches[u].off, litlen, price); /* note : macro modifies last_pos */
|
SET_PRICE(mlen, mlen, matches[u].off, litlen, price); /* note : macro modifies last_pos */
|
||||||
mlen++;
|
mlen++;
|
||||||
} }
|
} }
|
||||||
|
|
||||||
if (last_pos < minMatch) { ip++; continue; }
|
if (last_pos < minMatch) { ip++; continue; }
|
||||||
|
|
||||||
@@ -572,38 +572,40 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
ZSTD_LOG_PARSER("%d: CURRENT_NoExt price[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]);
|
ZSTD_LOG_PARSER("%d: CURRENT_NoExt price[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]);
|
||||||
|
|
||||||
best_mlen = minMatch;
|
best_mlen = minMatch;
|
||||||
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++)
|
{ U32 i;
|
||||||
if (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(inr - opt[cur].rep[i], minMatch)) { /* check rep */
|
for (i=0; i<ZSTD_REP_NUM; i++) {
|
||||||
mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - opt[cur].rep[i], iend) + minMatch;
|
if ((opt[cur].rep[i]<(U32)(inr-prefixStart))
|
||||||
ZSTD_LOG_PARSER("%d: Found REP %d/%d mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), i, ZSTD_REP_NUM, mlen, i, opt[cur].rep[i], cur, opt[cur].off);
|
&& (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(inr - opt[cur].rep[i], minMatch))) { /* check rep */
|
||||||
|
mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - opt[cur].rep[i], iend) + minMatch;
|
||||||
|
ZSTD_LOG_PARSER("%d: Found REP %d/%d mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), i, ZSTD_REP_NUM, mlen, i, opt[cur].rep[i], cur, opt[cur].off);
|
||||||
|
|
||||||
if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
|
if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
|
||||||
ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos);
|
ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos);
|
||||||
best_mlen = mlen; best_off = i; last_pos = cur + 1;
|
best_mlen = mlen; best_off = i; last_pos = cur + 1;
|
||||||
goto _storeSequence;
|
goto _storeSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
best_off = (i<=1 && opt[cur].mlen != 1) ? 1-i : i;
|
best_off = (i<=1 && opt[cur].mlen != 1) ? 1-i : i;
|
||||||
if (opt[cur].mlen == 1) {
|
if (opt[cur].mlen == 1) {
|
||||||
litlen = opt[cur].litlen;
|
litlen = opt[cur].litlen;
|
||||||
if (cur > litlen) {
|
if (cur > litlen) {
|
||||||
price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - MINMATCH);
|
price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - MINMATCH);
|
||||||
} else
|
} else
|
||||||
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH);
|
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH);
|
||||||
} else {
|
} else {
|
||||||
litlen = 0;
|
litlen = 0;
|
||||||
price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - MINMATCH);
|
price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - MINMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mlen > best_mlen) best_mlen = mlen;
|
if (mlen > best_mlen) best_mlen = mlen;
|
||||||
ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_off, price, litlen);
|
ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_off, price, litlen);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
|
if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
|
||||||
SET_PRICE(cur + mlen, mlen, i, litlen, price);
|
SET_PRICE(cur + mlen, mlen, i, litlen, price);
|
||||||
mlen--;
|
mlen--;
|
||||||
} while (mlen >= minMatch);
|
} while (mlen >= minMatch);
|
||||||
} }
|
} } }
|
||||||
|
|
||||||
match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, inr, iend, maxSearches, mls, matches, best_mlen);
|
match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, inr, iend, maxSearches, mls, matches, best_mlen);
|
||||||
ZSTD_LOG_PARSER("%d: ZSTD_GetAllMatches match_num=%d\n", (int)(inr-base), match_num);
|
ZSTD_LOG_PARSER("%d: ZSTD_GetAllMatches match_num=%d\n", (int)(inr-base), match_num);
|
||||||
@@ -712,8 +714,11 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
|
|||||||
anchor = ip = ip + mlen;
|
anchor = ip = ip + mlen;
|
||||||
} } /* for (cur=0; cur < last_pos; ) */
|
} } /* for (cur=0; cur < last_pos; ) */
|
||||||
|
|
||||||
{ /* Last Literals */
|
/* Save reps for next block */
|
||||||
size_t lastLLSize = iend - anchor;
|
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) ctx->savedRep[i] = rep[i]; }
|
||||||
|
|
||||||
|
/* Last Literals */
|
||||||
|
{ size_t const lastLLSize = iend - anchor;
|
||||||
ZSTD_LOG_ENCODE("%d: lastLLSize literals=%u\n", (int)(ip-base), (U32)lastLLSize);
|
ZSTD_LOG_ENCODE("%d: lastLLSize literals=%u\n", (int)(ip-base), (U32)lastLLSize);
|
||||||
memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
||||||
seqStorePtr->lit += lastLLSize;
|
seqStorePtr->lit += lastLLSize;
|
||||||
@@ -732,6 +737,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
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;
|
const BYTE* const base = ctx->base;
|
||||||
|
const U32 lowestIndex = ctx->lowLimit;
|
||||||
const U32 dictLimit = ctx->dictLimit;
|
const U32 dictLimit = ctx->dictLimit;
|
||||||
const BYTE* const prefixStart = base + dictLimit;
|
const BYTE* const prefixStart = base + dictLimit;
|
||||||
const BYTE* const dictBase = ctx->dictBase;
|
const BYTE* const dictBase = ctx->dictBase;
|
||||||
@@ -748,12 +754,12 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
U32 offset, rep[ZSTD_REP_INIT];
|
U32 offset, rep[ZSTD_REP_INIT];
|
||||||
{ U32 i; for (i=0; i<ZSTD_REP_INIT; i++) rep[i]=REPCODE_STARTVALUE; }
|
{ U32 i; for (i=0; i<ZSTD_REP_INIT; i++) rep[i]=ctx->rep[i]; }
|
||||||
|
|
||||||
ctx->nextToUpdate3 = ctx->nextToUpdate;
|
ctx->nextToUpdate3 = ctx->nextToUpdate;
|
||||||
ZSTD_resetSeqStore(seqStorePtr);
|
ZSTD_resetSeqStore(seqStorePtr);
|
||||||
ZSTD_rescaleFreqs(seqStorePtr);
|
ZSTD_rescaleFreqs(seqStorePtr);
|
||||||
if ((ip - prefixStart) < REPCODE_STARTVALUE) ip += REPCODE_STARTVALUE;
|
ip += (ip==prefixStart);
|
||||||
|
|
||||||
ZSTD_LOG_BLOCK("%d: COMPBLOCK_OPT_EXTDICT srcSz=%d maxSrch=%d mls=%d sufLen=%d\n", (int)(ip-base), (int)srcSize, maxSearches, mls, sufficient_len);
|
ZSTD_LOG_BLOCK("%d: COMPBLOCK_OPT_EXTDICT srcSz=%d maxSrch=%d mls=%d sufLen=%d\n", (int)(ip-base), (int)srcSize, maxSearches, mls, sufficient_len);
|
||||||
|
|
||||||
@@ -768,31 +774,32 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
opt[0].litlen = (U32)(ip - anchor);
|
opt[0].litlen = (U32)(ip - anchor);
|
||||||
|
|
||||||
/* check repCode */
|
/* check repCode */
|
||||||
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) {
|
{ U32 i;
|
||||||
const U32 repIndex = (U32)(current - rep[i]);
|
for (i=0; i<ZSTD_REP_NUM; i++) {
|
||||||
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
const U32 repIndex = (U32)(current - rep[i]);
|
||||||
const BYTE* const repMatch = repBase + repIndex;
|
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
||||||
if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */
|
const BYTE* const repMatch = repBase + repIndex;
|
||||||
&& (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
|
if ( (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex)) /* intentional overflow */
|
||||||
/* repcode detected we should take it */
|
&& (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
|
||||||
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
/* repcode detected we should take it */
|
||||||
mlen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
||||||
|
mlen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
|
||||||
|
|
||||||
ZSTD_LOG_PARSER("%d: start try REP rep[%d]=%d mlen=%d\n", (int)(ip-base), i, (int)rep[i], (int)mlen);
|
ZSTD_LOG_PARSER("%d: start try REP rep[%d]=%d mlen=%d\n", (int)(ip-base), i, (int)rep[i], (int)mlen);
|
||||||
if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {
|
if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {
|
||||||
best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
|
best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
|
||||||
goto _storeSequence;
|
goto _storeSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
best_off = (i<=1 && ip == anchor) ? 1-i : i;
|
best_off = (i<=1 && ip == anchor) ? 1-i : i;
|
||||||
litlen = opt[0].litlen;
|
litlen = opt[0].litlen;
|
||||||
do {
|
do {
|
||||||
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH);
|
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH);
|
||||||
if (mlen > last_pos || price < opt[mlen].price)
|
if (mlen > last_pos || price < opt[mlen].price)
|
||||||
SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */
|
SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */
|
||||||
mlen--;
|
mlen--;
|
||||||
} while (mlen >= minMatch);
|
} while (mlen >= minMatch);
|
||||||
} } }
|
} } }
|
||||||
|
|
||||||
match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, ip, iend, maxSearches, mls, matches, minMatch); /* first search (depth 0) */
|
match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, ip, iend, maxSearches, mls, matches, minMatch); /* first search (depth 0) */
|
||||||
|
|
||||||
@@ -869,44 +876,45 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
ZSTD_LOG_PARSER("%d: CURRENT_Ext price[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]);
|
ZSTD_LOG_PARSER("%d: CURRENT_Ext price[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]);
|
||||||
best_mlen = 0;
|
best_mlen = 0;
|
||||||
|
|
||||||
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) {
|
{ U32 i;
|
||||||
const U32 repIndex = (U32)(current+cur - opt[cur].rep[i]);
|
for (i=0; i<ZSTD_REP_NUM; i++) {
|
||||||
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
const U32 repIndex = (U32)(current+cur - opt[cur].rep[i]);
|
||||||
const BYTE* const repMatch = repBase + repIndex;
|
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
||||||
if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */
|
const BYTE* const repMatch = repBase + repIndex;
|
||||||
&& (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
|
if ( (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex)) /* intentional overflow */
|
||||||
/* repcode detected */
|
&& (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
|
||||||
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
/* repcode detected */
|
||||||
mlen = (U32)ZSTD_count_2segments(inr+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
||||||
ZSTD_LOG_PARSER("%d: Found REP %d/%d mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), i, ZSTD_REP_NUM, mlen, i, opt[cur].rep[i], cur, opt[cur].off);
|
mlen = (U32)ZSTD_count_2segments(inr+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
|
||||||
|
ZSTD_LOG_PARSER("%d: Found REP %d/%d mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), i, ZSTD_REP_NUM, mlen, i, opt[cur].rep[i], cur, opt[cur].off);
|
||||||
|
|
||||||
if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
|
if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
|
||||||
ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos);
|
ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos);
|
||||||
best_mlen = mlen; best_off = i; last_pos = cur + 1;
|
best_mlen = mlen; best_off = i; last_pos = cur + 1;
|
||||||
goto _storeSequence;
|
goto _storeSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
best_off = (i<=1 && opt[cur].mlen != 1) ? 1-i : i;
|
best_off = (i<=1 && opt[cur].mlen != 1) ? 1-i : i;
|
||||||
if (opt[cur].mlen == 1) {
|
if (opt[cur].mlen == 1) {
|
||||||
litlen = opt[cur].litlen;
|
litlen = opt[cur].litlen;
|
||||||
if (cur > litlen) {
|
if (cur > litlen) {
|
||||||
price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - MINMATCH);
|
price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - MINMATCH);
|
||||||
} else
|
} else
|
||||||
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH);
|
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH);
|
||||||
} else {
|
} else {
|
||||||
litlen = 0;
|
litlen = 0;
|
||||||
price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - MINMATCH);
|
price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - MINMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
best_mlen = mlen;
|
best_mlen = mlen;
|
||||||
ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_off, price, litlen);
|
ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_off, price, litlen);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
|
if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
|
||||||
SET_PRICE(cur + mlen, mlen, i, litlen, price);
|
SET_PRICE(cur + mlen, mlen, i, litlen, price);
|
||||||
mlen--;
|
mlen--;
|
||||||
} while (mlen >= minMatch);
|
} while (mlen >= minMatch);
|
||||||
} } }
|
} } }
|
||||||
|
|
||||||
match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, inr, iend, maxSearches, mls, matches, minMatch);
|
match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, inr, iend, maxSearches, mls, matches, minMatch);
|
||||||
ZSTD_LOG_PARSER("%d: ZSTD_GetAllMatches match_num=%d\n", (int)(inr-base), match_num);
|
ZSTD_LOG_PARSER("%d: ZSTD_GetAllMatches match_num=%d\n", (int)(inr-base), match_num);
|
||||||
@@ -1023,8 +1031,11 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
|
|||||||
anchor = ip = ip + mlen;
|
anchor = ip = ip + mlen;
|
||||||
} } /* for (cur=0; cur < last_pos; ) */
|
} } /* for (cur=0; cur < last_pos; ) */
|
||||||
|
|
||||||
{ /* Last Literals */
|
/* Save reps for next block */
|
||||||
size_t lastLLSize = iend - anchor;
|
ctx->savedRep[0] = rep[0]; ctx->savedRep[1] = rep[1]; ctx->savedRep[2] = rep[2];
|
||||||
|
|
||||||
|
/* Last Literals */
|
||||||
|
{ size_t lastLLSize = iend - anchor;
|
||||||
ZSTD_LOG_ENCODE("%d: lastLLSize literals=%u\n", (int)(ip-base), (U32)(lastLLSize));
|
ZSTD_LOG_ENCODE("%d: lastLLSize literals=%u\n", (int)(ip-base), (U32)(lastLLSize));
|
||||||
memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
||||||
seqStorePtr->lit += lastLLSize;
|
seqStorePtr->lit += lastLLSize;
|
||||||
|
|||||||
+309
-556
@@ -59,13 +59,11 @@
|
|||||||
/* **************************************************************
|
/* **************************************************************
|
||||||
* Includes
|
* Includes
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
#include <stdlib.h> /* malloc, free, qsort */
|
|
||||||
#include <string.h> /* memcpy, memset */
|
#include <string.h> /* memcpy, memset */
|
||||||
#include <stdio.h> /* printf (debug) */
|
|
||||||
#include "huf_static.h"
|
|
||||||
#include "bitstream.h"
|
#include "bitstream.h"
|
||||||
#include "fse.h" /* header compression */
|
#include "fse.h" /* header compression */
|
||||||
|
#define HUF_STATIC_LINKING_ONLY
|
||||||
|
#include "huf.h"
|
||||||
|
|
||||||
|
|
||||||
/* **************************************************************
|
/* **************************************************************
|
||||||
@@ -74,63 +72,70 @@
|
|||||||
#define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
|
#define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
|
||||||
|
|
||||||
|
|
||||||
|
/*-***************************/
|
||||||
|
/* generic DTableDesc */
|
||||||
|
/*-***************************/
|
||||||
|
|
||||||
/* *******************************************************
|
typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; } DTableDesc;
|
||||||
* HUF : Huffman block decompression
|
|
||||||
*********************************************************/
|
|
||||||
typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX2; /* single-symbol decoding */
|
|
||||||
|
|
||||||
typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX4; /* double-symbols decoding */
|
|
||||||
|
|
||||||
typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t;
|
|
||||||
|
|
||||||
|
static DTableDesc HUF_getDTableDesc(const HUF_DTable* table)
|
||||||
|
{
|
||||||
|
DTableDesc dtd;
|
||||||
|
memcpy(&dtd, table, sizeof(dtd));
|
||||||
|
return dtd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-***************************/
|
/*-***************************/
|
||||||
/* single-symbol decoding */
|
/* single-symbol decoding */
|
||||||
/*-***************************/
|
/*-***************************/
|
||||||
|
|
||||||
size_t HUF_readDTableX2 (U16* DTable, const void* src, size_t srcSize)
|
typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX2; /* single-symbol decoding */
|
||||||
|
|
||||||
|
size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
BYTE huffWeight[HUF_MAX_SYMBOL_VALUE + 1];
|
BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];
|
||||||
U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1]; /* large enough for values from 0 to 16 */
|
U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */
|
||||||
U32 tableLog = 0;
|
U32 tableLog = 0;
|
||||||
size_t iSize;
|
|
||||||
U32 nbSymbols = 0;
|
U32 nbSymbols = 0;
|
||||||
U32 n;
|
size_t iSize;
|
||||||
U32 nextRankStart;
|
|
||||||
void* const dtPtr = DTable + 1;
|
void* const dtPtr = DTable + 1;
|
||||||
HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
|
HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
|
||||||
|
|
||||||
HUF_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(U16)); /* if compilation fails here, assertion is false */
|
HUF_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable));
|
||||||
//memset(huffWeight, 0, sizeof(huffWeight)); /* is not necessary, even though some analyzer complain ... */
|
//memset(huffWeight, 0, sizeof(huffWeight)); /* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
iSize = HUF_readStats(huffWeight, HUF_MAX_SYMBOL_VALUE + 1, rankVal, &nbSymbols, &tableLog, src, srcSize);
|
iSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize);
|
||||||
if (HUF_isError(iSize)) return iSize;
|
if (HUF_isError(iSize)) return iSize;
|
||||||
|
|
||||||
/* check result */
|
/* Table header */
|
||||||
if (tableLog > DTable[0]) return ERROR(tableLog_tooLarge); /* DTable is too small */
|
{ DTableDesc dtd = HUF_getDTableDesc(DTable);
|
||||||
DTable[0] = (U16)tableLog; /* maybe should separate sizeof allocated DTable, from used size of DTable, in case of re-use */
|
if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge); /* DTable too small, huffman tree cannot fit in */
|
||||||
|
dtd.tableType = 0;
|
||||||
|
dtd.tableLog = (BYTE)tableLog;
|
||||||
|
memcpy(DTable, &dtd, sizeof(dtd));
|
||||||
|
}
|
||||||
|
|
||||||
/* Prepare ranks */
|
/* Prepare ranks */
|
||||||
nextRankStart = 0;
|
{ U32 n, nextRankStart = 0;
|
||||||
for (n=1; n<tableLog+1; n++) {
|
for (n=1; n<tableLog+1; n++) {
|
||||||
U32 current = nextRankStart;
|
U32 current = nextRankStart;
|
||||||
nextRankStart += (rankVal[n] << (n-1));
|
nextRankStart += (rankVal[n] << (n-1));
|
||||||
rankVal[n] = current;
|
rankVal[n] = current;
|
||||||
}
|
} }
|
||||||
|
|
||||||
/* fill DTable */
|
/* fill DTable */
|
||||||
for (n=0; n<nbSymbols; n++) {
|
{ U32 n;
|
||||||
const U32 w = huffWeight[n];
|
for (n=0; n<nbSymbols; n++) {
|
||||||
const U32 length = (1 << w) >> 1;
|
U32 const w = huffWeight[n];
|
||||||
U32 i;
|
U32 const length = (1 << w) >> 1;
|
||||||
HUF_DEltX2 D;
|
U32 i;
|
||||||
D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w);
|
HUF_DEltX2 D;
|
||||||
for (i = rankVal[w]; i < rankVal[w] + length; i++)
|
D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w);
|
||||||
dt[i] = D;
|
for (i = rankVal[w]; i < rankVal[w] + length; i++)
|
||||||
rankVal[w] += length;
|
dt[i] = D;
|
||||||
}
|
rankVal[w] += length;
|
||||||
|
} }
|
||||||
|
|
||||||
return iSize;
|
return iSize;
|
||||||
}
|
}
|
||||||
@@ -138,8 +143,8 @@ size_t HUF_readDTableX2 (U16* DTable, const void* src, size_t srcSize)
|
|||||||
|
|
||||||
static BYTE HUF_decodeSymbolX2(BIT_DStream_t* Dstream, const HUF_DEltX2* dt, const U32 dtLog)
|
static BYTE HUF_decodeSymbolX2(BIT_DStream_t* Dstream, const HUF_DEltX2* dt, const U32 dtLog)
|
||||||
{
|
{
|
||||||
const size_t val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */
|
size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */
|
||||||
const BYTE c = dt[val].byte;
|
BYTE const c = dt[val].byte;
|
||||||
BIT_skipBits(Dstream, dt[val].nbBits);
|
BIT_skipBits(Dstream, dt[val].nbBits);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -148,7 +153,7 @@ static BYTE HUF_decodeSymbolX2(BIT_DStream_t* Dstream, const HUF_DEltX2* dt, con
|
|||||||
*ptr++ = HUF_decodeSymbolX2(DStreamPtr, dt, dtLog)
|
*ptr++ = HUF_decodeSymbolX2(DStreamPtr, dt, dtLog)
|
||||||
|
|
||||||
#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \
|
#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \
|
||||||
if (MEM_64bits() || (HUF_MAX_TABLELOG<=12)) \
|
if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
|
||||||
HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
|
HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
|
||||||
|
|
||||||
#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \
|
#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \
|
||||||
@@ -178,17 +183,18 @@ static inline size_t HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* const bitDPtr, B
|
|||||||
return pEnd-pStart;
|
return pEnd-pStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t HUF_decompress1X2_usingDTable(
|
static size_t HUF_decompress1X2_usingDTable_internal(
|
||||||
void* dst, size_t dstSize,
|
void* dst, size_t dstSize,
|
||||||
const void* cSrc, size_t cSrcSize,
|
const void* cSrc, size_t cSrcSize,
|
||||||
const U16* DTable)
|
const HUF_DTable* DTable)
|
||||||
{
|
{
|
||||||
BYTE* op = (BYTE*)dst;
|
BYTE* op = (BYTE*)dst;
|
||||||
BYTE* const oend = op + dstSize;
|
BYTE* const oend = op + dstSize;
|
||||||
const U32 dtLog = DTable[0];
|
const void* dtPtr = DTable + 1;
|
||||||
const void* dtPtr = DTable;
|
const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
|
||||||
const HUF_DEltX2* const dt = ((const HUF_DEltX2*)dtPtr)+1;
|
|
||||||
BIT_DStream_t bitD;
|
BIT_DStream_t bitD;
|
||||||
|
DTableDesc const dtd = HUF_getDTableDesc(DTable);
|
||||||
|
U32 const dtLog = dtd.tableLog;
|
||||||
|
|
||||||
{ size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
|
{ size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
|
||||||
if (HUF_isError(errorCode)) return errorCode; }
|
if (HUF_isError(errorCode)) return errorCode; }
|
||||||
@@ -201,25 +207,39 @@ size_t HUF_decompress1X2_usingDTable(
|
|||||||
return dstSize;
|
return dstSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
size_t HUF_decompress1X2_usingDTable(
|
||||||
|
void* dst, size_t dstSize,
|
||||||
|
const void* cSrc, size_t cSrcSize,
|
||||||
|
const HUF_DTable* DTable)
|
||||||
|
{
|
||||||
|
DTableDesc dtd = HUF_getDTableDesc(DTable);
|
||||||
|
if (dtd.tableType != 0) return ERROR(GENERIC);
|
||||||
|
return HUF_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HUF_decompress1X2_DCtx (HUF_DTable* DCtx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
{
|
{
|
||||||
HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_MAX_TABLELOG);
|
|
||||||
const BYTE* ip = (const BYTE*) cSrc;
|
const BYTE* ip = (const BYTE*) cSrc;
|
||||||
|
|
||||||
size_t const errorCode = HUF_readDTableX2 (DTable, cSrc, cSrcSize);
|
size_t const hSize = HUF_readDTableX2 (DCtx, cSrc, cSrcSize);
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (HUF_isError(hSize)) return hSize;
|
||||||
if (errorCode >= cSrcSize) return ERROR(srcSize_wrong);
|
if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
|
||||||
ip += errorCode;
|
ip += hSize; cSrcSize -= hSize;
|
||||||
cSrcSize -= errorCode;
|
|
||||||
|
|
||||||
return HUF_decompress1X2_usingDTable (dst, dstSize, ip, cSrcSize, DTable);
|
return HUF_decompress1X2_usingDTable_internal (dst, dstSize, ip, cSrcSize, DCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
|
{
|
||||||
|
HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
|
||||||
|
return HUF_decompress1X2_DCtx (DTable, dst, dstSize, cSrc, cSrcSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t HUF_decompress4X2_usingDTable(
|
static size_t HUF_decompress4X2_usingDTable_internal(
|
||||||
void* dst, size_t dstSize,
|
void* dst, size_t dstSize,
|
||||||
const void* cSrc, size_t cSrcSize,
|
const void* cSrc, size_t cSrcSize,
|
||||||
const U16* DTable)
|
const HUF_DTable* DTable)
|
||||||
{
|
{
|
||||||
/* Check */
|
/* Check */
|
||||||
if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
|
if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
|
||||||
@@ -227,20 +247,18 @@ size_t HUF_decompress4X2_usingDTable(
|
|||||||
{ const BYTE* const istart = (const BYTE*) cSrc;
|
{ const BYTE* const istart = (const BYTE*) cSrc;
|
||||||
BYTE* const ostart = (BYTE*) dst;
|
BYTE* const ostart = (BYTE*) dst;
|
||||||
BYTE* const oend = ostart + dstSize;
|
BYTE* const oend = ostart + dstSize;
|
||||||
const void* const dtPtr = DTable;
|
const void* const dtPtr = DTable + 1;
|
||||||
const HUF_DEltX2* const dt = ((const HUF_DEltX2*)dtPtr) +1;
|
const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
|
||||||
const U32 dtLog = DTable[0];
|
|
||||||
size_t errorCode;
|
|
||||||
|
|
||||||
/* Init */
|
/* Init */
|
||||||
BIT_DStream_t bitD1;
|
BIT_DStream_t bitD1;
|
||||||
BIT_DStream_t bitD2;
|
BIT_DStream_t bitD2;
|
||||||
BIT_DStream_t bitD3;
|
BIT_DStream_t bitD3;
|
||||||
BIT_DStream_t bitD4;
|
BIT_DStream_t bitD4;
|
||||||
const size_t length1 = MEM_readLE16(istart);
|
size_t const length1 = MEM_readLE16(istart);
|
||||||
const size_t length2 = MEM_readLE16(istart+2);
|
size_t const length2 = MEM_readLE16(istart+2);
|
||||||
const size_t length3 = MEM_readLE16(istart+4);
|
size_t const length3 = MEM_readLE16(istart+4);
|
||||||
size_t length4;
|
size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
|
||||||
const BYTE* const istart1 = istart + 6; /* jumpTable */
|
const BYTE* const istart1 = istart + 6; /* jumpTable */
|
||||||
const BYTE* const istart2 = istart1 + length1;
|
const BYTE* const istart2 = istart1 + length1;
|
||||||
const BYTE* const istart3 = istart2 + length2;
|
const BYTE* const istart3 = istart2 + length2;
|
||||||
@@ -254,17 +272,18 @@ size_t HUF_decompress4X2_usingDTable(
|
|||||||
BYTE* op3 = opStart3;
|
BYTE* op3 = opStart3;
|
||||||
BYTE* op4 = opStart4;
|
BYTE* op4 = opStart4;
|
||||||
U32 endSignal;
|
U32 endSignal;
|
||||||
|
DTableDesc const dtd = HUF_getDTableDesc(DTable);
|
||||||
|
U32 const dtLog = dtd.tableLog;
|
||||||
|
|
||||||
length4 = cSrcSize - (length1 + length2 + length3 + 6);
|
|
||||||
if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
|
if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
|
||||||
errorCode = BIT_initDStream(&bitD1, istart1, length1);
|
{ size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (HUF_isError(errorCode)) return errorCode; }
|
||||||
errorCode = BIT_initDStream(&bitD2, istart2, length2);
|
{ size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (HUF_isError(errorCode)) return errorCode; }
|
||||||
errorCode = BIT_initDStream(&bitD3, istart3, length3);
|
{ size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (HUF_isError(errorCode)) return errorCode; }
|
||||||
errorCode = BIT_initDStream(&bitD4, istart4, length4);
|
{ size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (HUF_isError(errorCode)) return errorCode; }
|
||||||
|
|
||||||
/* 16-32 symbols per loop (4-8 symbols per stream) */
|
/* 16-32 symbols per loop (4-8 symbols per stream) */
|
||||||
endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
|
endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
|
||||||
@@ -310,24 +329,42 @@ size_t HUF_decompress4X2_usingDTable(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
size_t HUF_decompress4X2_usingDTable(
|
||||||
|
void* dst, size_t dstSize,
|
||||||
|
const void* cSrc, size_t cSrcSize,
|
||||||
|
const HUF_DTable* DTable)
|
||||||
|
{
|
||||||
|
DTableDesc dtd = HUF_getDTableDesc(DTable);
|
||||||
|
if (dtd.tableType != 0) return ERROR(GENERIC);
|
||||||
|
return HUF_decompress4X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t HUF_decompress4X2_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
{
|
{
|
||||||
HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_MAX_TABLELOG);
|
|
||||||
const BYTE* ip = (const BYTE*) cSrc;
|
const BYTE* ip = (const BYTE*) cSrc;
|
||||||
|
|
||||||
size_t const errorCode = HUF_readDTableX2 (DTable, cSrc, cSrcSize);
|
size_t const hSize = HUF_readDTableX2 (dctx, cSrc, cSrcSize);
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (HUF_isError(hSize)) return hSize;
|
||||||
if (errorCode >= cSrcSize) return ERROR(srcSize_wrong);
|
if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
|
||||||
ip += errorCode;
|
ip += hSize; cSrcSize -= hSize;
|
||||||
cSrcSize -= errorCode;
|
|
||||||
|
|
||||||
return HUF_decompress4X2_usingDTable (dst, dstSize, ip, cSrcSize, DTable);
|
return HUF_decompress4X2_usingDTable_internal (dst, dstSize, ip, cSrcSize, dctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
|
{
|
||||||
|
HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
|
||||||
|
return HUF_decompress4X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *************************/
|
/* *************************/
|
||||||
/* double-symbols decoding */
|
/* double-symbols decoding */
|
||||||
/* *************************/
|
/* *************************/
|
||||||
|
typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX4; /* double-symbols decoding */
|
||||||
|
|
||||||
|
typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t;
|
||||||
|
|
||||||
static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 consumed,
|
static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 consumed,
|
||||||
const U32* rankValOrigin, const int minWeight,
|
const U32* rankValOrigin, const int minWeight,
|
||||||
@@ -335,7 +372,7 @@ static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 co
|
|||||||
U32 nbBitsBaseline, U16 baseSeq)
|
U32 nbBitsBaseline, U16 baseSeq)
|
||||||
{
|
{
|
||||||
HUF_DEltX4 DElt;
|
HUF_DEltX4 DElt;
|
||||||
U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1];
|
U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1];
|
||||||
|
|
||||||
/* get pre-calculated rankVal */
|
/* get pre-calculated rankVal */
|
||||||
memcpy(rankVal, rankValOrigin, sizeof(rankVal));
|
memcpy(rankVal, rankValOrigin, sizeof(rankVal));
|
||||||
@@ -369,14 +406,14 @@ static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 co
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef U32 rankVal_t[HUF_ABSOLUTEMAX_TABLELOG][HUF_ABSOLUTEMAX_TABLELOG + 1];
|
typedef U32 rankVal_t[HUF_TABLELOG_ABSOLUTEMAX][HUF_TABLELOG_ABSOLUTEMAX + 1];
|
||||||
|
|
||||||
static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog,
|
static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog,
|
||||||
const sortedSymbol_t* sortedList, const U32 sortedListSize,
|
const sortedSymbol_t* sortedList, const U32 sortedListSize,
|
||||||
const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
|
const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
|
||||||
const U32 nbBitsBaseline)
|
const U32 nbBitsBaseline)
|
||||||
{
|
{
|
||||||
U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1];
|
U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1];
|
||||||
const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */
|
const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */
|
||||||
const U32 minBits = nbBitsBaseline - maxWeight;
|
const U32 minBits = nbBitsBaseline - maxWeight;
|
||||||
U32 s;
|
U32 s;
|
||||||
@@ -413,29 +450,30 @@ static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t HUF_readDTableX4 (U32* DTable, const void* src, size_t srcSize)
|
size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
BYTE weightList[HUF_MAX_SYMBOL_VALUE + 1];
|
BYTE weightList[HUF_SYMBOLVALUE_MAX + 1];
|
||||||
sortedSymbol_t sortedSymbol[HUF_MAX_SYMBOL_VALUE + 1];
|
sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1];
|
||||||
U32 rankStats[HUF_ABSOLUTEMAX_TABLELOG + 1] = { 0 };
|
U32 rankStats[HUF_TABLELOG_ABSOLUTEMAX + 1] = { 0 };
|
||||||
U32 rankStart0[HUF_ABSOLUTEMAX_TABLELOG + 2] = { 0 };
|
U32 rankStart0[HUF_TABLELOG_ABSOLUTEMAX + 2] = { 0 };
|
||||||
U32* const rankStart = rankStart0+1;
|
U32* const rankStart = rankStart0+1;
|
||||||
rankVal_t rankVal;
|
rankVal_t rankVal;
|
||||||
U32 tableLog, maxW, sizeOfSort, nbSymbols;
|
U32 tableLog, maxW, sizeOfSort, nbSymbols;
|
||||||
const U32 memLog = DTable[0];
|
DTableDesc dtd = HUF_getDTableDesc(DTable);
|
||||||
|
U32 const maxTableLog = dtd.maxTableLog;
|
||||||
size_t iSize;
|
size_t iSize;
|
||||||
void* dtPtr = DTable;
|
void* dtPtr = DTable+1; /* force compiler to avoid strict-aliasing */
|
||||||
HUF_DEltX4* const dt = ((HUF_DEltX4*)dtPtr) + 1;
|
HUF_DEltX4* const dt = (HUF_DEltX4*)dtPtr;
|
||||||
|
|
||||||
HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(U32)); /* if compilation fails here, assertion is false */
|
HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable)); /* if compilation fails here, assertion is false */
|
||||||
if (memLog > HUF_ABSOLUTEMAX_TABLELOG) return ERROR(tableLog_tooLarge);
|
if (maxTableLog > HUF_TABLELOG_ABSOLUTEMAX) return ERROR(tableLog_tooLarge);
|
||||||
//memset(weightList, 0, sizeof(weightList)); /* is not necessary, even though some analyzer complain ... */
|
//memset(weightList, 0, sizeof(weightList)); /* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
iSize = HUF_readStats(weightList, HUF_MAX_SYMBOL_VALUE + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
|
iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
|
||||||
if (HUF_isError(iSize)) return iSize;
|
if (HUF_isError(iSize)) return iSize;
|
||||||
|
|
||||||
/* check result */
|
/* check result */
|
||||||
if (tableLog > memLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */
|
if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */
|
||||||
|
|
||||||
/* find maxWeight */
|
/* find maxWeight */
|
||||||
for (maxW = tableLog; rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */
|
for (maxW = tableLog; rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */
|
||||||
@@ -464,7 +502,7 @@ size_t HUF_readDTableX4 (U32* DTable, const void* src, size_t srcSize)
|
|||||||
|
|
||||||
/* Build rankVal */
|
/* Build rankVal */
|
||||||
{ U32* const rankVal0 = rankVal[0];
|
{ U32* const rankVal0 = rankVal[0];
|
||||||
{ int const rescale = (memLog-tableLog) - 1; /* tableLog <= memLog */
|
{ int const rescale = (maxTableLog-tableLog) - 1; /* tableLog <= maxTableLog */
|
||||||
U32 nextRankVal = 0;
|
U32 nextRankVal = 0;
|
||||||
U32 w;
|
U32 w;
|
||||||
for (w=1; w<maxW+1; w++) {
|
for (w=1; w<maxW+1; w++) {
|
||||||
@@ -474,18 +512,21 @@ size_t HUF_readDTableX4 (U32* DTable, const void* src, size_t srcSize)
|
|||||||
} }
|
} }
|
||||||
{ U32 const minBits = tableLog+1 - maxW;
|
{ U32 const minBits = tableLog+1 - maxW;
|
||||||
U32 consumed;
|
U32 consumed;
|
||||||
for (consumed = minBits; consumed < memLog - minBits + 1; consumed++) {
|
for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) {
|
||||||
U32* const rankValPtr = rankVal[consumed];
|
U32* const rankValPtr = rankVal[consumed];
|
||||||
U32 w;
|
U32 w;
|
||||||
for (w = 1; w < maxW+1; w++) {
|
for (w = 1; w < maxW+1; w++) {
|
||||||
rankValPtr[w] = rankVal0[w] >> consumed;
|
rankValPtr[w] = rankVal0[w] >> consumed;
|
||||||
} } } }
|
} } } }
|
||||||
|
|
||||||
HUF_fillDTableX4(dt, memLog,
|
HUF_fillDTableX4(dt, maxTableLog,
|
||||||
sortedSymbol, sizeOfSort,
|
sortedSymbol, sizeOfSort,
|
||||||
rankStart0, rankVal, maxW,
|
rankStart0, rankVal, maxW,
|
||||||
tableLog+1);
|
tableLog+1);
|
||||||
|
|
||||||
|
dtd.tableLog = (BYTE)maxTableLog;
|
||||||
|
dtd.tableType = 1;
|
||||||
|
memcpy(DTable, &dtd, sizeof(dtd));
|
||||||
return iSize;
|
return iSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,7 +558,7 @@ static U32 HUF_decodeLastSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DE
|
|||||||
ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
|
ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
|
||||||
|
|
||||||
#define HUF_DECODE_SYMBOLX4_1(ptr, DStreamPtr) \
|
#define HUF_DECODE_SYMBOLX4_1(ptr, DStreamPtr) \
|
||||||
if (MEM_64bits() || (HUF_MAX_TABLELOG<=12)) \
|
if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
|
||||||
ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
|
ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
|
||||||
|
|
||||||
#define HUF_DECODE_SYMBOLX4_2(ptr, DStreamPtr) \
|
#define HUF_DECODE_SYMBOLX4_2(ptr, DStreamPtr) \
|
||||||
@@ -536,7 +577,7 @@ static inline size_t HUF_decodeStreamX4(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* c
|
|||||||
HUF_DECODE_SYMBOLX4_0(p, bitDPtr);
|
HUF_DECODE_SYMBOLX4_0(p, bitDPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* closer to the end */
|
/* closer to end : up to 2 symbols at a time */
|
||||||
while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd-2))
|
while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd-2))
|
||||||
HUF_DECODE_SYMBOLX4_0(p, bitDPtr);
|
HUF_DECODE_SYMBOLX4_0(p, bitDPtr);
|
||||||
|
|
||||||
@@ -550,26 +591,26 @@ static inline size_t HUF_decodeStreamX4(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* c
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t HUF_decompress1X4_usingDTable(
|
static size_t HUF_decompress1X4_usingDTable_internal(
|
||||||
void* dst, size_t dstSize,
|
void* dst, size_t dstSize,
|
||||||
const void* cSrc, size_t cSrcSize,
|
const void* cSrc, size_t cSrcSize,
|
||||||
const U32* DTable)
|
const HUF_DTable* DTable)
|
||||||
{
|
{
|
||||||
const BYTE* const istart = (const BYTE*) cSrc;
|
BIT_DStream_t bitD;
|
||||||
BYTE* const ostart = (BYTE*) dst;
|
|
||||||
BYTE* const oend = ostart + dstSize;
|
|
||||||
|
|
||||||
const U32 dtLog = DTable[0];
|
|
||||||
const void* const dtPtr = DTable;
|
|
||||||
const HUF_DEltX4* const dt = ((const HUF_DEltX4*)dtPtr) +1;
|
|
||||||
|
|
||||||
/* Init */
|
/* Init */
|
||||||
BIT_DStream_t bitD;
|
{ size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
|
||||||
{ size_t const errorCode = BIT_initDStream(&bitD, istart, cSrcSize);
|
if (HUF_isError(errorCode)) return errorCode;
|
||||||
if (HUF_isError(errorCode)) return errorCode; }
|
}
|
||||||
|
|
||||||
/* decode */
|
/* decode */
|
||||||
HUF_decodeStreamX4(ostart, &bitD, oend, dt, dtLog);
|
{ BYTE* const ostart = (BYTE*) dst;
|
||||||
|
BYTE* const oend = ostart + dstSize;
|
||||||
|
const void* const dtPtr = DTable+1; /* force compiler to not use strict-aliasing */
|
||||||
|
const HUF_DEltX4* const dt = (const HUF_DEltX4*)dtPtr;
|
||||||
|
DTableDesc const dtd = HUF_getDTableDesc(DTable);
|
||||||
|
HUF_decodeStreamX4(ostart, &bitD, oend, dt, dtd.tableLog);
|
||||||
|
}
|
||||||
|
|
||||||
/* check */
|
/* check */
|
||||||
if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
|
if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
|
||||||
@@ -578,49 +619,61 @@ size_t HUF_decompress1X4_usingDTable(
|
|||||||
return dstSize;
|
return dstSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
size_t HUF_decompress1X4_usingDTable(
|
||||||
{
|
|
||||||
HUF_CREATE_STATIC_DTABLEX4(DTable, HUF_MAX_TABLELOG);
|
|
||||||
const BYTE* ip = (const BYTE*) cSrc;
|
|
||||||
|
|
||||||
size_t const hSize = HUF_readDTableX4 (DTable, cSrc, cSrcSize);
|
|
||||||
if (HUF_isError(hSize)) return hSize;
|
|
||||||
if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
|
|
||||||
ip += hSize;
|
|
||||||
cSrcSize -= hSize;
|
|
||||||
|
|
||||||
return HUF_decompress1X4_usingDTable (dst, dstSize, ip, cSrcSize, DTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t HUF_decompress4X4_usingDTable(
|
|
||||||
void* dst, size_t dstSize,
|
void* dst, size_t dstSize,
|
||||||
const void* cSrc, size_t cSrcSize,
|
const void* cSrc, size_t cSrcSize,
|
||||||
const U32* DTable)
|
const HUF_DTable* DTable)
|
||||||
|
{
|
||||||
|
DTableDesc dtd = HUF_getDTableDesc(DTable);
|
||||||
|
if (dtd.tableType != 1) return ERROR(GENERIC);
|
||||||
|
return HUF_decompress1X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HUF_decompress1X4_DCtx (HUF_DTable* DCtx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
|
{
|
||||||
|
const BYTE* ip = (const BYTE*) cSrc;
|
||||||
|
|
||||||
|
size_t const hSize = HUF_readDTableX4 (DCtx, cSrc, cSrcSize);
|
||||||
|
if (HUF_isError(hSize)) return hSize;
|
||||||
|
if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
|
||||||
|
ip += hSize; cSrcSize -= hSize;
|
||||||
|
|
||||||
|
return HUF_decompress1X4_usingDTable_internal (dst, dstSize, ip, cSrcSize, DCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
|
{
|
||||||
|
HUF_CREATE_STATIC_DTABLEX4(DTable, HUF_TABLELOG_MAX);
|
||||||
|
return HUF_decompress1X4_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t HUF_decompress4X4_usingDTable_internal(
|
||||||
|
void* dst, size_t dstSize,
|
||||||
|
const void* cSrc, size_t cSrcSize,
|
||||||
|
const HUF_DTable* DTable)
|
||||||
{
|
{
|
||||||
if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
|
if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
|
||||||
|
|
||||||
{ const BYTE* const istart = (const BYTE*) cSrc;
|
{ const BYTE* const istart = (const BYTE*) cSrc;
|
||||||
BYTE* const ostart = (BYTE*) dst;
|
BYTE* const ostart = (BYTE*) dst;
|
||||||
BYTE* const oend = ostart + dstSize;
|
BYTE* const oend = ostart + dstSize;
|
||||||
const void* const dtPtr = DTable;
|
const void* const dtPtr = DTable+1;
|
||||||
const HUF_DEltX4* const dt = ((const HUF_DEltX4*)dtPtr) +1;
|
const HUF_DEltX4* const dt = (const HUF_DEltX4*)dtPtr;
|
||||||
const U32 dtLog = DTable[0];
|
|
||||||
size_t errorCode;
|
|
||||||
|
|
||||||
/* Init */
|
/* Init */
|
||||||
BIT_DStream_t bitD1;
|
BIT_DStream_t bitD1;
|
||||||
BIT_DStream_t bitD2;
|
BIT_DStream_t bitD2;
|
||||||
BIT_DStream_t bitD3;
|
BIT_DStream_t bitD3;
|
||||||
BIT_DStream_t bitD4;
|
BIT_DStream_t bitD4;
|
||||||
const size_t length1 = MEM_readLE16(istart);
|
size_t const length1 = MEM_readLE16(istart);
|
||||||
const size_t length2 = MEM_readLE16(istart+2);
|
size_t const length2 = MEM_readLE16(istart+2);
|
||||||
const size_t length3 = MEM_readLE16(istart+4);
|
size_t const length3 = MEM_readLE16(istart+4);
|
||||||
size_t length4;
|
size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
|
||||||
const BYTE* const istart1 = istart + 6; /* jumpTable */
|
const BYTE* const istart1 = istart + 6; /* jumpTable */
|
||||||
const BYTE* const istart2 = istart1 + length1;
|
const BYTE* const istart2 = istart1 + length1;
|
||||||
const BYTE* const istart3 = istart2 + length2;
|
const BYTE* const istart3 = istart2 + length2;
|
||||||
const BYTE* const istart4 = istart3 + length3;
|
const BYTE* const istart4 = istart3 + length3;
|
||||||
const size_t segmentSize = (dstSize+3) / 4;
|
size_t const segmentSize = (dstSize+3) / 4;
|
||||||
BYTE* const opStart2 = ostart + segmentSize;
|
BYTE* const opStart2 = ostart + segmentSize;
|
||||||
BYTE* const opStart3 = opStart2 + segmentSize;
|
BYTE* const opStart3 = opStart2 + segmentSize;
|
||||||
BYTE* const opStart4 = opStart3 + segmentSize;
|
BYTE* const opStart4 = opStart3 + segmentSize;
|
||||||
@@ -629,17 +682,18 @@ size_t HUF_decompress4X4_usingDTable(
|
|||||||
BYTE* op3 = opStart3;
|
BYTE* op3 = opStart3;
|
||||||
BYTE* op4 = opStart4;
|
BYTE* op4 = opStart4;
|
||||||
U32 endSignal;
|
U32 endSignal;
|
||||||
|
DTableDesc const dtd = HUF_getDTableDesc(DTable);
|
||||||
|
U32 const dtLog = dtd.tableLog;
|
||||||
|
|
||||||
length4 = cSrcSize - (length1 + length2 + length3 + 6);
|
|
||||||
if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
|
if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
|
||||||
errorCode = BIT_initDStream(&bitD1, istart1, length1);
|
{ size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (HUF_isError(errorCode)) return errorCode; }
|
||||||
errorCode = BIT_initDStream(&bitD2, istart2, length2);
|
{ size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (HUF_isError(errorCode)) return errorCode; }
|
||||||
errorCode = BIT_initDStream(&bitD3, istart3, length3);
|
{ size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (HUF_isError(errorCode)) return errorCode; }
|
||||||
errorCode = BIT_initDStream(&bitD4, istart4, length4);
|
{ size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
|
||||||
if (HUF_isError(errorCode)) return errorCode;
|
if (HUF_isError(errorCode)) return errorCode; }
|
||||||
|
|
||||||
/* 16-32 symbols per loop (4-8 symbols per stream) */
|
/* 16-32 symbols per loop (4-8 symbols per stream) */
|
||||||
endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
|
endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
|
||||||
@@ -677,8 +731,8 @@ size_t HUF_decompress4X4_usingDTable(
|
|||||||
HUF_decodeStreamX4(op4, &bitD4, oend, dt, dtLog);
|
HUF_decodeStreamX4(op4, &bitD4, oend, dt, dtLog);
|
||||||
|
|
||||||
/* check */
|
/* check */
|
||||||
endSignal = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
|
{ U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
|
||||||
if (!endSignal) return ERROR(corruption_detected);
|
if (!endCheck) return ERROR(corruption_detected); }
|
||||||
|
|
||||||
/* decoded size */
|
/* decoded size */
|
||||||
return dstSize;
|
return dstSize;
|
||||||
@@ -686,398 +740,33 @@ size_t HUF_decompress4X4_usingDTable(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t HUF_decompress4X4_usingDTable(
|
||||||
|
void* dst, size_t dstSize,
|
||||||
|
const void* cSrc, size_t cSrcSize,
|
||||||
|
const HUF_DTable* DTable)
|
||||||
|
{
|
||||||
|
DTableDesc dtd = HUF_getDTableDesc(DTable);
|
||||||
|
if (dtd.tableType != 1) return ERROR(GENERIC);
|
||||||
|
return HUF_decompress4X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t HUF_decompress4X4_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
|
{
|
||||||
|
const BYTE* ip = (const BYTE*) cSrc;
|
||||||
|
|
||||||
|
size_t hSize = HUF_readDTableX4 (dctx, cSrc, cSrcSize);
|
||||||
|
if (HUF_isError(hSize)) return hSize;
|
||||||
|
if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
|
||||||
|
ip += hSize; cSrcSize -= hSize;
|
||||||
|
|
||||||
|
return HUF_decompress4X4_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx);
|
||||||
|
}
|
||||||
|
|
||||||
size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
{
|
{
|
||||||
HUF_CREATE_STATIC_DTABLEX4(DTable, HUF_MAX_TABLELOG);
|
HUF_CREATE_STATIC_DTABLEX4(DTable, HUF_TABLELOG_MAX);
|
||||||
const BYTE* ip = (const BYTE*) cSrc;
|
return HUF_decompress4X4_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
|
||||||
|
|
||||||
size_t hSize = HUF_readDTableX4 (DTable, cSrc, cSrcSize);
|
|
||||||
if (HUF_isError(hSize)) return hSize;
|
|
||||||
if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
|
|
||||||
ip += hSize;
|
|
||||||
cSrcSize -= hSize;
|
|
||||||
|
|
||||||
return HUF_decompress4X4_usingDTable (dst, dstSize, ip, cSrcSize, DTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ********************************/
|
|
||||||
/* quad-symbol decoding */
|
|
||||||
/* ********************************/
|
|
||||||
typedef struct { BYTE nbBits; BYTE nbBytes; } HUF_DDescX6;
|
|
||||||
typedef union { BYTE byte[4]; U32 sequence; } HUF_DSeqX6;
|
|
||||||
|
|
||||||
/* recursive, up to level 3; may benefit from <template>-like strategy to nest each level inline */
|
|
||||||
static void HUF_fillDTableX6LevelN(HUF_DDescX6* DDescription, HUF_DSeqX6* DSequence, int sizeLog,
|
|
||||||
const rankVal_t rankValOrigin, const U32 consumed, const int minWeight, const U32 maxWeight,
|
|
||||||
const sortedSymbol_t* sortedSymbols, const U32 sortedListSize, const U32* rankStart,
|
|
||||||
const U32 nbBitsBaseline, HUF_DSeqX6 baseSeq, HUF_DDescX6 DDesc)
|
|
||||||
{
|
|
||||||
const int scaleLog = nbBitsBaseline - sizeLog; /* note : targetLog >= (nbBitsBaseline-1), hence scaleLog <= 1 */
|
|
||||||
const int minBits = nbBitsBaseline - maxWeight;
|
|
||||||
const U32 level = DDesc.nbBytes;
|
|
||||||
U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1];
|
|
||||||
U32 symbolStartPos, s;
|
|
||||||
|
|
||||||
/* local rankVal, will be modified */
|
|
||||||
memcpy(rankVal, rankValOrigin[consumed], sizeof(rankVal));
|
|
||||||
|
|
||||||
/* fill skipped values */
|
|
||||||
if (minWeight>1) {
|
|
||||||
U32 i;
|
|
||||||
const U32 skipSize = rankVal[minWeight];
|
|
||||||
for (i = 0; i < skipSize; i++) {
|
|
||||||
DSequence[i] = baseSeq;
|
|
||||||
DDescription[i] = DDesc;
|
|
||||||
} }
|
|
||||||
|
|
||||||
/* fill DTable */
|
|
||||||
DDesc.nbBytes++;
|
|
||||||
symbolStartPos = rankStart[minWeight];
|
|
||||||
for (s=symbolStartPos; s<sortedListSize; s++) {
|
|
||||||
const BYTE symbol = sortedSymbols[s].symbol;
|
|
||||||
const U32 weight = sortedSymbols[s].weight; /* >= 1 (sorted) */
|
|
||||||
const int nbBits = nbBitsBaseline - weight; /* >= 1 (by construction) */
|
|
||||||
const int totalBits = consumed+nbBits;
|
|
||||||
const U32 start = rankVal[weight];
|
|
||||||
const U32 length = 1 << (sizeLog-nbBits);
|
|
||||||
baseSeq.byte[level] = symbol;
|
|
||||||
DDesc.nbBits = (BYTE)totalBits;
|
|
||||||
|
|
||||||
if ((level<3) && (sizeLog-totalBits >= minBits)) { /* enough room for another symbol */
|
|
||||||
int nextMinWeight = totalBits + scaleLog;
|
|
||||||
if (nextMinWeight < 1) nextMinWeight = 1;
|
|
||||||
HUF_fillDTableX6LevelN(DDescription+start, DSequence+start, sizeLog-nbBits,
|
|
||||||
rankValOrigin, totalBits, nextMinWeight, maxWeight,
|
|
||||||
sortedSymbols, sortedListSize, rankStart,
|
|
||||||
nbBitsBaseline, baseSeq, DDesc); /* recursive (max : level 3) */
|
|
||||||
} else {
|
|
||||||
U32 i;
|
|
||||||
const U32 end = start + length;
|
|
||||||
for (i = start; i < end; i++) {
|
|
||||||
DDescription[i] = DDesc;
|
|
||||||
DSequence[i] = baseSeq;
|
|
||||||
} }
|
|
||||||
rankVal[weight] += length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* note : same preparation as X4 */
|
|
||||||
size_t HUF_readDTableX6 (U32* DTable, const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
BYTE weightList[HUF_MAX_SYMBOL_VALUE + 1];
|
|
||||||
sortedSymbol_t sortedSymbol[HUF_MAX_SYMBOL_VALUE + 1];
|
|
||||||
U32 rankStats[HUF_ABSOLUTEMAX_TABLELOG + 1] = { 0 };
|
|
||||||
U32 rankStart0[HUF_ABSOLUTEMAX_TABLELOG + 2] = { 0 };
|
|
||||||
U32* const rankStart = rankStart0+1;
|
|
||||||
U32 tableLog, maxW, sizeOfSort, nbSymbols;
|
|
||||||
rankVal_t rankVal;
|
|
||||||
const U32 memLog = DTable[0];
|
|
||||||
size_t iSize;
|
|
||||||
|
|
||||||
if (memLog > HUF_ABSOLUTEMAX_TABLELOG) return ERROR(tableLog_tooLarge);
|
|
||||||
//memset(weightList, 0, sizeof(weightList)); /* is not necessary, even though some analyzer complain ... */
|
|
||||||
|
|
||||||
iSize = HUF_readStats(weightList, HUF_MAX_SYMBOL_VALUE + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
|
|
||||||
if (HUF_isError(iSize)) return iSize;
|
|
||||||
|
|
||||||
/* check result */
|
|
||||||
if (tableLog > memLog) return ERROR(tableLog_tooLarge); /* DTable is too small */
|
|
||||||
|
|
||||||
/* find maxWeight */
|
|
||||||
for (maxW = tableLog; maxW && rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */
|
|
||||||
|
|
||||||
/* Get start index of each weight */
|
|
||||||
{ U32 w, nextRankStart = 0;
|
|
||||||
for (w=1; w<maxW+1; w++) {
|
|
||||||
U32 current = nextRankStart;
|
|
||||||
nextRankStart += rankStats[w];
|
|
||||||
rankStart[w] = current;
|
|
||||||
}
|
|
||||||
rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/
|
|
||||||
sizeOfSort = nextRankStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* sort symbols by weight */
|
|
||||||
{ U32 s;
|
|
||||||
for (s=0; s<nbSymbols; s++) {
|
|
||||||
U32 w = weightList[s];
|
|
||||||
U32 r = rankStart[w]++;
|
|
||||||
sortedSymbol[r].symbol = (BYTE)s;
|
|
||||||
sortedSymbol[r].weight = (BYTE)w;
|
|
||||||
}
|
|
||||||
rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build rankVal */
|
|
||||||
{ const U32 minBits = tableLog+1 - maxW;
|
|
||||||
U32 nextRankVal = 0;
|
|
||||||
U32 w, consumed;
|
|
||||||
const int rescale = (memLog-tableLog) - 1; /* tableLog <= memLog */
|
|
||||||
U32* rankVal0 = rankVal[0];
|
|
||||||
for (w=1; w<maxW+1; w++) {
|
|
||||||
U32 current = nextRankVal;
|
|
||||||
nextRankVal += rankStats[w] << (w+rescale);
|
|
||||||
rankVal0[w] = current;
|
|
||||||
}
|
|
||||||
for (consumed = minBits; consumed <= memLog - minBits; consumed++) {
|
|
||||||
U32* rankValPtr = rankVal[consumed];
|
|
||||||
for (w = 1; w < maxW+1; w++) {
|
|
||||||
rankValPtr[w] = rankVal0[w] >> consumed;
|
|
||||||
} } }
|
|
||||||
|
|
||||||
/* fill tables */
|
|
||||||
{ void* ddPtr = DTable+1;
|
|
||||||
HUF_DDescX6* DDescription = (HUF_DDescX6*)ddPtr;
|
|
||||||
void* dsPtr = DTable + 1 + ((size_t)1<<(memLog-1));
|
|
||||||
HUF_DSeqX6* DSequence = (HUF_DSeqX6*)dsPtr;
|
|
||||||
HUF_DSeqX6 DSeq;
|
|
||||||
HUF_DDescX6 DDesc;
|
|
||||||
DSeq.sequence = 0;
|
|
||||||
DDesc.nbBits = 0;
|
|
||||||
DDesc.nbBytes = 0;
|
|
||||||
HUF_fillDTableX6LevelN(DDescription, DSequence, memLog,
|
|
||||||
(const U32 (*)[HUF_ABSOLUTEMAX_TABLELOG + 1])rankVal, 0, 1, maxW,
|
|
||||||
sortedSymbol, sizeOfSort, rankStart0,
|
|
||||||
tableLog+1, DSeq, DDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return iSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static U32 HUF_decodeSymbolX6(void* op, BIT_DStream_t* DStream, const HUF_DDescX6* dd, const HUF_DSeqX6* ds, const U32 dtLog)
|
|
||||||
{
|
|
||||||
size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
|
|
||||||
memcpy(op, ds+val, sizeof(HUF_DSeqX6));
|
|
||||||
BIT_skipBits(DStream, dd[val].nbBits);
|
|
||||||
return dd[val].nbBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
static U32 HUF_decodeLastSymbolsX6(void* op, U32 const maxL, BIT_DStream_t* DStream,
|
|
||||||
const HUF_DDescX6* dd, const HUF_DSeqX6* ds, const U32 dtLog)
|
|
||||||
{
|
|
||||||
size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
|
|
||||||
U32 const length = dd[val].nbBytes;
|
|
||||||
if (length <= maxL) {
|
|
||||||
memcpy(op, ds+val, length);
|
|
||||||
BIT_skipBits(DStream, dd[val].nbBits);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
memcpy(op, ds+val, maxL);
|
|
||||||
if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
|
|
||||||
BIT_skipBits(DStream, dd[val].nbBits);
|
|
||||||
if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))
|
|
||||||
DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8); /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
|
|
||||||
}
|
|
||||||
return maxL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define HUF_DECODE_SYMBOLX6_0(ptr, DStreamPtr) \
|
|
||||||
ptr += HUF_decodeSymbolX6(ptr, DStreamPtr, dd, ds, dtLog)
|
|
||||||
|
|
||||||
#define HUF_DECODE_SYMBOLX6_1(ptr, DStreamPtr) \
|
|
||||||
if (MEM_64bits() || (HUF_MAX_TABLELOG<=12)) \
|
|
||||||
HUF_DECODE_SYMBOLX6_0(ptr, DStreamPtr)
|
|
||||||
|
|
||||||
#define HUF_DECODE_SYMBOLX6_2(ptr, DStreamPtr) \
|
|
||||||
if (MEM_64bits()) \
|
|
||||||
HUF_DECODE_SYMBOLX6_0(ptr, DStreamPtr)
|
|
||||||
|
|
||||||
static inline size_t HUF_decodeStreamX6(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, const U32* DTable, const U32 dtLog)
|
|
||||||
{
|
|
||||||
const void* const ddPtr = DTable+1;
|
|
||||||
const HUF_DDescX6* dd = (const HUF_DDescX6*)ddPtr;
|
|
||||||
const void* const dsPtr = DTable + 1 + ((size_t)1<<(dtLog-1));
|
|
||||||
const HUF_DSeqX6* ds = (const HUF_DSeqX6*)dsPtr;
|
|
||||||
BYTE* const pStart = p;
|
|
||||||
|
|
||||||
/* up to 16 symbols at a time */
|
|
||||||
while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd-16)) {
|
|
||||||
HUF_DECODE_SYMBOLX6_2(p, bitDPtr);
|
|
||||||
HUF_DECODE_SYMBOLX6_1(p, bitDPtr);
|
|
||||||
HUF_DECODE_SYMBOLX6_2(p, bitDPtr);
|
|
||||||
HUF_DECODE_SYMBOLX6_0(p, bitDPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* closer to the end, up to 4 symbols at a time */
|
|
||||||
while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd-4))
|
|
||||||
HUF_DECODE_SYMBOLX6_0(p, bitDPtr);
|
|
||||||
|
|
||||||
while ((BIT_reloadDStream(bitDPtr) <= BIT_DStream_endOfBuffer) && (p < pEnd))
|
|
||||||
p += HUF_decodeLastSymbolsX6(p, (U32)(pEnd-p), bitDPtr, dd, ds, dtLog);
|
|
||||||
|
|
||||||
return p-pStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t HUF_decompress1X6_usingDTable(
|
|
||||||
void* dst, size_t dstSize,
|
|
||||||
const void* cSrc, size_t cSrcSize,
|
|
||||||
const U32* DTable)
|
|
||||||
{
|
|
||||||
const BYTE* const istart = (const BYTE*) cSrc;
|
|
||||||
BYTE* const ostart = (BYTE*) dst;
|
|
||||||
BYTE* const oend = ostart + dstSize;
|
|
||||||
BIT_DStream_t bitD;
|
|
||||||
|
|
||||||
/* Init */
|
|
||||||
{ size_t const errorCode = BIT_initDStream(&bitD, istart, cSrcSize);
|
|
||||||
if (HUF_isError(errorCode)) return errorCode; }
|
|
||||||
|
|
||||||
/* finish bitStreams one by one */
|
|
||||||
{ U32 const dtLog = DTable[0];
|
|
||||||
HUF_decodeStreamX6(ostart, &bitD, oend, DTable, dtLog); }
|
|
||||||
|
|
||||||
/* check */
|
|
||||||
if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
|
|
||||||
|
|
||||||
/* decoded size */
|
|
||||||
return dstSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t HUF_decompress1X6 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
||||||
{
|
|
||||||
HUF_CREATE_STATIC_DTABLEX6(DTable, HUF_MAX_TABLELOG);
|
|
||||||
const BYTE* ip = (const BYTE*) cSrc;
|
|
||||||
|
|
||||||
size_t const hSize = HUF_readDTableX6 (DTable, cSrc, cSrcSize);
|
|
||||||
if (HUF_isError(hSize)) return hSize;
|
|
||||||
if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
|
|
||||||
ip += hSize;
|
|
||||||
cSrcSize -= hSize;
|
|
||||||
|
|
||||||
return HUF_decompress1X6_usingDTable (dst, dstSize, ip, cSrcSize, DTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define HUF_DECODE_ROUNDX6 \
|
|
||||||
HUF_DECODE_SYMBOLX6_2(op1, &bitD1); \
|
|
||||||
HUF_DECODE_SYMBOLX6_2(op2, &bitD2); \
|
|
||||||
HUF_DECODE_SYMBOLX6_2(op3, &bitD3); \
|
|
||||||
HUF_DECODE_SYMBOLX6_2(op4, &bitD4); \
|
|
||||||
HUF_DECODE_SYMBOLX6_1(op1, &bitD1); \
|
|
||||||
HUF_DECODE_SYMBOLX6_1(op2, &bitD2); \
|
|
||||||
HUF_DECODE_SYMBOLX6_1(op3, &bitD3); \
|
|
||||||
HUF_DECODE_SYMBOLX6_1(op4, &bitD4); \
|
|
||||||
HUF_DECODE_SYMBOLX6_2(op1, &bitD1); \
|
|
||||||
HUF_DECODE_SYMBOLX6_2(op2, &bitD2); \
|
|
||||||
HUF_DECODE_SYMBOLX6_2(op3, &bitD3); \
|
|
||||||
HUF_DECODE_SYMBOLX6_2(op4, &bitD4); \
|
|
||||||
HUF_DECODE_SYMBOLX6_0(op1, &bitD1); \
|
|
||||||
HUF_DECODE_SYMBOLX6_0(op2, &bitD2); \
|
|
||||||
HUF_DECODE_SYMBOLX6_0(op3, &bitD3); \
|
|
||||||
HUF_DECODE_SYMBOLX6_0(op4, &bitD4);
|
|
||||||
|
|
||||||
size_t HUF_decompress4X6_usingDTable(
|
|
||||||
void* dst, size_t dstSize,
|
|
||||||
const void* cSrc, size_t cSrcSize,
|
|
||||||
const U32* DTable)
|
|
||||||
{
|
|
||||||
/* Check */
|
|
||||||
if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
|
|
||||||
if (dstSize < 64) return ERROR(dstSize_tooSmall); /* only work for dstSize >= 64 */
|
|
||||||
|
|
||||||
{ const BYTE* const istart = (const BYTE*) cSrc;
|
|
||||||
BYTE* const ostart = (BYTE*) dst;
|
|
||||||
BYTE* const oend = ostart + dstSize;
|
|
||||||
|
|
||||||
const U32 dtLog = DTable[0];
|
|
||||||
const void* const ddPtr = DTable+1;
|
|
||||||
const HUF_DDescX6* dd = (const HUF_DDescX6*)ddPtr;
|
|
||||||
const void* const dsPtr = DTable + 1 + ((size_t)1<<(dtLog-1));
|
|
||||||
const HUF_DSeqX6* ds = (const HUF_DSeqX6*)dsPtr;
|
|
||||||
|
|
||||||
/* Init */
|
|
||||||
BIT_DStream_t bitD1;
|
|
||||||
BIT_DStream_t bitD2;
|
|
||||||
BIT_DStream_t bitD3;
|
|
||||||
BIT_DStream_t bitD4;
|
|
||||||
const size_t length1 = MEM_readLE16(istart);
|
|
||||||
const size_t length2 = MEM_readLE16(istart+2);
|
|
||||||
const size_t length3 = MEM_readLE16(istart+4);
|
|
||||||
size_t length4;
|
|
||||||
const BYTE* const istart1 = istart + 6; /* jumpTable */
|
|
||||||
const BYTE* const istart2 = istart1 + length1;
|
|
||||||
const BYTE* const istart3 = istart2 + length2;
|
|
||||||
const BYTE* const istart4 = istart3 + length3;
|
|
||||||
const size_t segmentSize = (dstSize+3) / 4;
|
|
||||||
BYTE* const opStart2 = ostart + segmentSize;
|
|
||||||
BYTE* const opStart3 = opStart2 + segmentSize;
|
|
||||||
BYTE* const opStart4 = opStart3 + segmentSize;
|
|
||||||
BYTE* op1 = ostart;
|
|
||||||
BYTE* op2 = opStart2;
|
|
||||||
BYTE* op3 = opStart3;
|
|
||||||
BYTE* op4 = opStart4;
|
|
||||||
U32 endSignal;
|
|
||||||
|
|
||||||
length4 = cSrcSize - (length1 + length2 + length3 + 6);
|
|
||||||
if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
|
|
||||||
{ size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
|
|
||||||
if (HUF_isError(errorCode)) return errorCode; }
|
|
||||||
{ size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
|
|
||||||
if (HUF_isError(errorCode)) return errorCode; }
|
|
||||||
{ size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
|
|
||||||
if (HUF_isError(errorCode)) return errorCode; }
|
|
||||||
{ size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
|
|
||||||
if (HUF_isError(errorCode)) return errorCode; }
|
|
||||||
|
|
||||||
/* 4-64 symbols per loop (1-16 symbols per stream) */
|
|
||||||
endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
|
|
||||||
if (endSignal==BIT_DStream_unfinished) {
|
|
||||||
HUF_DECODE_ROUNDX6;
|
|
||||||
if (sizeof(bitD1.bitContainer)==4) { /* need to decode at least 4 bytes per stream */
|
|
||||||
endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
|
|
||||||
HUF_DECODE_ROUNDX6;
|
|
||||||
}
|
|
||||||
{ U32 const saved2 = MEM_read32(opStart2); /* saved from overwrite */
|
|
||||||
U32 const saved3 = MEM_read32(opStart3);
|
|
||||||
U32 const saved4 = MEM_read32(opStart4);
|
|
||||||
endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
|
|
||||||
for ( ; (op3 <= opStart4) && (endSignal==BIT_DStream_unfinished) && (op4<=(oend-16)) ; ) {
|
|
||||||
HUF_DECODE_ROUNDX6;
|
|
||||||
endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
|
|
||||||
}
|
|
||||||
MEM_write32(opStart2, saved2);
|
|
||||||
MEM_write32(opStart3, saved3);
|
|
||||||
MEM_write32(opStart4, saved4);
|
|
||||||
} }
|
|
||||||
|
|
||||||
/* check corruption */
|
|
||||||
if (op1 > opStart2) return ERROR(corruption_detected);
|
|
||||||
if (op2 > opStart3) return ERROR(corruption_detected);
|
|
||||||
if (op3 > opStart4) return ERROR(corruption_detected);
|
|
||||||
/* note : op4 already verified within main loop */
|
|
||||||
|
|
||||||
/* finish bitStreams one by one */
|
|
||||||
HUF_decodeStreamX6(op1, &bitD1, opStart2, DTable, dtLog);
|
|
||||||
HUF_decodeStreamX6(op2, &bitD2, opStart3, DTable, dtLog);
|
|
||||||
HUF_decodeStreamX6(op3, &bitD3, opStart4, DTable, dtLog);
|
|
||||||
HUF_decodeStreamX6(op4, &bitD4, oend, DTable, dtLog);
|
|
||||||
|
|
||||||
/* check */
|
|
||||||
endSignal = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
|
|
||||||
if (!endSignal) return ERROR(corruption_detected);
|
|
||||||
|
|
||||||
/* decoded size */
|
|
||||||
return dstSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t HUF_decompress4X6 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
|
||||||
{
|
|
||||||
HUF_CREATE_STATIC_DTABLEX6(DTable, HUF_MAX_TABLELOG);
|
|
||||||
const BYTE* ip = (const BYTE*) cSrc;
|
|
||||||
|
|
||||||
size_t const hSize = HUF_readDTableX6 (DTable, cSrc, cSrcSize);
|
|
||||||
if (HUF_isError(hSize)) return hSize;
|
|
||||||
if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
|
|
||||||
ip += hSize;
|
|
||||||
cSrcSize -= hSize;
|
|
||||||
|
|
||||||
return HUF_decompress4X6_usingDTable (dst, dstSize, ip, cSrcSize, DTable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1085,6 +774,25 @@ size_t HUF_decompress4X6 (void* dst, size_t dstSize, const void* cSrc, size_t cS
|
|||||||
/* Generic decompression selector */
|
/* Generic decompression selector */
|
||||||
/* ********************************/
|
/* ********************************/
|
||||||
|
|
||||||
|
size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize,
|
||||||
|
const void* cSrc, size_t cSrcSize,
|
||||||
|
const HUF_DTable* DTable)
|
||||||
|
{
|
||||||
|
DTableDesc const dtd = HUF_getDTableDesc(DTable);
|
||||||
|
return dtd.tableType ? HUF_decompress1X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable) :
|
||||||
|
HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize,
|
||||||
|
const void* cSrc, size_t cSrcSize,
|
||||||
|
const HUF_DTable* DTable)
|
||||||
|
{
|
||||||
|
DTableDesc const dtd = HUF_getDTableDesc(DTable);
|
||||||
|
return dtd.tableType ? HUF_decompress4X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable) :
|
||||||
|
HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;
|
typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;
|
||||||
static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] =
|
static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] =
|
||||||
{
|
{
|
||||||
@@ -1107,12 +815,29 @@ static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, qu
|
|||||||
{{ 722,128}, {1891,145}, {1936,146}}, /* Q ==15 : 93-99% */
|
{{ 722,128}, {1891,145}, {1936,146}}, /* Q ==15 : 93-99% */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** HUF_selectDecoder() :
|
||||||
|
* Tells which decoder is likely to decode faster,
|
||||||
|
* based on a set of pre-determined metrics.
|
||||||
|
* @return : 0==HUF_decompress4X2, 1==HUF_decompress4X4 .
|
||||||
|
* Assumption : 0 < cSrcSize < dstSize <= 128 KB */
|
||||||
|
U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize)
|
||||||
|
{
|
||||||
|
/* decoder timing evaluation */
|
||||||
|
U32 const Q = (U32)(cSrcSize * 16 / dstSize); /* Q < 16 since dstSize > cSrcSize */
|
||||||
|
U32 const D256 = (U32)(dstSize >> 8);
|
||||||
|
U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256);
|
||||||
|
U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256);
|
||||||
|
DTime1 += DTime1 >> 3; /* advantage to algorithm using less memory, for cache eviction */
|
||||||
|
|
||||||
|
return DTime1 < DTime0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
|
typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
|
||||||
|
|
||||||
size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
{
|
{
|
||||||
static const decompressionAlgo decompress[3] = { HUF_decompress4X2, HUF_decompress4X4, HUF_decompress4X6 };
|
static const decompressionAlgo decompress[2] = { HUF_decompress4X2, HUF_decompress4X4 };
|
||||||
U32 Dtime[3]; /* decompression time estimation */
|
|
||||||
|
|
||||||
/* validation checks */
|
/* validation checks */
|
||||||
if (dstSize == 0) return ERROR(dstSize_tooSmall);
|
if (dstSize == 0) return ERROR(dstSize_tooSmall);
|
||||||
@@ -1120,22 +845,50 @@ size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcS
|
|||||||
if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
|
if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
|
||||||
if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
|
if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
|
||||||
|
|
||||||
/* decoder timing evaluation */
|
{ U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
|
||||||
{ U32 const Q = (U32)(cSrcSize * 16 / dstSize); /* Q < 16 since dstSize > cSrcSize */
|
|
||||||
U32 const D256 = (U32)(dstSize >> 8);
|
|
||||||
U32 n; for (n=0; n<3; n++)
|
|
||||||
Dtime[n] = algoTime[Q][n].tableTime + (algoTime[Q][n].decode256Time * D256);
|
|
||||||
}
|
|
||||||
|
|
||||||
Dtime[1] += Dtime[1] >> 4; Dtime[2] += Dtime[2] >> 3; /* advantage to algorithms using less memory, for cache eviction */
|
|
||||||
|
|
||||||
{ U32 algoNb = 0;
|
|
||||||
if (Dtime[1] < Dtime[0]) algoNb = 1;
|
|
||||||
// if (Dtime[2] < Dtime[algoNb]) algoNb = 2; /* current speed of HUF_decompress4X6 is not good */
|
|
||||||
return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);
|
return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
//return HUF_decompress4X2(dst, dstSize, cSrc, cSrcSize); /* multi-streams single-symbol decoding */
|
//return HUF_decompress4X2(dst, dstSize, cSrc, cSrcSize); /* multi-streams single-symbol decoding */
|
||||||
//return HUF_decompress4X4(dst, dstSize, cSrc, cSrcSize); /* multi-streams double-symbols decoding */
|
//return HUF_decompress4X4(dst, dstSize, cSrc, cSrcSize); /* multi-streams double-symbols decoding */
|
||||||
//return HUF_decompress4X6(dst, dstSize, cSrc, cSrcSize); /* multi-streams quad-symbols decoding */
|
}
|
||||||
|
|
||||||
|
size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
|
{
|
||||||
|
/* validation checks */
|
||||||
|
if (dstSize == 0) return ERROR(dstSize_tooSmall);
|
||||||
|
if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
|
||||||
|
if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
|
||||||
|
if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
|
||||||
|
|
||||||
|
{ U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
|
||||||
|
return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
|
||||||
|
HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HUF_decompress4X_hufOnly (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
|
{
|
||||||
|
/* validation checks */
|
||||||
|
if (dstSize == 0) return ERROR(dstSize_tooSmall);
|
||||||
|
if ((cSrcSize >= dstSize) || (cSrcSize <= 1)) return ERROR(corruption_detected); /* invalid */
|
||||||
|
|
||||||
|
{ U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
|
||||||
|
return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
|
||||||
|
HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
|
{
|
||||||
|
/* validation checks */
|
||||||
|
if (dstSize == 0) return ERROR(dstSize_tooSmall);
|
||||||
|
if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
|
||||||
|
if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
|
||||||
|
if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
|
||||||
|
|
||||||
|
{ U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
|
||||||
|
return algoNb ? HUF_decompress1X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
|
||||||
|
HUF_decompress1X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,9 +35,9 @@
|
|||||||
***************************************/
|
***************************************/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "error_private.h"
|
#include "error_private.h"
|
||||||
#include "zstd_internal.h" /* MIN, ZSTD_blockHeaderSize */
|
#include "zstd_internal.h" /* MIN, ZSTD_blockHeaderSize, ZSTD_BLOCKSIZE_MAX */
|
||||||
#include "zstd_static.h" /* ZSTD_BLOCKSIZE_MAX */
|
#define ZBUFF_STATIC_LINKING_ONLY
|
||||||
#include "zbuff_static.h"
|
#include "zbuff.h"
|
||||||
|
|
||||||
|
|
||||||
/*-***************************************************************************
|
/*-***************************************************************************
|
||||||
@@ -82,15 +82,31 @@ struct ZBUFF_DCtx_s {
|
|||||||
size_t blockSize;
|
size_t blockSize;
|
||||||
BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
|
BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
|
||||||
size_t lhSize;
|
size_t lhSize;
|
||||||
|
ZSTD_customMem customMem;
|
||||||
}; /* typedef'd to ZBUFF_DCtx within "zstd_buffered.h" */
|
}; /* typedef'd to ZBUFF_DCtx within "zstd_buffered.h" */
|
||||||
|
|
||||||
|
|
||||||
ZBUFF_DCtx* ZBUFF_createDCtx(void)
|
ZBUFF_DCtx* ZBUFF_createDCtx(void)
|
||||||
{
|
{
|
||||||
ZBUFF_DCtx* zbd = (ZBUFF_DCtx*)malloc(sizeof(ZBUFF_DCtx));
|
return ZBUFF_createDCtx_advanced(defaultCustomMem);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZBUFF_DCtx* ZBUFF_createDCtx_advanced(ZSTD_customMem customMem)
|
||||||
|
{
|
||||||
|
ZBUFF_DCtx* zbd;
|
||||||
|
|
||||||
|
if (!customMem.customAlloc && !customMem.customFree)
|
||||||
|
customMem = defaultCustomMem;
|
||||||
|
|
||||||
|
if (!customMem.customAlloc || !customMem.customFree)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
zbd = (ZBUFF_DCtx*)customMem.customAlloc(customMem.opaque, sizeof(ZBUFF_DCtx));
|
||||||
if (zbd==NULL) return NULL;
|
if (zbd==NULL) return NULL;
|
||||||
memset(zbd, 0, sizeof(*zbd));
|
memset(zbd, 0, sizeof(ZBUFF_DCtx));
|
||||||
zbd->zd = ZSTD_createDCtx();
|
memcpy(&zbd->customMem, &customMem, sizeof(ZSTD_customMem));
|
||||||
|
zbd->zd = ZSTD_createDCtx_advanced(customMem);
|
||||||
|
if (zbd->zd == NULL) { ZBUFF_freeDCtx(zbd); return NULL; }
|
||||||
zbd->stage = ZBUFFds_init;
|
zbd->stage = ZBUFFds_init;
|
||||||
return zbd;
|
return zbd;
|
||||||
}
|
}
|
||||||
@@ -99,9 +115,9 @@ size_t ZBUFF_freeDCtx(ZBUFF_DCtx* zbd)
|
|||||||
{
|
{
|
||||||
if (zbd==NULL) return 0; /* support free on null */
|
if (zbd==NULL) return 0; /* support free on null */
|
||||||
ZSTD_freeDCtx(zbd->zd);
|
ZSTD_freeDCtx(zbd->zd);
|
||||||
free(zbd->inBuff);
|
if (zbd->inBuff) zbd->customMem.customFree(zbd->customMem.opaque, zbd->inBuff);
|
||||||
free(zbd->outBuff);
|
if (zbd->outBuff) zbd->customMem.customFree(zbd->customMem.opaque, zbd->outBuff);
|
||||||
free(zbd);
|
zbd->customMem.customFree(zbd->customMem.opaque, zbd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,6 +137,15 @@ size_t ZBUFF_decompressInit(ZBUFF_DCtx* zbd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* internal util function */
|
||||||
|
MEM_STATIC size_t ZBUFF_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
size_t const length = MIN(dstCapacity, srcSize);
|
||||||
|
memcpy(dst, src, length);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *** Decompression *** */
|
/* *** Decompression *** */
|
||||||
|
|
||||||
size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
||||||
@@ -166,20 +191,22 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
|||||||
if (ZSTD_isError(h2Result)) return h2Result;
|
if (ZSTD_isError(h2Result)) return h2Result;
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
zbd->fParams.windowSize = MAX(zbd->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
|
||||||
|
|
||||||
/* Frame header instruct buffer sizes */
|
/* Frame header instruct buffer sizes */
|
||||||
{ size_t const blockSize = MIN(1 << zbd->fParams.windowLog, ZSTD_BLOCKSIZE_MAX);
|
{ size_t const blockSize = MIN(zbd->fParams.windowSize, ZSTD_BLOCKSIZE_MAX);
|
||||||
zbd->blockSize = blockSize;
|
zbd->blockSize = blockSize;
|
||||||
if (zbd->inBuffSize < blockSize) {
|
if (zbd->inBuffSize < blockSize) {
|
||||||
free(zbd->inBuff);
|
zbd->customMem.customFree(zbd->customMem.opaque, zbd->inBuff);
|
||||||
zbd->inBuffSize = blockSize;
|
zbd->inBuffSize = blockSize;
|
||||||
zbd->inBuff = (char*)malloc(blockSize);
|
zbd->inBuff = (char*)zbd->customMem.customAlloc(zbd->customMem.opaque, blockSize);
|
||||||
if (zbd->inBuff == NULL) return ERROR(memory_allocation);
|
if (zbd->inBuff == NULL) return ERROR(memory_allocation);
|
||||||
}
|
}
|
||||||
{ size_t const neededOutSize = ((size_t)1 << zbd->fParams.windowLog) + blockSize;
|
{ size_t const neededOutSize = zbd->fParams.windowSize + blockSize;
|
||||||
if (zbd->outBuffSize < neededOutSize) {
|
if (zbd->outBuffSize < neededOutSize) {
|
||||||
free(zbd->outBuff);
|
zbd->customMem.customFree(zbd->customMem.opaque, zbd->outBuff);
|
||||||
zbd->outBuffSize = neededOutSize;
|
zbd->outBuffSize = neededOutSize;
|
||||||
zbd->outBuff = (char*)malloc(neededOutSize);
|
zbd->outBuff = (char*)zbd->customMem.customAlloc(zbd->customMem.opaque, neededOutSize);
|
||||||
if (zbd->outBuff == NULL) return ERROR(memory_allocation);
|
if (zbd->outBuff == NULL) return ERROR(memory_allocation);
|
||||||
} } }
|
} } }
|
||||||
zbd->stage = ZBUFFds_read;
|
zbd->stage = ZBUFFds_read;
|
||||||
@@ -192,12 +219,13 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */
|
if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */
|
||||||
|
const int isSkipFrame = ZSTD_isSkipFrame(zbd->zd);
|
||||||
size_t const decodedSize = ZSTD_decompressContinue(zbd->zd,
|
size_t const decodedSize = ZSTD_decompressContinue(zbd->zd,
|
||||||
zbd->outBuff + zbd->outStart, zbd->outBuffSize - zbd->outStart,
|
zbd->outBuff + zbd->outStart, (isSkipFrame ? 0 : zbd->outBuffSize - zbd->outStart),
|
||||||
ip, neededInSize);
|
ip, neededInSize);
|
||||||
if (ZSTD_isError(decodedSize)) return decodedSize;
|
if (ZSTD_isError(decodedSize)) return decodedSize;
|
||||||
ip += neededInSize;
|
ip += neededInSize;
|
||||||
if (!decodedSize) break; /* this was just a header */
|
if (!decodedSize && !isSkipFrame) break; /* this was just a header */
|
||||||
zbd->outEnd = zbd->outStart + decodedSize;
|
zbd->outEnd = zbd->outStart + decodedSize;
|
||||||
zbd->stage = ZBUFFds_flush;
|
zbd->stage = ZBUFFds_flush;
|
||||||
break;
|
break;
|
||||||
@@ -217,12 +245,13 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
|||||||
if (loadedSize < toLoad) { notDone = 0; break; } /* not enough input, wait for more */
|
if (loadedSize < toLoad) { notDone = 0; break; } /* not enough input, wait for more */
|
||||||
|
|
||||||
/* decode loaded input */
|
/* decode loaded input */
|
||||||
{ size_t const decodedSize = ZSTD_decompressContinue(zbd->zd,
|
{ const int isSkipFrame = ZSTD_isSkipFrame(zbd->zd);
|
||||||
|
size_t const decodedSize = ZSTD_decompressContinue(zbd->zd,
|
||||||
zbd->outBuff + zbd->outStart, zbd->outBuffSize - zbd->outStart,
|
zbd->outBuff + zbd->outStart, zbd->outBuffSize - zbd->outStart,
|
||||||
zbd->inBuff, neededInSize);
|
zbd->inBuff, neededInSize);
|
||||||
if (ZSTD_isError(decodedSize)) return decodedSize;
|
if (ZSTD_isError(decodedSize)) return decodedSize;
|
||||||
zbd->inPos = 0; /* input is consumed */
|
zbd->inPos = 0; /* input is consumed */
|
||||||
if (!decodedSize) { zbd->stage = ZBUFFds_read; break; } /* this was just a header */
|
if (!decodedSize && !isSkipFrame) { zbd->stage = ZBUFFds_read; break; } /* this was just a header */
|
||||||
zbd->outEnd = zbd->outStart + decodedSize;
|
zbd->outEnd = zbd->outStart + decodedSize;
|
||||||
zbd->stage = ZBUFFds_flush;
|
zbd->stage = ZBUFFds_flush;
|
||||||
// break; /* ZBUFFds_flush follows */
|
// break; /* ZBUFFds_flush follows */
|
||||||
@@ -250,7 +279,7 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
|
|||||||
*srcSizePtr = ip-istart;
|
*srcSizePtr = ip-istart;
|
||||||
*dstCapacityPtr = op-ostart;
|
*dstCapacityPtr = op-ostart;
|
||||||
{ size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zbd->zd);
|
{ size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zbd->zd);
|
||||||
if (nextSrcSizeHint > ZSTD_blockHeaderSize) nextSrcSizeHint+= ZSTD_blockHeaderSize; /* get following block header too */
|
// if (nextSrcSizeHint > ZSTD_blockHeaderSize) nextSrcSizeHint+= ZSTD_blockHeaderSize; /* get following block header too */
|
||||||
nextSrcSizeHint -= zbd->inPos; /* already loaded*/
|
nextSrcSizeHint -= zbd->inPos; /* already loaded*/
|
||||||
return nextSrcSizeHint;
|
return nextSrcSizeHint;
|
||||||
}
|
}
|
||||||
|
|||||||
+334
-112
@@ -53,15 +53,18 @@
|
|||||||
/*-*******************************************************
|
/*-*******************************************************
|
||||||
* Dependencies
|
* Dependencies
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
#include <stdlib.h> /* calloc */
|
#include <string.h> /* memcpy, memmove, memset */
|
||||||
#include <string.h> /* memcpy, memmove */
|
|
||||||
#include <stdio.h> /* debug only : printf */
|
#include <stdio.h> /* debug only : printf */
|
||||||
#include "mem.h" /* low level memory routines */
|
#include "mem.h" /* low level memory routines */
|
||||||
|
#define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
|
||||||
|
#include "xxhash.h" /* XXH64_* */
|
||||||
|
#define FSE_STATIC_LINKING_ONLY
|
||||||
|
#include "fse.h"
|
||||||
|
#define HUF_STATIC_LINKING_ONLY
|
||||||
|
#include "huf.h"
|
||||||
#include "zstd_internal.h"
|
#include "zstd_internal.h"
|
||||||
#include "fse_static.h"
|
|
||||||
#include "huf_static.h"
|
|
||||||
|
|
||||||
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
|
||||||
# include "zstd_legacy.h"
|
# include "zstd_legacy.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -101,25 +104,31 @@ static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
|
|||||||
* Context management
|
* Context management
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
|
typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
|
||||||
ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock } ZSTD_dStage;
|
ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock,
|
||||||
|
ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage;
|
||||||
|
|
||||||
struct ZSTD_DCtx_s
|
struct ZSTD_DCtx_s
|
||||||
{
|
{
|
||||||
FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
|
FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
|
||||||
FSE_DTable OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
|
FSE_DTable OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
|
||||||
FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
|
FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
|
||||||
unsigned hufTableX4[HUF_DTABLE_SIZE(HufLog)];
|
HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */
|
||||||
const void* previousDstEnd;
|
const void* previousDstEnd;
|
||||||
const void* base;
|
const void* base;
|
||||||
const void* vBase;
|
const void* vBase;
|
||||||
const void* dictEnd;
|
const void* dictEnd;
|
||||||
size_t expected;
|
size_t expected;
|
||||||
size_t headerSize;
|
U32 rep[3];
|
||||||
ZSTD_frameParams fParams;
|
ZSTD_frameParams fParams;
|
||||||
blockType_t bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
|
blockType_t bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
|
||||||
ZSTD_dStage stage;
|
ZSTD_dStage stage;
|
||||||
U32 flagRepeatTable;
|
U32 litEntropy;
|
||||||
|
U32 fseEntropy;
|
||||||
|
XXH64_state_t xxhState;
|
||||||
|
size_t headerSize;
|
||||||
|
U32 dictID;
|
||||||
const BYTE* litPtr;
|
const BYTE* litPtr;
|
||||||
|
ZSTD_customMem customMem;
|
||||||
size_t litBufSize;
|
size_t litBufSize;
|
||||||
size_t litSize;
|
size_t litSize;
|
||||||
BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH];
|
BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH];
|
||||||
@@ -136,22 +145,39 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
|
|||||||
dctx->base = NULL;
|
dctx->base = NULL;
|
||||||
dctx->vBase = NULL;
|
dctx->vBase = NULL;
|
||||||
dctx->dictEnd = NULL;
|
dctx->dictEnd = NULL;
|
||||||
dctx->hufTableX4[0] = HufLog;
|
dctx->hufTable[0] = (HUF_DTable)((HufLog)*0x1000001);
|
||||||
dctx->flagRepeatTable = 0;
|
dctx->litEntropy = dctx->fseEntropy = 0;
|
||||||
|
dctx->dictID = 0;
|
||||||
|
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->rep[i] = repStartValue[i]; }
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZSTD_DCtx* ZSTD_createDCtx(void)
|
ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
|
||||||
{
|
{
|
||||||
ZSTD_DCtx* dctx = (ZSTD_DCtx*)malloc(sizeof(ZSTD_DCtx));
|
ZSTD_DCtx* dctx;
|
||||||
if (dctx==NULL) return NULL;
|
|
||||||
|
if (!customMem.customAlloc && !customMem.customFree)
|
||||||
|
customMem = defaultCustomMem;
|
||||||
|
|
||||||
|
if (!customMem.customAlloc || !customMem.customFree)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dctx = (ZSTD_DCtx*) customMem.customAlloc(customMem.opaque, sizeof(ZSTD_DCtx));
|
||||||
|
if (!dctx) return NULL;
|
||||||
|
memcpy(&dctx->customMem, &customMem, sizeof(ZSTD_customMem));
|
||||||
ZSTD_decompressBegin(dctx);
|
ZSTD_decompressBegin(dctx);
|
||||||
return dctx;
|
return dctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZSTD_DCtx* ZSTD_createDCtx(void)
|
||||||
|
{
|
||||||
|
return ZSTD_createDCtx_advanced(defaultCustomMem);
|
||||||
|
}
|
||||||
|
|
||||||
size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
|
size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
|
||||||
{
|
{
|
||||||
free(dctx);
|
if (dctx==NULL) return 0; /* support free on NULL */
|
||||||
|
dctx->customMem.customFree(dctx->customMem.opaque, dctx);
|
||||||
return 0; /* reserved as a potential error code in the future */
|
return 0; /* reserved as a potential error code in the future */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,17 +209,44 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
|
|||||||
|
|
||||||
/* Frame descriptor
|
/* Frame descriptor
|
||||||
|
|
||||||
1 byte, using :
|
// old
|
||||||
|
1 byte - Alloc :
|
||||||
bit 0-3 : windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN (see zstd_internal.h)
|
bit 0-3 : windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN (see zstd_internal.h)
|
||||||
bit 4 : minmatch 4(0) or 3(1)
|
bit 4 : reserved for windowLog (must be zero)
|
||||||
bit 5 : reserved (must be zero)
|
bit 5 : reserved (must be zero)
|
||||||
bit 6-7 : Frame content size : unknown, 1 byte, 2 bytes, 8 bytes
|
bit 6-7 : Frame content size : unknown, 1 byte, 2 bytes, 8 bytes
|
||||||
|
|
||||||
Optional : content size (0, 1, 2 or 8 bytes)
|
1 byte - checker :
|
||||||
0 : unknown
|
bit 0-1 : dictID (0, 1, 2 or 4 bytes)
|
||||||
1 : 0-255 bytes
|
bit 2-7 : reserved (must be zero)
|
||||||
2 : 256 - 65535+256
|
|
||||||
8 : up to 16 exa
|
// new
|
||||||
|
1 byte - FrameHeaderDescription :
|
||||||
|
bit 0-1 : dictID (0, 1, 2 or 4 bytes)
|
||||||
|
bit 2 : checksumFlag
|
||||||
|
bit 3 : reserved (must be zero)
|
||||||
|
bit 4 : reserved (unused, can be any value)
|
||||||
|
bit 5 : Single Segment (if 1, WindowLog byte is not present)
|
||||||
|
bit 6-7 : FrameContentFieldSize (0, 2, 4, or 8)
|
||||||
|
if (SkippedWindowLog && !FrameContentFieldsize) FrameContentFieldsize=1;
|
||||||
|
|
||||||
|
Optional : WindowLog (0 or 1 byte)
|
||||||
|
bit 0-2 : octal Fractional (1/8th)
|
||||||
|
bit 3-7 : Power of 2, with 0 = 1 KB (up to 2 TB)
|
||||||
|
|
||||||
|
Optional : dictID (0, 1, 2 or 4 bytes)
|
||||||
|
Automatic adaptation
|
||||||
|
0 : no dictID
|
||||||
|
1 : 1 - 255
|
||||||
|
2 : 256 - 65535
|
||||||
|
4 : all other values
|
||||||
|
|
||||||
|
Optional : content size (0, 1, 2, 4 or 8 bytes)
|
||||||
|
0 : unknown (fcfs==0 and swl==0)
|
||||||
|
1 : 0-255 bytes (fcfs==0 and swl==1)
|
||||||
|
2 : 256 - 65535+256 (fcfs==1)
|
||||||
|
4 : 0 - 4GB-1 (fcfs==2)
|
||||||
|
8 : 0 - 16EB-1 (fcfs==3)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -269,13 +322,18 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
|
|||||||
static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
|
static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
if (srcSize < ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong);
|
if (srcSize < ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong);
|
||||||
{ U32 const fcsId = (((const BYTE*)src)[4]) >> 6;
|
{ BYTE const fhd = ((const BYTE*)src)[4];
|
||||||
return ZSTD_frameHeaderSize_min + ZSTD_fcs_fieldSize[fcsId]; }
|
U32 const dictID= fhd & 3;
|
||||||
|
U32 const directMode = (fhd >> 5) & 1;
|
||||||
|
U32 const fcsId = fhd >> 6;
|
||||||
|
return ZSTD_frameHeaderSize_min + !directMode + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
|
||||||
|
+ (directMode && !ZSTD_fcs_fieldSize[fcsId]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** ZSTD_getFrameParams() :
|
/** ZSTD_getFrameParams() :
|
||||||
* decode Frame Header, or provide expected `srcSize`.
|
* decode Frame Header, or require larger `srcSize`.
|
||||||
* @return : 0, `fparamsPtr` is correctly filled,
|
* @return : 0, `fparamsPtr` is correctly filled,
|
||||||
* >0, `srcSize` is too small, result is expected `srcSize`,
|
* >0, `srcSize` is too small, result is expected `srcSize`,
|
||||||
* or an error code, which can be tested using ZSTD_isError() */
|
* or an error code, which can be tested using ZSTD_isError() */
|
||||||
@@ -284,24 +342,63 @@ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t
|
|||||||
const BYTE* ip = (const BYTE*)src;
|
const BYTE* ip = (const BYTE*)src;
|
||||||
|
|
||||||
if (srcSize < ZSTD_frameHeaderSize_min) return ZSTD_frameHeaderSize_min;
|
if (srcSize < ZSTD_frameHeaderSize_min) return ZSTD_frameHeaderSize_min;
|
||||||
if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
|
if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) {
|
||||||
|
if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
|
||||||
|
if (srcSize < ZSTD_skippableHeaderSize) return ZSTD_skippableHeaderSize; /* magic number + skippable frame length */
|
||||||
|
memset(fparamsPtr, 0, sizeof(*fparamsPtr));
|
||||||
|
fparamsPtr->frameContentSize = MEM_readLE32((const char *)src + 4);
|
||||||
|
fparamsPtr->windowSize = 0; /* windowSize==0 means a frame is skippable */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ERROR(prefix_unknown);
|
||||||
|
}
|
||||||
|
|
||||||
/* ensure there is enough `srcSize` to fully read/decode frame header */
|
/* ensure there is enough `srcSize` to fully read/decode frame header */
|
||||||
{ size_t const fhsize = ZSTD_frameHeaderSize(src, srcSize);
|
{ size_t const fhsize = ZSTD_frameHeaderSize(src, srcSize);
|
||||||
if (srcSize < fhsize) return fhsize; }
|
if (srcSize < fhsize) return fhsize; }
|
||||||
|
|
||||||
memset(fparamsPtr, 0, sizeof(*fparamsPtr));
|
{ BYTE const fhdByte = ip[4];
|
||||||
{ BYTE const frameDesc = ip[4];
|
size_t pos = 5;
|
||||||
fparamsPtr->windowLog = (frameDesc & 0xF) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
|
U32 const dictIDSizeCode = fhdByte&3;
|
||||||
if ((frameDesc & 0x20) != 0) return ERROR(frameParameter_unsupported); /* reserved 1 bit */
|
U32 const checksumFlag = (fhdByte>>2)&1;
|
||||||
switch(frameDesc >> 6) /* fcsId */
|
U32 const directMode = (fhdByte>>5)&1;
|
||||||
|
U32 const fcsID = fhdByte>>6;
|
||||||
|
U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX;
|
||||||
|
U32 windowSize = 0;
|
||||||
|
U32 dictID = 0;
|
||||||
|
U64 frameContentSize = 0;
|
||||||
|
if ((fhdByte & 0x08) != 0) return ERROR(frameParameter_unsupported); /* reserved bits, which must be zero */
|
||||||
|
if (!directMode) {
|
||||||
|
BYTE const wlByte = ip[pos++];
|
||||||
|
U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
|
||||||
|
if (windowLog > ZSTD_WINDOWLOG_MAX) return ERROR(frameParameter_unsupported);
|
||||||
|
windowSize = (1U << windowLog);
|
||||||
|
windowSize += (windowSize >> 3) * (wlByte&7);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(dictIDSizeCode)
|
||||||
{
|
{
|
||||||
default: /* impossible */
|
default: /* impossible */
|
||||||
case 0 : fparamsPtr->frameContentSize = 0; break;
|
case 0 : break;
|
||||||
case 1 : fparamsPtr->frameContentSize = ip[5]; break;
|
case 1 : dictID = ip[pos]; pos++; break;
|
||||||
case 2 : fparamsPtr->frameContentSize = MEM_readLE16(ip+5)+256; break;
|
case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break;
|
||||||
case 3 : fparamsPtr->frameContentSize = MEM_readLE64(ip+5); break;
|
case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break;
|
||||||
} }
|
}
|
||||||
|
switch(fcsID)
|
||||||
|
{
|
||||||
|
default: /* impossible */
|
||||||
|
case 0 : if (directMode) frameContentSize = ip[pos]; break;
|
||||||
|
case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
|
||||||
|
case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
|
||||||
|
case 3 : frameContentSize = MEM_readLE64(ip+pos); break;
|
||||||
|
}
|
||||||
|
if (!windowSize) windowSize = (U32)frameContentSize;
|
||||||
|
if (windowSize > windowSizeMax) return ERROR(frameParameter_unsupported);
|
||||||
|
fparamsPtr->frameContentSize = frameContentSize;
|
||||||
|
fparamsPtr->windowSize = windowSize;
|
||||||
|
fparamsPtr->dictID = dictID;
|
||||||
|
fparamsPtr->checksumFlag = checksumFlag;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,10 +406,11 @@ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t
|
|||||||
/** ZSTD_decodeFrameHeader() :
|
/** ZSTD_decodeFrameHeader() :
|
||||||
* `srcSize` must be the size provided by ZSTD_frameHeaderSize().
|
* `srcSize` must be the size provided by ZSTD_frameHeaderSize().
|
||||||
* @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
|
* @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
|
||||||
static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* zc, const void* src, size_t srcSize)
|
static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
size_t const result = ZSTD_getFrameParams(&(zc->fParams), src, srcSize);
|
size_t const result = ZSTD_getFrameParams(&(dctx->fParams), src, srcSize);
|
||||||
if ((MEM_32bits()) && (zc->fParams.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bits);
|
if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID)) return ERROR(dictionary_wrong);
|
||||||
|
if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,13 +454,14 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|||||||
const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
|
const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
|
||||||
{
|
{
|
||||||
const BYTE* const istart = (const BYTE*) src;
|
const BYTE* const istart = (const BYTE*) src;
|
||||||
|
litBlockType_t lbt;
|
||||||
|
|
||||||
/* any compressed block with literals segment must be at least this size */
|
|
||||||
if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
|
if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
|
||||||
|
lbt = (litBlockType_t)(istart[0]>> 6);
|
||||||
|
|
||||||
switch(istart[0]>> 6)
|
switch(lbt)
|
||||||
{
|
{
|
||||||
case IS_HUF:
|
case lbt_huffman:
|
||||||
{ size_t litSize, litCSize, singleStream=0;
|
{ size_t litSize, litCSize, singleStream=0;
|
||||||
U32 lhSize = ((istart[0]) >> 4) & 3;
|
U32 lhSize = ((istart[0]) >> 4) & 3;
|
||||||
if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for lhSize, + cSize (+nbSeq) */
|
if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for lhSize, + cSize (+nbSeq) */
|
||||||
@@ -392,29 +491,31 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|||||||
if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
|
if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
|
||||||
|
|
||||||
if (HUF_isError(singleStream ?
|
if (HUF_isError(singleStream ?
|
||||||
HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
|
HUF_decompress1X2_DCtx(dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) :
|
||||||
HUF_decompress (dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
|
HUF_decompress4X_hufOnly (dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
|
||||||
return ERROR(corruption_detected);
|
return ERROR(corruption_detected);
|
||||||
|
|
||||||
dctx->litPtr = dctx->litBuffer;
|
dctx->litPtr = dctx->litBuffer;
|
||||||
dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+8;
|
dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+8;
|
||||||
dctx->litSize = litSize;
|
dctx->litSize = litSize;
|
||||||
|
dctx->litEntropy = 1;
|
||||||
return litCSize + lhSize;
|
return litCSize + lhSize;
|
||||||
}
|
}
|
||||||
case IS_PCH:
|
case lbt_repeat:
|
||||||
{ size_t litSize, litCSize;
|
{ size_t litSize, litCSize;
|
||||||
U32 lhSize = ((istart[0]) >> 4) & 3;
|
U32 lhSize = ((istart[0]) >> 4) & 3;
|
||||||
if (lhSize != 1) /* only case supported for now : small litSize, single stream */
|
if (lhSize != 1) /* only case supported for now : small litSize, single stream */
|
||||||
return ERROR(corruption_detected);
|
return ERROR(corruption_detected);
|
||||||
if (!dctx->flagRepeatTable)
|
if (dctx->litEntropy==0)
|
||||||
return ERROR(dictionary_corrupted);
|
return ERROR(dictionary_corrupted);
|
||||||
|
|
||||||
/* 2 - 2 - 10 - 10 */
|
/* 2 - 2 - 10 - 10 */
|
||||||
lhSize=3;
|
lhSize=3;
|
||||||
litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
|
litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
|
||||||
litCSize = ((istart[1] & 3) << 8) + istart[2];
|
litCSize = ((istart[1] & 3) << 8) + istart[2];
|
||||||
|
if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
|
||||||
|
|
||||||
{ size_t const errorCode = HUF_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
|
{ size_t const errorCode = HUF_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTable);
|
||||||
if (HUF_isError(errorCode)) return ERROR(corruption_detected);
|
if (HUF_isError(errorCode)) return ERROR(corruption_detected);
|
||||||
}
|
}
|
||||||
dctx->litPtr = dctx->litBuffer;
|
dctx->litPtr = dctx->litBuffer;
|
||||||
@@ -422,7 +523,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|||||||
dctx->litSize = litSize;
|
dctx->litSize = litSize;
|
||||||
return litCSize + lhSize;
|
return litCSize + lhSize;
|
||||||
}
|
}
|
||||||
case IS_RAW:
|
case lbt_raw:
|
||||||
{ size_t litSize;
|
{ size_t litSize;
|
||||||
U32 lhSize = ((istart[0]) >> 4) & 3;
|
U32 lhSize = ((istart[0]) >> 4) & 3;
|
||||||
switch(lhSize)
|
switch(lhSize)
|
||||||
@@ -453,7 +554,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|||||||
dctx->litSize = litSize;
|
dctx->litSize = litSize;
|
||||||
return lhSize+litSize;
|
return lhSize+litSize;
|
||||||
}
|
}
|
||||||
case IS_RLE:
|
case lbt_rle:
|
||||||
{ size_t litSize;
|
{ size_t litSize;
|
||||||
U32 lhSize = ((istart[0]) >> 4) & 3;
|
U32 lhSize = ((istart[0]) >> 4) & 3;
|
||||||
switch(lhSize)
|
switch(lhSize)
|
||||||
@@ -582,10 +683,10 @@ typedef struct {
|
|||||||
} seqState_t;
|
} seqState_t;
|
||||||
|
|
||||||
|
|
||||||
|
static seq_t ZSTD_decodeSequence(seqState_t* seqState)
|
||||||
static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
|
|
||||||
{
|
{
|
||||||
/* Literal length */
|
seq_t seq;
|
||||||
|
|
||||||
U32 const llCode = FSE_peekSymbol(&(seqState->stateLL));
|
U32 const llCode = FSE_peekSymbol(&(seqState->stateLL));
|
||||||
U32 const mlCode = FSE_peekSymbol(&(seqState->stateML));
|
U32 const mlCode = FSE_peekSymbol(&(seqState->stateML));
|
||||||
U32 const ofCode = FSE_peekSymbol(&(seqState->stateOffb)); /* <= maxOff, by table construction */
|
U32 const ofCode = FSE_peekSymbol(&(seqState->stateOffb)); /* <= maxOff, by table construction */
|
||||||
@@ -641,13 +742,13 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
|
|||||||
seqState->prevOffset[1] = seqState->prevOffset[0];
|
seqState->prevOffset[1] = seqState->prevOffset[0];
|
||||||
seqState->prevOffset[0] = offset;
|
seqState->prevOffset[0] = offset;
|
||||||
}
|
}
|
||||||
seq->offset = offset;
|
seq.offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
seq->matchLength = ML_base[mlCode] + MINMATCH + ((mlCode>31) ? BIT_readBits(&(seqState->DStream), mlBits) : 0); /* <= 16 bits */
|
seq.matchLength = ML_base[mlCode] + MINMATCH + ((mlCode>31) ? BIT_readBits(&(seqState->DStream), mlBits) : 0); /* <= 16 bits */
|
||||||
if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&(seqState->DStream));
|
if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&(seqState->DStream));
|
||||||
|
|
||||||
seq->litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBits(&(seqState->DStream), llBits) : 0); /* <= 16 bits */
|
seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBits(&(seqState->DStream), llBits) : 0); /* <= 16 bits */
|
||||||
if (MEM_32bits() ||
|
if (MEM_32bits() ||
|
||||||
(totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&(seqState->DStream));
|
(totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&(seqState->DStream));
|
||||||
|
|
||||||
@@ -656,6 +757,8 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
|
|||||||
FSE_updateState(&(seqState->stateML), &(seqState->DStream)); /* <= 9 bits */
|
FSE_updateState(&(seqState->stateML), &(seqState->DStream)); /* <= 9 bits */
|
||||||
if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); /* <= 18 bits */
|
if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); /* <= 18 bits */
|
||||||
FSE_updateState(&(seqState->stateOffb), &(seqState->DStream)); /* <= 8 bits */
|
FSE_updateState(&(seqState->stateOffb), &(seqState->DStream)); /* <= 8 bits */
|
||||||
|
|
||||||
|
return seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -753,20 +856,16 @@ static size_t ZSTD_decompressSequences(
|
|||||||
int nbSeq;
|
int nbSeq;
|
||||||
|
|
||||||
/* Build Decoding Tables */
|
/* Build Decoding Tables */
|
||||||
{ size_t const seqHSize = ZSTD_decodeSeqHeaders(&nbSeq, DTableLL, DTableML, DTableOffb, dctx->flagRepeatTable, ip, seqSize);
|
{ size_t const seqHSize = ZSTD_decodeSeqHeaders(&nbSeq, DTableLL, DTableML, DTableOffb, dctx->fseEntropy, ip, seqSize);
|
||||||
if (ZSTD_isError(seqHSize)) return seqHSize;
|
if (ZSTD_isError(seqHSize)) return seqHSize;
|
||||||
ip += seqHSize;
|
ip += seqHSize;
|
||||||
dctx->flagRepeatTable = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Regen sequences */
|
/* Regen sequences */
|
||||||
if (nbSeq) {
|
if (nbSeq) {
|
||||||
seq_t sequence;
|
|
||||||
seqState_t seqState;
|
seqState_t seqState;
|
||||||
|
dctx->fseEntropy = 1;
|
||||||
memset(&sequence, 0, sizeof(sequence));
|
{ U32 i; for (i=0; i<ZSTD_REP_INIT; i++) seqState.prevOffset[i] = dctx->rep[i]; }
|
||||||
sequence.offset = REPCODE_STARTVALUE;
|
|
||||||
{ U32 i; for (i=0; i<ZSTD_REP_INIT; i++) seqState.prevOffset[i] = REPCODE_STARTVALUE; }
|
|
||||||
{ size_t const errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
|
{ size_t const errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
|
||||||
if (ERR_isError(errorCode)) return ERROR(corruption_detected); }
|
if (ERR_isError(errorCode)) return ERROR(corruption_detected); }
|
||||||
FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
|
FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
|
||||||
@@ -775,24 +874,16 @@ static size_t ZSTD_decompressSequences(
|
|||||||
|
|
||||||
for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
|
for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
|
||||||
nbSeq--;
|
nbSeq--;
|
||||||
ZSTD_decodeSequence(&sequence, &seqState);
|
{ seq_t const sequence = ZSTD_decodeSequence(&seqState);
|
||||||
|
size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
|
||||||
#if 0 /* debug */
|
|
||||||
static BYTE* start = NULL;
|
|
||||||
if (start==NULL) start = op;
|
|
||||||
size_t pos = (size_t)(op-start);
|
|
||||||
if ((pos >= 5810037) && (pos < 5810400))
|
|
||||||
printf("Dpos %6u :%5u literals & match %3u bytes at distance %6u \n",
|
|
||||||
pos, (U32)sequence.litLength, (U32)sequence.matchLength, (U32)sequence.offset);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{ size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
|
|
||||||
if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
|
if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
|
||||||
op += oneSeqSize;
|
op += oneSeqSize;
|
||||||
} }
|
} }
|
||||||
|
|
||||||
/* check if reached exact end */
|
/* check if reached exact end */
|
||||||
if (nbSeq) return ERROR(corruption_detected);
|
if (nbSeq) return ERROR(corruption_detected);
|
||||||
|
/* save reps for next block */
|
||||||
|
{ U32 i; for (i=0; i<ZSTD_REP_INIT; i++) dctx->rep[i] = (U32)(seqState.prevOffset[i]); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* last literal segment */
|
/* last literal segment */
|
||||||
@@ -845,6 +936,14 @@ size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t ZSTD_generateNxByte(void* dst, size_t dstCapacity, BYTE byte, size_t length)
|
||||||
|
{
|
||||||
|
if (length > dstCapacity) return ERROR(dstSize_tooSmall);
|
||||||
|
memset(dst, byte, length);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! ZSTD_decompressFrame() :
|
/*! ZSTD_decompressFrame() :
|
||||||
* `dctx` must be properly initialized */
|
* `dctx` must be properly initialized */
|
||||||
static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
||||||
@@ -854,10 +953,9 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|||||||
const BYTE* ip = (const BYTE*)src;
|
const BYTE* ip = (const BYTE*)src;
|
||||||
const BYTE* const iend = ip + srcSize;
|
const BYTE* const iend = ip + srcSize;
|
||||||
BYTE* const ostart = (BYTE* const)dst;
|
BYTE* const ostart = (BYTE* const)dst;
|
||||||
BYTE* op = ostart;
|
|
||||||
BYTE* const oend = ostart + dstCapacity;
|
BYTE* const oend = ostart + dstCapacity;
|
||||||
|
BYTE* op = ostart;
|
||||||
size_t remainingSize = srcSize;
|
size_t remainingSize = srcSize;
|
||||||
blockProperties_t blockProperties = { bt_compressed, 0 };
|
|
||||||
|
|
||||||
/* check */
|
/* check */
|
||||||
if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
|
if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
|
||||||
@@ -872,7 +970,8 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|||||||
|
|
||||||
/* Loop on each block */
|
/* Loop on each block */
|
||||||
while (1) {
|
while (1) {
|
||||||
size_t decodedSize=0;
|
size_t decodedSize;
|
||||||
|
blockProperties_t blockProperties;
|
||||||
size_t const cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
|
size_t const cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
|
||||||
if (ZSTD_isError(cBlockSize)) return cBlockSize;
|
if (ZSTD_isError(cBlockSize)) return cBlockSize;
|
||||||
|
|
||||||
@@ -889,11 +988,12 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|||||||
decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
|
decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
|
||||||
break;
|
break;
|
||||||
case bt_rle :
|
case bt_rle :
|
||||||
return ERROR(GENERIC); /* not yet supported */
|
decodedSize = ZSTD_generateNxByte(op, oend-op, *ip, blockProperties.origSize);
|
||||||
break;
|
break;
|
||||||
case bt_end :
|
case bt_end :
|
||||||
/* end of frame */
|
/* end of frame */
|
||||||
if (remainingSize) return ERROR(srcSize_wrong);
|
if (remainingSize) return ERROR(srcSize_wrong);
|
||||||
|
decodedSize = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ERROR(GENERIC); /* impossible */
|
return ERROR(GENERIC); /* impossible */
|
||||||
@@ -901,6 +1001,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|||||||
if (cBlockSize == 0) break; /* bt_end */
|
if (cBlockSize == 0) break; /* bt_end */
|
||||||
|
|
||||||
if (ZSTD_isError(decodedSize)) return decodedSize;
|
if (ZSTD_isError(decodedSize)) return decodedSize;
|
||||||
|
if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, op, decodedSize);
|
||||||
op += decodedSize;
|
op += decodedSize;
|
||||||
ip += cBlockSize;
|
ip += cBlockSize;
|
||||||
remainingSize -= cBlockSize;
|
remainingSize -= cBlockSize;
|
||||||
@@ -910,6 +1011,11 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! ZSTD_decompress_usingPreparedDCtx() :
|
||||||
|
* Same as ZSTD_decompress_usingDict, but using a reference context `preparedDCtx`, where dictionary has been loaded.
|
||||||
|
* It avoids reloading the dictionary each time.
|
||||||
|
* `preparedDCtx` must have been properly initialized using ZSTD_decompressBegin_usingDict().
|
||||||
|
* Requires 2 contexts : 1 for reference (preparedDCtx), which will not be modified, and 1 to run the decompression operation (dctx) */
|
||||||
size_t ZSTD_decompress_usingPreparedDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* refDCtx,
|
size_t ZSTD_decompress_usingPreparedDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* refDCtx,
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t srcSize)
|
const void* src, size_t srcSize)
|
||||||
@@ -926,7 +1032,7 @@ size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
|
|||||||
const void* dict, size_t dictSize)
|
const void* dict, size_t dictSize)
|
||||||
{
|
{
|
||||||
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
||||||
{ const U32 magicNumber = MEM_readLE32(src);
|
{ U32 const magicNumber = MEM_readLE32(src);
|
||||||
if (ZSTD_isLegacy(magicNumber))
|
if (ZSTD_isLegacy(magicNumber))
|
||||||
return ZSTD_decompressLegacy(dst, dstCapacity, src, srcSize, dict, dictSize, magicNumber);
|
return ZSTD_decompressLegacy(dst, dstCapacity, src, srcSize, dict, dictSize, magicNumber);
|
||||||
}
|
}
|
||||||
@@ -947,7 +1053,7 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
|
|||||||
{
|
{
|
||||||
#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
|
#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
|
||||||
size_t regenSize;
|
size_t regenSize;
|
||||||
ZSTD_DCtx* dctx = ZSTD_createDCtx();
|
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
|
||||||
if (dctx==NULL) return ERROR(memory_allocation);
|
if (dctx==NULL) return ERROR(memory_allocation);
|
||||||
regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize);
|
regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize);
|
||||||
ZSTD_freeDCtx(dctx);
|
ZSTD_freeDCtx(dctx);
|
||||||
@@ -967,17 +1073,30 @@ size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
|
|||||||
return dctx->expected;
|
return dctx->expected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ZSTD_isSkipFrame(ZSTD_DCtx* dctx)
|
||||||
|
{
|
||||||
|
return dctx->stage == ZSTDds_skipFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ZSTD_decompressContinue() :
|
||||||
|
* @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity)
|
||||||
|
* or an error code, which can be tested using ZSTD_isError() */
|
||||||
size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
|
if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
|
||||||
if (dstCapacity) ZSTD_checkContinuity(dctx, dst);
|
if (dstCapacity) ZSTD_checkContinuity(dctx, dst);
|
||||||
|
|
||||||
/* Decompress : frame header; part 1 */
|
|
||||||
switch (dctx->stage)
|
switch (dctx->stage)
|
||||||
{
|
{
|
||||||
case ZSTDds_getFrameHeaderSize :
|
case ZSTDds_getFrameHeaderSize :
|
||||||
if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
|
if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
|
||||||
|
if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
|
||||||
|
memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
|
||||||
|
dctx->expected = ZSTD_skippableHeaderSize - ZSTD_frameHeaderSize_min; /* magic number + skippable frame length */
|
||||||
|
dctx->stage = ZSTDds_decodeSkippableHeader;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
|
dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
|
||||||
if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
|
if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
|
||||||
memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
|
memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
|
||||||
@@ -1002,6 +1121,13 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|||||||
size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
|
size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
|
||||||
if (ZSTD_isError(cBlockSize)) return cBlockSize;
|
if (ZSTD_isError(cBlockSize)) return cBlockSize;
|
||||||
if (bp.blockType == bt_end) {
|
if (bp.blockType == bt_end) {
|
||||||
|
if (dctx->fParams.checksumFlag) {
|
||||||
|
U64 const h64 = XXH64_digest(&dctx->xxhState);
|
||||||
|
U32 const h32 = (U32)(h64>>11) & ((1<<22)-1);
|
||||||
|
const BYTE* const ip = (const BYTE*)src;
|
||||||
|
U32 const check32 = ip[2] + (ip[1] << 8) + ((ip[0] & 0x3F) << 16);
|
||||||
|
if (check32 != h32) return ERROR(checksum_wrong);
|
||||||
|
}
|
||||||
dctx->expected = 0;
|
dctx->expected = 0;
|
||||||
dctx->stage = ZSTDds_getFrameHeaderSize;
|
dctx->stage = ZSTDds_getFrameHeaderSize;
|
||||||
} else {
|
} else {
|
||||||
@@ -1033,8 +1159,21 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|||||||
dctx->stage = ZSTDds_decodeBlockHeader;
|
dctx->stage = ZSTDds_decodeBlockHeader;
|
||||||
dctx->expected = ZSTD_blockHeaderSize;
|
dctx->expected = ZSTD_blockHeaderSize;
|
||||||
dctx->previousDstEnd = (char*)dst + rSize;
|
dctx->previousDstEnd = (char*)dst + rSize;
|
||||||
|
if (ZSTD_isError(rSize)) return rSize;
|
||||||
|
if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);
|
||||||
return rSize;
|
return rSize;
|
||||||
}
|
}
|
||||||
|
case ZSTDds_decodeSkippableHeader:
|
||||||
|
{ memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
|
||||||
|
dctx->expected = MEM_readLE32(dctx->headerBuffer + 4);
|
||||||
|
dctx->stage = ZSTDds_skipFrame;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case ZSTDds_skipFrame:
|
||||||
|
{ dctx->expected = 0;
|
||||||
|
dctx->stage = ZSTDds_getFrameHeaderSize;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return ERROR(GENERIC); /* impossible */
|
return ERROR(GENERIC); /* impossible */
|
||||||
}
|
}
|
||||||
@@ -1049,68 +1188,78 @@ static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSi
|
|||||||
dctx->previousDstEnd = (const char*)dict + dictSize;
|
dctx->previousDstEnd = (const char*)dict + dictSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
|
static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* const dict, size_t const dictSize)
|
||||||
{
|
{
|
||||||
size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, litlengthHeaderSize;
|
const BYTE* dictPtr = (const BYTE*)dict;
|
||||||
|
const BYTE* const dictEnd = dictPtr + dictSize;
|
||||||
|
|
||||||
hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
|
{ size_t const hSize = HUF_readDTableX4(dctx->hufTable, dict, dictSize);
|
||||||
if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
|
if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
|
||||||
dict = (const char*)dict + hSize;
|
dictPtr += hSize;
|
||||||
dictSize -= hSize;
|
}
|
||||||
|
|
||||||
{ short offcodeNCount[MaxOff+1];
|
{ short offcodeNCount[MaxOff+1];
|
||||||
U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
|
U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
|
||||||
offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
|
size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
|
||||||
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
{ size_t const errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
|
{ size_t const errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
|
||||||
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
dict = (const char*)dict + offcodeHeaderSize;
|
dictPtr += offcodeHeaderSize;
|
||||||
dictSize -= offcodeHeaderSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{ short matchlengthNCount[MaxML+1];
|
{ short matchlengthNCount[MaxML+1];
|
||||||
unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
|
unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
|
||||||
matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
|
size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
|
||||||
if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
{ size_t const errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
|
{ size_t const errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
|
||||||
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
dict = (const char*)dict + matchlengthHeaderSize;
|
dictPtr += matchlengthHeaderSize;
|
||||||
dictSize -= matchlengthHeaderSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{ short litlengthNCount[MaxLL+1];
|
{ short litlengthNCount[MaxLL+1];
|
||||||
unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
|
unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
|
||||||
litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
|
size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
|
||||||
if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
{ size_t const errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
|
{ size_t const errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
|
||||||
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
|
dictPtr += litlengthHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
dctx->flagRepeatTable = 1;
|
if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
|
||||||
return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
|
dctx->rep[0] = MEM_readLE32(dictPtr+0); if (dctx->rep[0] >= dictSize) return ERROR(dictionary_corrupted);
|
||||||
|
dctx->rep[1] = MEM_readLE32(dictPtr+4); if (dctx->rep[1] >= dictSize) return ERROR(dictionary_corrupted);
|
||||||
|
dctx->rep[2] = MEM_readLE32(dictPtr+8); if (dctx->rep[2] >= dictSize) return ERROR(dictionary_corrupted);
|
||||||
|
dictPtr += 12;
|
||||||
|
|
||||||
|
dctx->litEntropy = dctx->fseEntropy = 1;
|
||||||
|
return dictPtr - (const BYTE*)dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
|
static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
|
||||||
{
|
{
|
||||||
size_t eSize;
|
if (dictSize < 8) return ERROR(dictionary_corrupted);
|
||||||
U32 const magic = MEM_readLE32(dict);
|
{ U32 const magic = MEM_readLE32(dict);
|
||||||
if (magic != ZSTD_DICT_MAGIC) {
|
if (magic != ZSTD_DICT_MAGIC) {
|
||||||
/* pure content mode */
|
/* pure content mode */
|
||||||
|
ZSTD_refDictContent(dctx, dict, dictSize);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dctx->dictID = MEM_readLE32((const char*)dict + 4);
|
||||||
|
|
||||||
|
/* load entropy tables */
|
||||||
|
dict = (const char*)dict + 8;
|
||||||
|
dictSize -= 8;
|
||||||
|
{ size_t const eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
|
||||||
|
if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
|
||||||
|
dict = (const char*)dict + eSize;
|
||||||
|
dictSize -= eSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reference dictionary content */
|
||||||
ZSTD_refDictContent(dctx, dict, dictSize);
|
ZSTD_refDictContent(dctx, dict, dictSize);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* load entropy tables */
|
|
||||||
dict = (const char*)dict + 4;
|
|
||||||
dictSize -= 4;
|
|
||||||
eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
|
|
||||||
if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
|
|
||||||
|
|
||||||
/* reference dictionary content */
|
|
||||||
dict = (const char*)dict + eSize;
|
|
||||||
dictSize -= eSize;
|
|
||||||
ZSTD_refDictContent(dctx, dict, dictSize);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1127,3 +1276,76 @@ size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct ZSTD_DDict_s {
|
||||||
|
void* dictContent;
|
||||||
|
size_t dictContentSize;
|
||||||
|
ZSTD_DCtx* refContext;
|
||||||
|
}; /* typedef'd tp ZSTD_CDict within zstd.h */
|
||||||
|
|
||||||
|
ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, ZSTD_customMem customMem)
|
||||||
|
{
|
||||||
|
if (!customMem.customAlloc && !customMem.customFree)
|
||||||
|
customMem = defaultCustomMem;
|
||||||
|
|
||||||
|
if (!customMem.customAlloc || !customMem.customFree)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
{ ZSTD_DDict* const ddict = (ZSTD_DDict*) customMem.customAlloc(customMem.opaque, sizeof(*ddict));
|
||||||
|
void* const dictContent = customMem.customAlloc(customMem.opaque, dictSize);
|
||||||
|
ZSTD_DCtx* const dctx = ZSTD_createDCtx_advanced(customMem);
|
||||||
|
|
||||||
|
if (!dictContent || !ddict || !dctx) {
|
||||||
|
customMem.customFree(customMem.opaque, dictContent);
|
||||||
|
customMem.customFree(customMem.opaque, ddict);
|
||||||
|
customMem.customFree(customMem.opaque, dctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(dictContent, dict, dictSize);
|
||||||
|
{ size_t const errorCode = ZSTD_decompressBegin_usingDict(dctx, dictContent, dictSize);
|
||||||
|
if (ZSTD_isError(errorCode)) {
|
||||||
|
customMem.customFree(customMem.opaque, dictContent);
|
||||||
|
customMem.customFree(customMem.opaque, ddict);
|
||||||
|
customMem.customFree(customMem.opaque, dctx);
|
||||||
|
return NULL;
|
||||||
|
} }
|
||||||
|
|
||||||
|
ddict->dictContent = dictContent;
|
||||||
|
ddict->dictContentSize = dictSize;
|
||||||
|
ddict->refContext = dctx;
|
||||||
|
return ddict;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! ZSTD_createDDict() :
|
||||||
|
* Create a digested dictionary, ready to start decompression operation without startup delay.
|
||||||
|
* `dict` can be released after `ZSTD_DDict` creation */
|
||||||
|
ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)
|
||||||
|
{
|
||||||
|
ZSTD_customMem const allocator = { NULL, NULL, NULL };
|
||||||
|
return ZSTD_createDDict_advanced(dict, dictSize, allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
|
||||||
|
{
|
||||||
|
ZSTD_freeFunction const cFree = ddict->refContext->customMem.customFree;
|
||||||
|
void* const opaque = ddict->refContext->customMem.opaque;
|
||||||
|
ZSTD_freeDCtx(ddict->refContext);
|
||||||
|
cFree(opaque, ddict->dictContent);
|
||||||
|
cFree(opaque, ddict);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! ZSTD_decompress_usingDDict() :
|
||||||
|
* Decompression using a pre-digested Dictionary
|
||||||
|
* Use dictionary without significant overhead. */
|
||||||
|
ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t srcSize,
|
||||||
|
const ZSTD_DDict* ddict)
|
||||||
|
{
|
||||||
|
return ZSTD_decompress_usingPreparedDCtx(dctx, ddict->refContext,
|
||||||
|
dst, dstCapacity,
|
||||||
|
src, srcSize);
|
||||||
|
}
|
||||||
|
|||||||
+175
-91
@@ -59,11 +59,13 @@
|
|||||||
#include "mem.h" /* read */
|
#include "mem.h" /* read */
|
||||||
#include "error_private.h"
|
#include "error_private.h"
|
||||||
#include "fse.h"
|
#include "fse.h"
|
||||||
#include "huf_static.h"
|
#define HUF_STATIC_LINKING_ONLY
|
||||||
#include "zstd_internal.h"
|
#include "huf.h"
|
||||||
|
#include "zstd_internal.h" /* includes zstd.h */
|
||||||
|
#include "xxhash.h"
|
||||||
#include "divsufsort.h"
|
#include "divsufsort.h"
|
||||||
#include "zdict_static.h"
|
#define ZDICT_STATIC_LINKING_ONLY
|
||||||
|
#include "zdict.h"
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
@@ -104,8 +106,7 @@ static void ZDICT_printHex(U32 dlevel, const void* ptr, size_t length)
|
|||||||
{
|
{
|
||||||
const BYTE* const b = (const BYTE*)ptr;
|
const BYTE* const b = (const BYTE*)ptr;
|
||||||
size_t u;
|
size_t u;
|
||||||
for (u=0; u<length; u++)
|
for (u=0; u<length; u++) {
|
||||||
{
|
|
||||||
BYTE c = b[u];
|
BYTE c = b[u];
|
||||||
if (c<32 || c>126) c = '.'; /* non-printable char */
|
if (c<32 || c>126) c = '.'; /* non-printable char */
|
||||||
DISPLAYLEVEL(dlevel, "%c", c);
|
DISPLAYLEVEL(dlevel, "%c", c);
|
||||||
@@ -198,8 +199,12 @@ static size_t ZDICT_count(const void* pIn, const void* pMatch)
|
|||||||
{
|
{
|
||||||
const char* const pStart = (const char*)pIn;
|
const char* const pStart = (const char*)pIn;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
size_t diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
|
size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
|
||||||
if (!diff) { pIn = (const char*)pIn+sizeof(size_t); pMatch = (const char*)pMatch+sizeof(size_t); continue; }
|
if (!diff) {
|
||||||
|
pIn = (const char*)pIn+sizeof(size_t);
|
||||||
|
pMatch = (const char*)pMatch+sizeof(size_t);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
pIn = (const char*)pIn+ZDICT_NbCommonBytes(diff);
|
pIn = (const char*)pIn+ZDICT_NbCommonBytes(diff);
|
||||||
return (size_t)((const char*)pIn - pStart);
|
return (size_t)((const char*)pIn - pStart);
|
||||||
}
|
}
|
||||||
@@ -346,9 +351,8 @@ static dictItem ZDICT_analyzePos(
|
|||||||
maxLength = i;
|
maxLength = i;
|
||||||
|
|
||||||
/* reduce maxLength in case of final into repetitive data */
|
/* reduce maxLength in case of final into repetitive data */
|
||||||
{
|
{ U32 l = (U32)maxLength;
|
||||||
U32 l = (U32)maxLength;
|
BYTE const c = b[pos + maxLength-1];
|
||||||
BYTE c = b[pos + maxLength-1];
|
|
||||||
while (b[pos+l-2]==c) l--;
|
while (b[pos+l-2]==c) l--;
|
||||||
maxLength = l;
|
maxLength = l;
|
||||||
}
|
}
|
||||||
@@ -367,12 +371,10 @@ static dictItem ZDICT_analyzePos(
|
|||||||
solution.savings = savings[maxLength];
|
solution.savings = savings[maxLength];
|
||||||
|
|
||||||
/* mark positions done */
|
/* mark positions done */
|
||||||
{
|
{ U32 id;
|
||||||
U32 id;
|
|
||||||
U32 testedPos;
|
|
||||||
for (id=start; id<end; id++) {
|
for (id=start; id<end; id++) {
|
||||||
U32 p, pEnd;
|
U32 p, pEnd;
|
||||||
testedPos = suffix[id];
|
U32 const testedPos = suffix[id];
|
||||||
if (testedPos == pos)
|
if (testedPos == pos)
|
||||||
length = solution.length;
|
length = solution.length;
|
||||||
else {
|
else {
|
||||||
@@ -439,7 +441,7 @@ static U32 ZDICT_checkMerge(dictItem* table, dictItem elt, U32 eltNbToSkip)
|
|||||||
static void ZDICT_removeDictItem(dictItem* table, U32 id)
|
static void ZDICT_removeDictItem(dictItem* table, U32 id)
|
||||||
{
|
{
|
||||||
/* convention : first element is nb of elts */
|
/* convention : first element is nb of elts */
|
||||||
U32 max = table->pos;
|
U32 const max = table->pos;
|
||||||
U32 u;
|
U32 u;
|
||||||
if (!id) return; /* protection, should never happen */
|
if (!id) return; /* protection, should never happen */
|
||||||
for (u=id; u<max-1; u++)
|
for (u=id; u<max-1; u++)
|
||||||
@@ -463,8 +465,7 @@ static void ZDICT_insertDictItem(dictItem* table, U32 maxSize, dictItem elt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* insert */
|
/* insert */
|
||||||
{
|
{ U32 current;
|
||||||
U32 current;
|
|
||||||
U32 nextElt = table->pos;
|
U32 nextElt = table->pos;
|
||||||
if (nextElt >= maxSize) nextElt = maxSize-1;
|
if (nextElt >= maxSize) nextElt = maxSize-1;
|
||||||
current = nextElt-1;
|
current = nextElt-1;
|
||||||
@@ -530,8 +531,7 @@ static size_t ZDICT_trainBuffer(dictItem* dictList, U32 dictListSize,
|
|||||||
DISPLAYLEVEL(2, "finding patterns ... \n");
|
DISPLAYLEVEL(2, "finding patterns ... \n");
|
||||||
DISPLAYLEVEL(3, "minimum ratio : %u \n", minRatio);
|
DISPLAYLEVEL(3, "minimum ratio : %u \n", minRatio);
|
||||||
|
|
||||||
{
|
{ U32 cursor; for (cursor=0; cursor < bufferSize; ) {
|
||||||
U32 cursor; for (cursor=0; cursor < bufferSize; ) {
|
|
||||||
dictItem solution;
|
dictItem solution;
|
||||||
if (doneMarks[cursor]) { cursor++; continue; }
|
if (doneMarks[cursor]) { cursor++; continue; }
|
||||||
solution = ZDICT_analyzePos(doneMarks, suffix, reverseSuffix[cursor], buffer, minRatio);
|
solution = ZDICT_analyzePos(doneMarks, suffix, reverseSuffix[cursor], buffer, minRatio);
|
||||||
@@ -542,8 +542,7 @@ static size_t ZDICT_trainBuffer(dictItem* dictList, U32 dictListSize,
|
|||||||
} }
|
} }
|
||||||
|
|
||||||
/* limit dictionary size */
|
/* limit dictionary size */
|
||||||
{
|
{ U32 const max = dictList->pos; /* convention : nb of useful elts within dictList */
|
||||||
U32 max = dictList->pos; /* convention : nb of useful elts within dictList */
|
|
||||||
U32 currentSize = 0;
|
U32 currentSize = 0;
|
||||||
U32 n; for (n=1; n<max; n++) {
|
U32 n; for (n=1; n<max; n++) {
|
||||||
currentSize += dictList[n].length;
|
currentSize += dictList[n].length;
|
||||||
@@ -579,9 +578,10 @@ typedef struct
|
|||||||
void* workPlace; /* must be ZSTD_BLOCKSIZE_MAX allocated */
|
void* workPlace; /* must be ZSTD_BLOCKSIZE_MAX allocated */
|
||||||
} EStats_ress_t;
|
} EStats_ress_t;
|
||||||
|
|
||||||
|
#define MAXREPOFFSET 1024
|
||||||
|
|
||||||
static void ZDICT_countEStats(EStats_ress_t esr,
|
static void ZDICT_countEStats(EStats_ress_t esr,
|
||||||
U32* countLit, U32* offsetcodeCount, U32* matchlengthCount, U32* litlengthCount,
|
U32* countLit, U32* offsetcodeCount, U32* matchlengthCount, U32* litlengthCount, U32* repOffsets,
|
||||||
const void* src, size_t srcSize)
|
const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
const seqStore_t* seqStorePtr;
|
const seqStore_t* seqStorePtr;
|
||||||
@@ -615,6 +615,17 @@ static void ZDICT_countEStats(EStats_ress_t esr,
|
|||||||
size_t u;
|
size_t u;
|
||||||
for (u=0; u<nbSeq; u++) litlengthCount[codePtr[u]]++;
|
for (u=0; u<nbSeq; u++) litlengthCount[codePtr[u]]++;
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
/* rep offsets */
|
||||||
|
{ const U32* const offsetPtr = seqStorePtr->offsetStart;
|
||||||
|
U32 offset1 = offsetPtr[0] - 3;
|
||||||
|
U32 offset2 = offsetPtr[1] - 3;
|
||||||
|
if (offset1 >= MAXREPOFFSET) offset1 = 0;
|
||||||
|
if (offset2 >= MAXREPOFFSET) offset2 = 0;
|
||||||
|
repOffsets[offset1] += 3;
|
||||||
|
repOffsets[offset2] += 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -630,12 +641,29 @@ static size_t ZDICT_maxSampleSize(const size_t* fileSizes, unsigned nbFiles)
|
|||||||
|
|
||||||
static size_t ZDICT_totalSampleSize(const size_t* fileSizes, unsigned nbFiles)
|
static size_t ZDICT_totalSampleSize(const size_t* fileSizes, unsigned nbFiles)
|
||||||
{
|
{
|
||||||
size_t total;
|
size_t total=0;
|
||||||
unsigned u;
|
unsigned u;
|
||||||
for (u=0, total=0; u<nbFiles; u++) total += fileSizes[u];
|
for (u=0; u<nbFiles; u++) total += fileSizes[u];
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct { U32 offset; U32 count; } offsetCount_t;
|
||||||
|
|
||||||
|
static void ZDICT_insertSortCount(offsetCount_t table[ZSTD_REP_NUM+1], U32 val, U32 count)
|
||||||
|
{
|
||||||
|
U32 u;
|
||||||
|
table[ZSTD_REP_NUM].offset = val;
|
||||||
|
table[ZSTD_REP_NUM].count = count;
|
||||||
|
for (u=ZSTD_REP_NUM; u>0; u--) {
|
||||||
|
offsetCount_t tmp;
|
||||||
|
if (table[u-1].count >= table[u].count) break;
|
||||||
|
tmp = table[u-1];
|
||||||
|
table[u-1] = table[u];
|
||||||
|
table[u] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define OFFCODE_MAX 18 /* only applicable to first block */
|
#define OFFCODE_MAX 18 /* only applicable to first block */
|
||||||
static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
|
static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
|
||||||
unsigned compressionLevel,
|
unsigned compressionLevel,
|
||||||
@@ -650,6 +678,8 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
|
|||||||
short matchLengthNCount[MaxML+1];
|
short matchLengthNCount[MaxML+1];
|
||||||
U32 litLengthCount[MaxLL+1];
|
U32 litLengthCount[MaxLL+1];
|
||||||
short litLengthNCount[MaxLL+1];
|
short litLengthNCount[MaxLL+1];
|
||||||
|
U32 repOffset[MAXREPOFFSET] = { 0 };
|
||||||
|
offsetCount_t bestRepOffset[ZSTD_REP_NUM+1];
|
||||||
EStats_ress_t esr;
|
EStats_ress_t esr;
|
||||||
ZSTD_parameters params;
|
ZSTD_parameters params;
|
||||||
U32 u, huffLog = 12, Offlog = OffFSELog, mlLog = MLFSELog, llLog = LLFSELog, total;
|
U32 u, huffLog = 12, Offlog = OffFSELog, mlLog = MLFSELog, llLog = LLFSELog, total;
|
||||||
@@ -657,12 +687,15 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
|
|||||||
size_t eSize = 0;
|
size_t eSize = 0;
|
||||||
size_t const totalSrcSize = ZDICT_totalSampleSize(fileSizes, nbFiles);
|
size_t const totalSrcSize = ZDICT_totalSampleSize(fileSizes, nbFiles);
|
||||||
size_t const averageSampleSize = totalSrcSize / nbFiles;
|
size_t const averageSampleSize = totalSrcSize / nbFiles;
|
||||||
|
BYTE* dstPtr = (BYTE*)dstBuffer;
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
for (u=0; u<256; u++) countLit[u]=1; /* any character must be described */
|
for (u=0; u<256; u++) countLit[u]=1; /* any character must be described */
|
||||||
for (u=0; u<=OFFCODE_MAX; u++) offcodeCount[u]=1;
|
for (u=0; u<=OFFCODE_MAX; u++) offcodeCount[u]=1;
|
||||||
for (u=0; u<=MaxML; u++) matchLengthCount[u]=1;
|
for (u=0; u<=MaxML; u++) matchLengthCount[u]=1;
|
||||||
for (u=0; u<=MaxLL; u++) litLengthCount[u]=1;
|
for (u=0; u<=MaxLL; u++) litLengthCount[u]=1;
|
||||||
|
repOffset[1] = repOffset[4] = repOffset[8] = 1;
|
||||||
|
memset(bestRepOffset, 0, sizeof(bestRepOffset));
|
||||||
esr.ref = ZSTD_createCCtx();
|
esr.ref = ZSTD_createCCtx();
|
||||||
esr.zc = ZSTD_createCCtx();
|
esr.zc = ZSTD_createCCtx();
|
||||||
esr.workPlace = malloc(ZSTD_BLOCKSIZE_MAX);
|
esr.workPlace = malloc(ZSTD_BLOCKSIZE_MAX);
|
||||||
@@ -680,7 +713,7 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
|
|||||||
/* collect stats on all files */
|
/* collect stats on all files */
|
||||||
for (u=0; u<nbFiles; u++) {
|
for (u=0; u<nbFiles; u++) {
|
||||||
ZDICT_countEStats(esr,
|
ZDICT_countEStats(esr,
|
||||||
countLit, offcodeCount, matchLengthCount, litLengthCount,
|
countLit, offcodeCount, matchLengthCount, litLengthCount, repOffset,
|
||||||
(const char*)srcBuffer + pos, fileSizes[u]);
|
(const char*)srcBuffer + pos, fileSizes[u]);
|
||||||
pos += fileSizes[u];
|
pos += fileSizes[u];
|
||||||
}
|
}
|
||||||
@@ -694,6 +727,13 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
|
|||||||
}
|
}
|
||||||
huffLog = (U32)errorCode;
|
huffLog = (U32)errorCode;
|
||||||
|
|
||||||
|
/* looking for most common first offsets */
|
||||||
|
{ U32 offset;
|
||||||
|
for (offset=1; offset<MAXREPOFFSET; offset++)
|
||||||
|
ZDICT_insertSortCount(bestRepOffset, offset, repOffset[offset]);
|
||||||
|
}
|
||||||
|
/* note : the result of this phase should be used to better appreciate the impact on statistics */
|
||||||
|
|
||||||
total=0; for (u=0; u<=OFFCODE_MAX; u++) total+=offcodeCount[u];
|
total=0; for (u=0; u<=OFFCODE_MAX; u++) total+=offcodeCount[u];
|
||||||
errorCode = FSE_normalizeCount(offcodeNCount, Offlog, offcodeCount, total, OFFCODE_MAX);
|
errorCode = FSE_normalizeCount(offcodeNCount, Offlog, offcodeCount, total, OFFCODE_MAX);
|
||||||
if (FSE_isError(errorCode)) {
|
if (FSE_isError(errorCode)) {
|
||||||
@@ -721,46 +761,70 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
|
|||||||
}
|
}
|
||||||
llLog = (U32)errorCode;
|
llLog = (U32)errorCode;
|
||||||
|
|
||||||
|
|
||||||
/* write result to buffer */
|
/* write result to buffer */
|
||||||
errorCode = HUF_writeCTable(dstBuffer, maxDstSize, hufTable, 255, huffLog);
|
{ size_t const hhSize = HUF_writeCTable(dstPtr, maxDstSize, hufTable, 255, huffLog);
|
||||||
if (HUF_isError(errorCode)) {
|
if (HUF_isError(hhSize)) {
|
||||||
eSize = ERROR(GENERIC);
|
eSize = ERROR(GENERIC);
|
||||||
DISPLAYLEVEL(1, "HUF_writeCTable error");
|
DISPLAYLEVEL(1, "HUF_writeCTable error");
|
||||||
goto _cleanup;
|
goto _cleanup;
|
||||||
|
}
|
||||||
|
dstPtr += hhSize;
|
||||||
|
maxDstSize -= hhSize;
|
||||||
|
eSize += hhSize;
|
||||||
}
|
}
|
||||||
dstBuffer = (char*)dstBuffer + errorCode;
|
|
||||||
maxDstSize -= errorCode;
|
|
||||||
eSize += errorCode;
|
|
||||||
|
|
||||||
errorCode = FSE_writeNCount(dstBuffer, maxDstSize, offcodeNCount, OFFCODE_MAX, Offlog);
|
{ size_t const ohSize = FSE_writeNCount(dstPtr, maxDstSize, offcodeNCount, OFFCODE_MAX, Offlog);
|
||||||
if (FSE_isError(errorCode)) {
|
if (FSE_isError(ohSize)) {
|
||||||
eSize = ERROR(GENERIC);
|
eSize = ERROR(GENERIC);
|
||||||
DISPLAYLEVEL(1, "FSE_writeNCount error with offcodeNCount");
|
DISPLAYLEVEL(1, "FSE_writeNCount error with offcodeNCount");
|
||||||
goto _cleanup;
|
goto _cleanup;
|
||||||
|
}
|
||||||
|
dstPtr += ohSize;
|
||||||
|
maxDstSize -= ohSize;
|
||||||
|
eSize += ohSize;
|
||||||
}
|
}
|
||||||
dstBuffer = (char*)dstBuffer + errorCode;
|
|
||||||
maxDstSize -= errorCode;
|
|
||||||
eSize += errorCode;
|
|
||||||
|
|
||||||
errorCode = FSE_writeNCount(dstBuffer, maxDstSize, matchLengthNCount, MaxML, mlLog);
|
{ size_t const mhSize = FSE_writeNCount(dstPtr, maxDstSize, matchLengthNCount, MaxML, mlLog);
|
||||||
if (FSE_isError(errorCode)) {
|
if (FSE_isError(mhSize)) {
|
||||||
eSize = ERROR(GENERIC);
|
eSize = ERROR(GENERIC);
|
||||||
DISPLAYLEVEL(1, "FSE_writeNCount error with matchLengthNCount");
|
DISPLAYLEVEL(1, "FSE_writeNCount error with matchLengthNCount");
|
||||||
goto _cleanup;
|
goto _cleanup;
|
||||||
|
}
|
||||||
|
dstPtr += mhSize;
|
||||||
|
maxDstSize -= mhSize;
|
||||||
|
eSize += mhSize;
|
||||||
}
|
}
|
||||||
dstBuffer = (char*)dstBuffer + errorCode;
|
|
||||||
maxDstSize -= errorCode;
|
|
||||||
eSize += errorCode;
|
|
||||||
|
|
||||||
errorCode = FSE_writeNCount(dstBuffer, maxDstSize, litLengthNCount, MaxLL, llLog);
|
{ size_t const lhSize = FSE_writeNCount(dstPtr, maxDstSize, litLengthNCount, MaxLL, llLog);
|
||||||
if (FSE_isError(errorCode)) {
|
if (FSE_isError(lhSize)) {
|
||||||
|
eSize = ERROR(GENERIC);
|
||||||
|
DISPLAYLEVEL(1, "FSE_writeNCount error with litlengthNCount");
|
||||||
|
goto _cleanup;
|
||||||
|
}
|
||||||
|
dstPtr += lhSize;
|
||||||
|
maxDstSize -= lhSize;
|
||||||
|
eSize += lhSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxDstSize<12) {
|
||||||
eSize = ERROR(GENERIC);
|
eSize = ERROR(GENERIC);
|
||||||
DISPLAYLEVEL(1, "FSE_writeNCount error with litlengthNCount");
|
DISPLAYLEVEL(1, "not enough space to write RepOffsets");
|
||||||
goto _cleanup;
|
goto _cleanup;
|
||||||
}
|
}
|
||||||
dstBuffer = (char*)dstBuffer + errorCode;
|
# if 0
|
||||||
maxDstSize -= errorCode;
|
MEM_writeLE32(dstPtr+0, bestRepOffset[0].offset);
|
||||||
eSize += errorCode;
|
MEM_writeLE32(dstPtr+4, bestRepOffset[1].offset);
|
||||||
|
MEM_writeLE32(dstPtr+8, bestRepOffset[2].offset);
|
||||||
|
#else
|
||||||
|
/* at this stage, we don't use the result of "most common first offset",
|
||||||
|
as the impact of statistics is not properly evaluated */
|
||||||
|
MEM_writeLE32(dstPtr+0, repStartValue[0]);
|
||||||
|
MEM_writeLE32(dstPtr+4, repStartValue[1]);
|
||||||
|
MEM_writeLE32(dstPtr+8, repStartValue[2]);
|
||||||
|
#endif
|
||||||
|
dstPtr += 12;
|
||||||
|
eSize += 12;
|
||||||
|
|
||||||
_cleanup:
|
_cleanup:
|
||||||
ZSTD_freeCCtx(esr.ref);
|
ZSTD_freeCCtx(esr.ref);
|
||||||
@@ -785,7 +849,7 @@ static size_t ZDICT_fastSampling(void* dictBuffer, size_t dictSize,
|
|||||||
{
|
{
|
||||||
char* dstPtr = (char*)dictBuffer + dictSize;
|
char* dstPtr = (char*)dictBuffer + dictSize;
|
||||||
const char* srcPtr = (const char*)samplesBuffer;
|
const char* srcPtr = (const char*)samplesBuffer;
|
||||||
size_t nbSegments = dictSize / DIB_FASTSEGMENTSIZE;
|
size_t const nbSegments = dictSize / DIB_FASTSEGMENTSIZE;
|
||||||
size_t segNb, interSize;
|
size_t segNb, interSize;
|
||||||
|
|
||||||
if (nbSegments <= 2) return ERROR(srcSize_wrong);
|
if (nbSegments <= 2) return ERROR(srcSize_wrong);
|
||||||
@@ -810,6 +874,33 @@ static size_t ZDICT_fastSampling(void* dictBuffer, size_t dictSize,
|
|||||||
return nbSegments * DIB_FASTSEGMENTSIZE;
|
return nbSegments * DIB_FASTSEGMENTSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t ZDICT_addEntropyTablesFromBuffer_advanced(void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity,
|
||||||
|
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
|
||||||
|
ZDICT_params_t params)
|
||||||
|
{
|
||||||
|
size_t hSize;
|
||||||
|
unsigned const compressionLevel = (params.compressionLevel == 0) ? g_compressionLevel_default : params.compressionLevel;
|
||||||
|
|
||||||
|
/* dictionary header */
|
||||||
|
MEM_writeLE32(dictBuffer, ZSTD_DICT_MAGIC);
|
||||||
|
{ U64 const randomID = XXH64((char*)dictBuffer + dictBufferCapacity - dictContentSize, dictContentSize, 0);
|
||||||
|
U32 const dictID = params.dictID ? params.dictID : (U32)(randomID>>11);
|
||||||
|
MEM_writeLE32((char*)dictBuffer+4, dictID);
|
||||||
|
}
|
||||||
|
hSize = 8;
|
||||||
|
|
||||||
|
/* entropy tables */
|
||||||
|
DISPLAYLEVEL(2, "\r%70s\r", ""); /* clean display line */
|
||||||
|
DISPLAYLEVEL(2, "statistics ... \n");
|
||||||
|
hSize += ZDICT_analyzeEntropy((char*)dictBuffer+hSize, dictBufferCapacity-hSize,
|
||||||
|
compressionLevel,
|
||||||
|
samplesBuffer, samplesSizes, nbSamples,
|
||||||
|
(char*)dictBuffer + dictBufferCapacity - dictContentSize, dictContentSize);
|
||||||
|
|
||||||
|
if (hSize + dictContentSize < dictBufferCapacity)
|
||||||
|
memmove((char*)dictBuffer + hSize, (char*)dictBuffer + dictBufferCapacity - dictContentSize, dictContentSize);
|
||||||
|
return MIN(dictBufferCapacity, hSize+dictContentSize);
|
||||||
|
}
|
||||||
|
|
||||||
#define DIB_MINSAMPLESSIZE (DIB_FASTSEGMENTSIZE*3)
|
#define DIB_MINSAMPLESSIZE (DIB_FASTSEGMENTSIZE*3)
|
||||||
/*! ZDICT_trainFromBuffer_unsafe() :
|
/*! ZDICT_trainFromBuffer_unsafe() :
|
||||||
@@ -818,14 +909,13 @@ static size_t ZDICT_fastSampling(void* dictBuffer, size_t dictSize,
|
|||||||
*/
|
*/
|
||||||
size_t ZDICT_trainFromBuffer_unsafe(
|
size_t ZDICT_trainFromBuffer_unsafe(
|
||||||
void* dictBuffer, size_t maxDictSize,
|
void* dictBuffer, size_t maxDictSize,
|
||||||
const void* samplesBuffer, const size_t* sampleSizes, unsigned nbSamples,
|
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
|
||||||
ZDICT_params_t params)
|
ZDICT_params_t params)
|
||||||
{
|
{
|
||||||
U32 const dictListSize = MAX( MAX(DICTLISTSIZE, nbSamples), (U32)(maxDictSize/16));
|
U32 const dictListSize = MAX( MAX(DICTLISTSIZE, nbSamples), (U32)(maxDictSize/16));
|
||||||
dictItem* dictList = (dictItem*)malloc(dictListSize * sizeof(*dictList));
|
dictItem* const dictList = (dictItem*)malloc(dictListSize * sizeof(*dictList));
|
||||||
unsigned selectivity = params.selectivityLevel;
|
unsigned selectivity = params.selectivityLevel;
|
||||||
unsigned compressionLevel = params.compressionLevel;
|
size_t const targetDictSize = maxDictSize;
|
||||||
size_t targetDictSize = maxDictSize;
|
|
||||||
size_t sBuffSize;
|
size_t sBuffSize;
|
||||||
size_t dictSize = 0;
|
size_t dictSize = 0;
|
||||||
|
|
||||||
@@ -834,18 +924,17 @@ size_t ZDICT_trainFromBuffer_unsafe(
|
|||||||
if (!dictList) return ERROR(memory_allocation);
|
if (!dictList) return ERROR(memory_allocation);
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
{ unsigned u; for (u=0, sBuffSize=0; u<nbSamples; u++) sBuffSize += sampleSizes[u]; }
|
{ unsigned u; for (u=0, sBuffSize=0; u<nbSamples; u++) sBuffSize += samplesSizes[u]; }
|
||||||
if (sBuffSize < DIB_MINSAMPLESSIZE) return 0; /* not enough source to create dictionary */
|
if (sBuffSize < DIB_MINSAMPLESSIZE) return 0; /* not enough source to create dictionary */
|
||||||
ZDICT_initDictItem(dictList);
|
ZDICT_initDictItem(dictList);
|
||||||
g_displayLevel = params.notificationLevel;
|
g_displayLevel = params.notificationLevel;
|
||||||
if (selectivity==0) selectivity = g_selectivity_default;
|
if (selectivity==0) selectivity = g_selectivity_default;
|
||||||
if (compressionLevel==0) compressionLevel = g_compressionLevel_default;
|
|
||||||
|
|
||||||
/* build dictionary */
|
/* build dictionary */
|
||||||
if (selectivity>1) { /* selectivity == 1 => fast mode */
|
if (selectivity>1) { /* selectivity == 1 => fast mode */
|
||||||
ZDICT_trainBuffer(dictList, dictListSize,
|
ZDICT_trainBuffer(dictList, dictListSize,
|
||||||
samplesBuffer, sBuffSize,
|
samplesBuffer, sBuffSize,
|
||||||
sampleSizes, nbSamples,
|
samplesSizes, nbSamples,
|
||||||
selectivity, (U32)targetDictSize);
|
selectivity, (U32)targetDictSize);
|
||||||
|
|
||||||
/* display best matches */
|
/* display best matches */
|
||||||
@@ -867,18 +956,16 @@ size_t ZDICT_trainFromBuffer_unsafe(
|
|||||||
|
|
||||||
/* create dictionary */
|
/* create dictionary */
|
||||||
{ U32 dictContentSize = ZDICT_dictSize(dictList);
|
{ U32 dictContentSize = ZDICT_dictSize(dictList);
|
||||||
size_t hSize;
|
|
||||||
BYTE* ptr;
|
|
||||||
U32 u;
|
|
||||||
|
|
||||||
/* build dict content */
|
/* build dict content */
|
||||||
ptr = (BYTE*)dictBuffer + maxDictSize;
|
{ U32 u;
|
||||||
for (u=1; u<dictList->pos; u++) {
|
BYTE* ptr = (BYTE*)dictBuffer + maxDictSize;
|
||||||
U32 l = dictList[u].length;
|
for (u=1; u<dictList->pos; u++) {
|
||||||
ptr -= l;
|
U32 l = dictList[u].length;
|
||||||
if (ptr<(BYTE*)dictBuffer) return ERROR(GENERIC); /* should not happen */
|
ptr -= l;
|
||||||
memcpy(ptr, (const char*)samplesBuffer+dictList[u].pos, l);
|
if (ptr<(BYTE*)dictBuffer) return ERROR(GENERIC); /* should not happen */
|
||||||
}
|
memcpy(ptr, (const char*)samplesBuffer+dictList[u].pos, l);
|
||||||
|
} }
|
||||||
|
|
||||||
/* fast mode dict content */
|
/* fast mode dict content */
|
||||||
if (selectivity==1) { /* note could also be used to complete a dictionary, but not necessarily better */
|
if (selectivity==1) { /* note could also be used to complete a dictionary, but not necessarily better */
|
||||||
@@ -888,21 +975,9 @@ size_t ZDICT_trainFromBuffer_unsafe(
|
|||||||
samplesBuffer, sBuffSize);
|
samplesBuffer, sBuffSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dictionary header */
|
dictSize = ZDICT_addEntropyTablesFromBuffer_advanced(dictBuffer, dictContentSize, maxDictSize,
|
||||||
MEM_writeLE32(dictBuffer, ZSTD_DICT_MAGIC);
|
samplesBuffer, samplesSizes, nbSamples,
|
||||||
hSize = 4;
|
params);
|
||||||
|
|
||||||
/* entropic tables */
|
|
||||||
DISPLAYLEVEL(2, "\r%70s\r", ""); /* clean display line */
|
|
||||||
DISPLAYLEVEL(2, "statistics ... \n");
|
|
||||||
hSize += ZDICT_analyzeEntropy((char*)dictBuffer+4, maxDictSize-4,
|
|
||||||
compressionLevel,
|
|
||||||
samplesBuffer, sampleSizes, nbSamples,
|
|
||||||
(char*)dictBuffer + maxDictSize - dictContentSize, dictContentSize);
|
|
||||||
|
|
||||||
if (hSize + dictContentSize < maxDictSize)
|
|
||||||
memmove((char*)dictBuffer + hSize, (char*)dictBuffer + maxDictSize - dictContentSize, dictContentSize);
|
|
||||||
dictSize = MIN(maxDictSize, hSize+dictContentSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clean up */
|
/* clean up */
|
||||||
@@ -914,8 +989,8 @@ size_t ZDICT_trainFromBuffer_unsafe(
|
|||||||
/* issue : samplesBuffer need to be followed by a noisy guard band.
|
/* issue : samplesBuffer need to be followed by a noisy guard band.
|
||||||
* work around : duplicate the buffer, and add the noise */
|
* work around : duplicate the buffer, and add the noise */
|
||||||
size_t ZDICT_trainFromBuffer_advanced(void* dictBuffer, size_t dictBufferCapacity,
|
size_t ZDICT_trainFromBuffer_advanced(void* dictBuffer, size_t dictBufferCapacity,
|
||||||
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
|
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
|
||||||
ZDICT_params_t params)
|
ZDICT_params_t params)
|
||||||
{
|
{
|
||||||
void* newBuff;
|
void* newBuff;
|
||||||
size_t sBuffSize;
|
size_t sBuffSize;
|
||||||
@@ -947,3 +1022,12 @@ size_t ZDICT_trainFromBuffer(void* dictBuffer, size_t dictBufferCapacity,
|
|||||||
params);
|
params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t ZDICT_addEntropyTablesFromBuffer(void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity,
|
||||||
|
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples)
|
||||||
|
{
|
||||||
|
ZDICT_params_t params;
|
||||||
|
memset(¶ms, 0, sizeof(params));
|
||||||
|
return ZDICT_addEntropyTablesFromBuffer_advanced(dictBuffer, dictContentSize, dictBufferCapacity,
|
||||||
|
samplesBuffer, samplesSizes, nbSamples,
|
||||||
|
params);
|
||||||
|
}
|
||||||
|
|||||||
@@ -52,6 +52,21 @@ extern "C" {
|
|||||||
size_t ZDICT_trainFromBuffer(void* dictBuffer, size_t dictBufferCapacity,
|
size_t ZDICT_trainFromBuffer(void* dictBuffer, size_t dictBufferCapacity,
|
||||||
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples);
|
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples);
|
||||||
|
|
||||||
|
/*! ZDICT_addEntropyTablesFromBuffer() :
|
||||||
|
|
||||||
|
Given a content-only dictionary (built for example from common strings in
|
||||||
|
the input), add entropy tables computed from the memory buffer
|
||||||
|
`samplesBuffer`, where `nbSamples` samples have been stored concatenated.
|
||||||
|
Each sample size is provided into an orderly table `samplesSizes`.
|
||||||
|
|
||||||
|
The input dictionary is the last `dictContentSize` bytes of `dictBuffer`. The
|
||||||
|
resulting dictionary with added entropy tables will written back to
|
||||||
|
`dictBuffer`.
|
||||||
|
@return : size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`).
|
||||||
|
*/
|
||||||
|
size_t ZDICT_addEntropyTablesFromBuffer(void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity,
|
||||||
|
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples);
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Helper functions
|
* Helper functions
|
||||||
@@ -60,6 +75,44 @@ unsigned ZDICT_isError(size_t errorCode);
|
|||||||
const char* ZDICT_getErrorName(size_t errorCode);
|
const char* ZDICT_getErrorName(size_t errorCode);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ZDICT_STATIC_LINKING_ONLY
|
||||||
|
|
||||||
|
/* ====================================================================================
|
||||||
|
* The definitions in this section are considered experimental.
|
||||||
|
* They should never be used with a dynamic library, as they may change in the future.
|
||||||
|
* They are provided for advanced usages.
|
||||||
|
* Use them only in association with static linking.
|
||||||
|
* ==================================================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
/*-*************************************
|
||||||
|
* Public type
|
||||||
|
***************************************/
|
||||||
|
typedef struct {
|
||||||
|
unsigned selectivityLevel; /* 0 means default; larger => bigger selection => larger dictionary */
|
||||||
|
unsigned compressionLevel; /* 0 means default; target a specific zstd compression level */
|
||||||
|
unsigned notificationLevel; /* Write to stderr; 0 = none (default); 1 = errors; 2 = progression; 3 = details; 4 = debug; */
|
||||||
|
unsigned dictID; /* 0 means auto mode (32-bits random value); other : force dictID value */
|
||||||
|
unsigned reserved[2]; /* space for future parameters */
|
||||||
|
} ZDICT_params_t;
|
||||||
|
|
||||||
|
|
||||||
|
/*-*************************************
|
||||||
|
* Public functions
|
||||||
|
***************************************/
|
||||||
|
/*! ZDICT_trainFromBuffer_advanced() :
|
||||||
|
Same as ZDICT_trainFromBuffer() with control over more parameters.
|
||||||
|
`parameters` is optional and can be provided with values set to 0 to mean "default".
|
||||||
|
@return : size of dictionary stored into `dictBuffer` (<= `dictBufferSize`)
|
||||||
|
or an error code, which can be tested by ZDICT_isError().
|
||||||
|
note : ZDICT_trainFromBuffer_advanced() will send notifications into stderr if instructed to, using ZDICT_setNotificationLevel()
|
||||||
|
*/
|
||||||
|
size_t ZDICT_trainFromBuffer_advanced(void* dictBuffer, size_t dictBufferCapacity,
|
||||||
|
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
|
||||||
|
ZDICT_params_t parameters);
|
||||||
|
|
||||||
|
#endif /* ZDICT_STATIC_LINKING_ONLY */
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
dictBuilder header file
|
|
||||||
for static linking only
|
|
||||||
Copyright (C) Yann Collet 2016
|
|
||||||
|
|
||||||
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://www.zstd.net
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* This library is EXPERIMENTAL, below API is not yet stable */
|
|
||||||
|
|
||||||
#ifndef DICTBUILDER_STATIC_H_002
|
|
||||||
#define DICTBUILDER_STATIC_H_002
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-*************************************
|
|
||||||
* Dependencies
|
|
||||||
***************************************/
|
|
||||||
#include "zdict.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
|
||||||
* Public type
|
|
||||||
***************************************/
|
|
||||||
typedef struct {
|
|
||||||
unsigned selectivityLevel; /* 0 means default; larger => bigger selection => larger dictionary */
|
|
||||||
unsigned compressionLevel; /* 0 means default; target a specific zstd compression level */
|
|
||||||
unsigned notificationLevel; /* Write to stderr; 0 = none (default); 1 = errors; 2 = progression; 3 = details; 4 = debug; */
|
|
||||||
unsigned reserved[3]; /* space for future parameters */
|
|
||||||
} ZDICT_params_t;
|
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
|
||||||
* Public functions
|
|
||||||
***************************************/
|
|
||||||
/*! ZDICT_trainFromBuffer_advanced() :
|
|
||||||
Same as ZDICT_trainFromBuffer() with control over more parameters.
|
|
||||||
`parameters` is optional and can be provided with values set to 0 to mean "default".
|
|
||||||
@return : size of dictionary stored into `dictBuffer` (<= `dictBufferSize`)
|
|
||||||
or an error code, which can be tested by DiB_isError().
|
|
||||||
note : ZDICT_trainFromBuffer_advanced() will send notifications into stderr if instructed to, using ZDICT_setNotificationLevel()
|
|
||||||
*/
|
|
||||||
size_t ZDICT_trainFromBuffer_advanced(void* dictBuffer, size_t dictBufferCapacity,
|
|
||||||
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
|
|
||||||
ZDICT_params_t parameters);
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* DICTBUILDER_STATIC_H_002 */
|
|
||||||
+40
-31
@@ -47,6 +47,7 @@ extern "C" {
|
|||||||
#include "zstd_v03.h"
|
#include "zstd_v03.h"
|
||||||
#include "zstd_v04.h"
|
#include "zstd_v04.h"
|
||||||
#include "zstd_v05.h"
|
#include "zstd_v05.h"
|
||||||
|
#include "zstd_v06.h"
|
||||||
|
|
||||||
|
|
||||||
/** ZSTD_isLegacy() :
|
/** ZSTD_isLegacy() :
|
||||||
@@ -55,15 +56,16 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
MEM_STATIC unsigned ZSTD_isLegacy (U32 magicNumberLE)
|
MEM_STATIC unsigned ZSTD_isLegacy (U32 magicNumberLE)
|
||||||
{
|
{
|
||||||
switch(magicNumberLE)
|
switch(magicNumberLE)
|
||||||
{
|
{
|
||||||
case ZSTDv01_magicNumberLE:return 1;
|
case ZSTDv01_magicNumberLE:return 1;
|
||||||
case ZSTDv02_magicNumber : return 2;
|
case ZSTDv02_magicNumber : return 2;
|
||||||
case ZSTDv03_magicNumber : return 3;
|
case ZSTDv03_magicNumber : return 3;
|
||||||
case ZSTDv04_magicNumber : return 4;
|
case ZSTDv04_magicNumber : return 4;
|
||||||
case ZSTDv05_MAGICNUMBER : return 5;
|
case ZSTDv05_MAGICNUMBER : return 5;
|
||||||
default : return 0;
|
case ZSTDv06_MAGICNUMBER : return 6;
|
||||||
}
|
default : return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -73,28 +75,35 @@ MEM_STATIC size_t ZSTD_decompressLegacy(
|
|||||||
const void* dict,size_t dictSize,
|
const void* dict,size_t dictSize,
|
||||||
U32 magicNumberLE)
|
U32 magicNumberLE)
|
||||||
{
|
{
|
||||||
switch(magicNumberLE)
|
switch(magicNumberLE)
|
||||||
{
|
{
|
||||||
case ZSTDv01_magicNumberLE :
|
case ZSTDv01_magicNumberLE :
|
||||||
return ZSTDv01_decompress(dst, dstCapacity, src, compressedSize);
|
return ZSTDv01_decompress(dst, dstCapacity, src, compressedSize);
|
||||||
case ZSTDv02_magicNumber :
|
case ZSTDv02_magicNumber :
|
||||||
return ZSTDv02_decompress(dst, dstCapacity, src, compressedSize);
|
return ZSTDv02_decompress(dst, dstCapacity, src, compressedSize);
|
||||||
case ZSTDv03_magicNumber :
|
case ZSTDv03_magicNumber :
|
||||||
return ZSTDv03_decompress(dst, dstCapacity, src, compressedSize);
|
return ZSTDv03_decompress(dst, dstCapacity, src, compressedSize);
|
||||||
case ZSTDv04_magicNumber :
|
case ZSTDv04_magicNumber :
|
||||||
return ZSTDv04_decompress(dst, dstCapacity, src, compressedSize);
|
return ZSTDv04_decompress(dst, dstCapacity, src, compressedSize);
|
||||||
case ZSTDv05_MAGICNUMBER :
|
case ZSTDv05_MAGICNUMBER :
|
||||||
{
|
{ size_t result;
|
||||||
size_t result;
|
ZSTDv05_DCtx* const zd = ZSTDv05_createDCtx();
|
||||||
ZSTDv05_DCtx* zd = ZSTDv05_createDCtx();
|
if (zd==NULL) return ERROR(memory_allocation);
|
||||||
if (zd==NULL) return ERROR(memory_allocation);
|
result = ZSTDv05_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize);
|
||||||
result = ZSTDv05_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize);
|
ZSTDv05_freeDCtx(zd);
|
||||||
ZSTDv05_freeDCtx(zd);
|
return result;
|
||||||
return result;
|
}
|
||||||
}
|
case ZSTDv06_MAGICNUMBER :
|
||||||
default :
|
{ size_t result;
|
||||||
return ERROR(prefix_unknown);
|
ZSTDv06_DCtx* const zd = ZSTDv06_createDCtx();
|
||||||
}
|
if (zd==NULL) return ERROR(memory_allocation);
|
||||||
|
result = ZSTDv06_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize);
|
||||||
|
ZSTDv06_freeDCtx(zd);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
default :
|
||||||
|
return ERROR(prefix_unknown);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -436,21 +436,6 @@ extern "C" {
|
|||||||
***************************************/
|
***************************************/
|
||||||
#define ZSTDv05_WINDOWLOG_ABSOLUTEMIN 11
|
#define ZSTDv05_WINDOWLOG_ABSOLUTEMIN 11
|
||||||
|
|
||||||
/* from faster to stronger */
|
|
||||||
typedef enum { ZSTDv05_fast, ZSTDv05_greedy, ZSTDv05_lazy, ZSTDv05_lazy2, ZSTDv05_btlazy2, ZSTDv05_opt, ZSTDv05_btopt } ZSTDv05_strategy;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
U64 srcSize; /* optional : tells how much bytes are present in the frame. Use 0 if not known. */
|
|
||||||
U32 windowLog; /* largest match distance : larger == more compression, more memory needed during decompression */
|
|
||||||
U32 contentLog; /* full search segment : larger == more compression, slower, more memory (useless for fast) */
|
|
||||||
U32 hashLog; /* dispatch table : larger == faster, more memory */
|
|
||||||
U32 searchLog; /* nb of searches : larger == more compression, slower */
|
|
||||||
U32 searchLength; /* match length searched : larger == faster decompression, sometimes less compression */
|
|
||||||
U32 targetLength; /* acceptable match size for optimal parser (only) : larger == more compression, slower */
|
|
||||||
ZSTDv05_strategy strategy;
|
|
||||||
} ZSTDv05_parameters;
|
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Advanced functions
|
* Advanced functions
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ extern "C" {
|
|||||||
* Dependencies
|
* Dependencies
|
||||||
***************************************/
|
***************************************/
|
||||||
#include <stddef.h> /* size_t */
|
#include <stddef.h> /* size_t */
|
||||||
|
#include "mem.h" /* U64, U32 */
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
@@ -91,6 +91,14 @@ size_t ZSTDv05_decompress_usingDict(ZSTDv05_DCtx* dctx,
|
|||||||
/*-************************
|
/*-************************
|
||||||
* Advanced Streaming API
|
* Advanced Streaming API
|
||||||
***************************/
|
***************************/
|
||||||
|
typedef enum { ZSTDv05_fast, ZSTDv05_greedy, ZSTDv05_lazy, ZSTDv05_lazy2, ZSTDv05_btlazy2, ZSTDv05_opt, ZSTDv05_btopt } ZSTDv05_strategy;
|
||||||
|
typedef struct {
|
||||||
|
U64 srcSize;
|
||||||
|
U32 windowLog; /* the only useful information to retrieve */
|
||||||
|
U32 contentLog; U32 hashLog; U32 searchLog; U32 searchLength; U32 targetLength; ZSTDv05_strategy strategy;
|
||||||
|
} ZSTDv05_parameters;
|
||||||
|
size_t ZSTDv05_getFrameParams(ZSTDv05_parameters* params, const void* src, size_t srcSize);
|
||||||
|
|
||||||
size_t ZSTDv05_decompressBegin_usingDict(ZSTDv05_DCtx* dctx, const void* dict, size_t dictSize);
|
size_t ZSTDv05_decompressBegin_usingDict(ZSTDv05_DCtx* dctx, const void* dict, size_t dictSize);
|
||||||
void ZSTDv05_copyDCtx(ZSTDv05_DCtx* dstDCtx, const ZSTDv05_DCtx* srcDCtx);
|
void ZSTDv05_copyDCtx(ZSTDv05_DCtx* dstDCtx, const ZSTDv05_DCtx* srcDCtx);
|
||||||
size_t ZSTDv05_nextSrcSizeToDecompress(ZSTDv05_DCtx* dctx);
|
size_t ZSTDv05_nextSrcSizeToDecompress(ZSTDv05_DCtx* dctx);
|
||||||
|
|||||||
@@ -0,0 +1,4583 @@
|
|||||||
|
/* ******************************************************************
|
||||||
|
zstd_v06.c
|
||||||
|
Decompression module for ZSTD v0.6 legacy format
|
||||||
|
Copyright (C) 2016, 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 :
|
||||||
|
- Homepage : http://www.zstd.net/
|
||||||
|
****************************************************************** */
|
||||||
|
|
||||||
|
/*- Dependencies -*/
|
||||||
|
#include "zstd_v06.h"
|
||||||
|
#include <stddef.h> /* size_t, ptrdiff_t */
|
||||||
|
#include <string.h> /* memcpy */
|
||||||
|
#include <stdlib.h> /* malloc, free, qsort */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ******************************************************************
|
||||||
|
mem.h
|
||||||
|
low-level memory access routines
|
||||||
|
Copyright (C) 2013-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 :
|
||||||
|
- FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||||
|
- Public forum : https://groups.google.com/forum/#!forum/lz4c
|
||||||
|
****************************************************************** */
|
||||||
|
#ifndef MEM_H_MODULE
|
||||||
|
#define MEM_H_MODULE
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*-****************************************
|
||||||
|
* Compiler specifics
|
||||||
|
******************************************/
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
# define MEM_STATIC static __attribute__((unused))
|
||||||
|
#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
||||||
|
# define MEM_STATIC static inline
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
# define MEM_STATIC static __inline
|
||||||
|
#else
|
||||||
|
# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*-**************************************************************
|
||||||
|
* Basic Types
|
||||||
|
*****************************************************************/
|
||||||
|
#if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
|
||||||
|
# include <stdint.h>
|
||||||
|
typedef uint8_t BYTE;
|
||||||
|
typedef uint16_t U16;
|
||||||
|
typedef int16_t S16;
|
||||||
|
typedef uint32_t U32;
|
||||||
|
typedef int32_t S32;
|
||||||
|
typedef uint64_t U64;
|
||||||
|
typedef int64_t S64;
|
||||||
|
#else
|
||||||
|
typedef unsigned char BYTE;
|
||||||
|
typedef unsigned short U16;
|
||||||
|
typedef signed short S16;
|
||||||
|
typedef unsigned int U32;
|
||||||
|
typedef signed int S32;
|
||||||
|
typedef unsigned long long U64;
|
||||||
|
typedef signed long long S64;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*-**************************************************************
|
||||||
|
* Memory I/O
|
||||||
|
*****************************************************************/
|
||||||
|
/* MEM_FORCE_MEMORY_ACCESS :
|
||||||
|
* By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
|
||||||
|
* Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
|
||||||
|
* The below switch allow to select different access method for improved performance.
|
||||||
|
* Method 0 (default) : use `memcpy()`. Safe and portable.
|
||||||
|
* Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
|
||||||
|
* This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
|
||||||
|
* Method 2 : direct access. This method is portable but violate C standard.
|
||||||
|
* It can generate buggy code on targets depending on alignment.
|
||||||
|
* In some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
|
||||||
|
* See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details.
|
||||||
|
* Prefer these methods in priority order (0 > 1 > 2)
|
||||||
|
*/
|
||||||
|
#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
|
||||||
|
# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
|
||||||
|
# define MEM_FORCE_MEMORY_ACCESS 2
|
||||||
|
# elif defined(__INTEL_COMPILER) || \
|
||||||
|
(defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) ))
|
||||||
|
# define MEM_FORCE_MEMORY_ACCESS 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; }
|
||||||
|
MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; }
|
||||||
|
|
||||||
|
MEM_STATIC unsigned MEM_isLittleEndian(void)
|
||||||
|
{
|
||||||
|
const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
|
||||||
|
return one.c[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2)
|
||||||
|
|
||||||
|
/* violates C standard, by lying on structure alignment.
|
||||||
|
Only use if no other choice to achieve best performance on target platform */
|
||||||
|
MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; }
|
||||||
|
MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; }
|
||||||
|
MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; }
|
||||||
|
MEM_STATIC U64 MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; }
|
||||||
|
|
||||||
|
MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }
|
||||||
|
MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; }
|
||||||
|
MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; }
|
||||||
|
|
||||||
|
#elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1)
|
||||||
|
|
||||||
|
/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
|
||||||
|
/* currently only defined for gcc and icc */
|
||||||
|
typedef union { U16 u16; U32 u32; U64 u64; size_t st; } __attribute__((packed)) unalign;
|
||||||
|
|
||||||
|
MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign*)ptr)->u16; }
|
||||||
|
MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
|
||||||
|
MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign*)ptr)->u64; }
|
||||||
|
MEM_STATIC U64 MEM_readST(const void* ptr) { return ((const unalign*)ptr)->st; }
|
||||||
|
|
||||||
|
MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; }
|
||||||
|
MEM_STATIC void MEM_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u32 = value; }
|
||||||
|
MEM_STATIC void MEM_write64(void* memPtr, U64 value) { ((unalign*)memPtr)->u64 = value; }
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* default method, safe and standard.
|
||||||
|
can sometimes prove slower */
|
||||||
|
|
||||||
|
MEM_STATIC U16 MEM_read16(const void* memPtr)
|
||||||
|
{
|
||||||
|
U16 val; memcpy(&val, memPtr, sizeof(val)); return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC U32 MEM_read32(const void* memPtr)
|
||||||
|
{
|
||||||
|
U32 val; memcpy(&val, memPtr, sizeof(val)); return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC U64 MEM_read64(const void* memPtr)
|
||||||
|
{
|
||||||
|
U64 val; memcpy(&val, memPtr, sizeof(val)); return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC size_t MEM_readST(const void* memPtr)
|
||||||
|
{
|
||||||
|
size_t val; memcpy(&val, memPtr, sizeof(val)); return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC void MEM_write16(void* memPtr, U16 value)
|
||||||
|
{
|
||||||
|
memcpy(memPtr, &value, sizeof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC void MEM_write32(void* memPtr, U32 value)
|
||||||
|
{
|
||||||
|
memcpy(memPtr, &value, sizeof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC void MEM_write64(void* memPtr, U64 value)
|
||||||
|
{
|
||||||
|
memcpy(memPtr, &value, sizeof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MEM_FORCE_MEMORY_ACCESS */
|
||||||
|
|
||||||
|
MEM_STATIC U32 MEM_swap32(U32 in)
|
||||||
|
{
|
||||||
|
#if defined(_MSC_VER) /* Visual Studio */
|
||||||
|
return _byteswap_ulong(in);
|
||||||
|
#elif defined (__GNUC__)
|
||||||
|
return __builtin_bswap32(in);
|
||||||
|
#else
|
||||||
|
return ((in << 24) & 0xff000000 ) |
|
||||||
|
((in << 8) & 0x00ff0000 ) |
|
||||||
|
((in >> 8) & 0x0000ff00 ) |
|
||||||
|
((in >> 24) & 0x000000ff );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC U64 MEM_swap64(U64 in)
|
||||||
|
{
|
||||||
|
#if defined(_MSC_VER) /* Visual Studio */
|
||||||
|
return _byteswap_uint64(in);
|
||||||
|
#elif defined (__GNUC__)
|
||||||
|
return __builtin_bswap64(in);
|
||||||
|
#else
|
||||||
|
return ((in << 56) & 0xff00000000000000ULL) |
|
||||||
|
((in << 40) & 0x00ff000000000000ULL) |
|
||||||
|
((in << 24) & 0x0000ff0000000000ULL) |
|
||||||
|
((in << 8) & 0x000000ff00000000ULL) |
|
||||||
|
((in >> 8) & 0x00000000ff000000ULL) |
|
||||||
|
((in >> 24) & 0x0000000000ff0000ULL) |
|
||||||
|
((in >> 40) & 0x000000000000ff00ULL) |
|
||||||
|
((in >> 56) & 0x00000000000000ffULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC size_t MEM_swapST(size_t in)
|
||||||
|
{
|
||||||
|
if (MEM_32bits())
|
||||||
|
return (size_t)MEM_swap32((U32)in);
|
||||||
|
else
|
||||||
|
return (size_t)MEM_swap64((U64)in);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=== Little endian r/w ===*/
|
||||||
|
|
||||||
|
MEM_STATIC U16 MEM_readLE16(const void* memPtr)
|
||||||
|
{
|
||||||
|
if (MEM_isLittleEndian())
|
||||||
|
return MEM_read16(memPtr);
|
||||||
|
else {
|
||||||
|
const BYTE* p = (const BYTE*)memPtr;
|
||||||
|
return (U16)(p[0] + (p[1]<<8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
|
||||||
|
{
|
||||||
|
if (MEM_isLittleEndian()) {
|
||||||
|
MEM_write16(memPtr, val);
|
||||||
|
} else {
|
||||||
|
BYTE* p = (BYTE*)memPtr;
|
||||||
|
p[0] = (BYTE)val;
|
||||||
|
p[1] = (BYTE)(val>>8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC U32 MEM_readLE32(const void* memPtr)
|
||||||
|
{
|
||||||
|
if (MEM_isLittleEndian())
|
||||||
|
return MEM_read32(memPtr);
|
||||||
|
else
|
||||||
|
return MEM_swap32(MEM_read32(memPtr));
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32)
|
||||||
|
{
|
||||||
|
if (MEM_isLittleEndian())
|
||||||
|
MEM_write32(memPtr, val32);
|
||||||
|
else
|
||||||
|
MEM_write32(memPtr, MEM_swap32(val32));
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC U64 MEM_readLE64(const void* memPtr)
|
||||||
|
{
|
||||||
|
if (MEM_isLittleEndian())
|
||||||
|
return MEM_read64(memPtr);
|
||||||
|
else
|
||||||
|
return MEM_swap64(MEM_read64(memPtr));
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64)
|
||||||
|
{
|
||||||
|
if (MEM_isLittleEndian())
|
||||||
|
MEM_write64(memPtr, val64);
|
||||||
|
else
|
||||||
|
MEM_write64(memPtr, MEM_swap64(val64));
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC size_t MEM_readLEST(const void* memPtr)
|
||||||
|
{
|
||||||
|
if (MEM_32bits())
|
||||||
|
return (size_t)MEM_readLE32(memPtr);
|
||||||
|
else
|
||||||
|
return (size_t)MEM_readLE64(memPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val)
|
||||||
|
{
|
||||||
|
if (MEM_32bits())
|
||||||
|
MEM_writeLE32(memPtr, (U32)val);
|
||||||
|
else
|
||||||
|
MEM_writeLE64(memPtr, (U64)val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=== Big endian r/w ===*/
|
||||||
|
|
||||||
|
MEM_STATIC U32 MEM_readBE32(const void* memPtr)
|
||||||
|
{
|
||||||
|
if (MEM_isLittleEndian())
|
||||||
|
return MEM_swap32(MEM_read32(memPtr));
|
||||||
|
else
|
||||||
|
return MEM_read32(memPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32)
|
||||||
|
{
|
||||||
|
if (MEM_isLittleEndian())
|
||||||
|
MEM_write32(memPtr, MEM_swap32(val32));
|
||||||
|
else
|
||||||
|
MEM_write32(memPtr, val32);
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC U64 MEM_readBE64(const void* memPtr)
|
||||||
|
{
|
||||||
|
if (MEM_isLittleEndian())
|
||||||
|
return MEM_swap64(MEM_read64(memPtr));
|
||||||
|
else
|
||||||
|
return MEM_read64(memPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64)
|
||||||
|
{
|
||||||
|
if (MEM_isLittleEndian())
|
||||||
|
MEM_write64(memPtr, MEM_swap64(val64));
|
||||||
|
else
|
||||||
|
MEM_write64(memPtr, val64);
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC size_t MEM_readBEST(const void* memPtr)
|
||||||
|
{
|
||||||
|
if (MEM_32bits())
|
||||||
|
return (size_t)MEM_readBE32(memPtr);
|
||||||
|
else
|
||||||
|
return (size_t)MEM_readBE64(memPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val)
|
||||||
|
{
|
||||||
|
if (MEM_32bits())
|
||||||
|
MEM_writeBE32(memPtr, (U32)val);
|
||||||
|
else
|
||||||
|
MEM_writeBE64(memPtr, (U64)val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* function safe only for comparisons */
|
||||||
|
MEM_STATIC U32 MEM_readMINMATCH(const void* memPtr, U32 length)
|
||||||
|
{
|
||||||
|
switch (length)
|
||||||
|
{
|
||||||
|
default :
|
||||||
|
case 4 : return MEM_read32(memPtr);
|
||||||
|
case 3 : if (MEM_isLittleEndian())
|
||||||
|
return MEM_read32(memPtr)<<8;
|
||||||
|
else
|
||||||
|
return MEM_read32(memPtr)>>8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MEM_H_MODULE */
|
||||||
|
|
||||||
|
/* ******************************************************************
|
||||||
|
Error codes list
|
||||||
|
Copyright (C) 2016, 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 :
|
||||||
|
- Homepage : http://www.zstd.net
|
||||||
|
****************************************************************** */
|
||||||
|
#ifndef ERROR_PUBLIC_H_MODULE
|
||||||
|
#define ERROR_PUBLIC_H_MODULE
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ****************************************
|
||||||
|
* error codes list
|
||||||
|
******************************************/
|
||||||
|
typedef enum {
|
||||||
|
ZSTDv06_error_no_error,
|
||||||
|
ZSTDv06_error_GENERIC,
|
||||||
|
ZSTDv06_error_prefix_unknown,
|
||||||
|
ZSTDv06_error_frameParameter_unsupported,
|
||||||
|
ZSTDv06_error_frameParameter_unsupportedBy32bits,
|
||||||
|
ZSTDv06_error_compressionParameter_unsupported,
|
||||||
|
ZSTDv06_error_init_missing,
|
||||||
|
ZSTDv06_error_memory_allocation,
|
||||||
|
ZSTDv06_error_stage_wrong,
|
||||||
|
ZSTDv06_error_dstSize_tooSmall,
|
||||||
|
ZSTDv06_error_srcSize_wrong,
|
||||||
|
ZSTDv06_error_corruption_detected,
|
||||||
|
ZSTDv06_error_tableLog_tooLarge,
|
||||||
|
ZSTDv06_error_maxSymbolValue_tooLarge,
|
||||||
|
ZSTDv06_error_maxSymbolValue_tooSmall,
|
||||||
|
ZSTDv06_error_dictionary_corrupted,
|
||||||
|
ZSTDv06_error_maxCode
|
||||||
|
} ZSTDv06_ErrorCode;
|
||||||
|
|
||||||
|
/* note : compare with size_t function results using ZSTDv06_getError() */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ERROR_PUBLIC_H_MODULE */
|
||||||
|
/*
|
||||||
|
zstd - standard compression library
|
||||||
|
Header File for static linking only
|
||||||
|
Copyright (C) 2014-2016, 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 homepage : http://www.zstd.net
|
||||||
|
*/
|
||||||
|
#ifndef ZSTDv06_STATIC_H
|
||||||
|
#define ZSTDv06_STATIC_H
|
||||||
|
|
||||||
|
/* The prototypes defined within this file are considered experimental.
|
||||||
|
* They should not be used in the context DLL as they may change in the future.
|
||||||
|
* Prefer static linking if you need them, to control breaking version changes issues.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*- Advanced Decompression functions -*/
|
||||||
|
|
||||||
|
/*! ZSTDv06_decompress_usingPreparedDCtx() :
|
||||||
|
* Same as ZSTDv06_decompress_usingDict, but using a reference context `preparedDCtx`, where dictionary has been loaded.
|
||||||
|
* It avoids reloading the dictionary each time.
|
||||||
|
* `preparedDCtx` must have been properly initialized using ZSTDv06_decompressBegin_usingDict().
|
||||||
|
* Requires 2 contexts : 1 for reference (preparedDCtx), which will not be modified, and 1 to run the decompression operation (dctx) */
|
||||||
|
ZSTDLIB_API size_t ZSTDv06_decompress_usingPreparedDCtx(
|
||||||
|
ZSTDv06_DCtx* dctx, const ZSTDv06_DCtx* preparedDCtx,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct ZSTDv06_frameParams_s { U64 frameContentSize; U32 windowLog; };
|
||||||
|
|
||||||
|
#define ZSTDv06_FRAMEHEADERSIZE_MAX 13 /* for static allocation */
|
||||||
|
static const size_t ZSTDv06_frameHeaderSize_min = 5;
|
||||||
|
static const size_t ZSTDv06_frameHeaderSize_max = ZSTDv06_FRAMEHEADERSIZE_MAX;
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZSTDv06_decompressBegin(ZSTDv06_DCtx* dctx);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Streaming decompression, direct mode (bufferless)
|
||||||
|
|
||||||
|
A ZSTDv06_DCtx object is required to track streaming operations.
|
||||||
|
Use ZSTDv06_createDCtx() / ZSTDv06_freeDCtx() to manage it.
|
||||||
|
A ZSTDv06_DCtx object can be re-used multiple times.
|
||||||
|
|
||||||
|
First optional operation is to retrieve frame parameters, using ZSTDv06_getFrameParams(), which doesn't consume the input.
|
||||||
|
It can provide the minimum size of rolling buffer required to properly decompress data,
|
||||||
|
and optionally the final size of uncompressed content.
|
||||||
|
(Note : content size is an optional info that may not be present. 0 means : content size unknown)
|
||||||
|
Frame parameters are extracted from the beginning of compressed frame.
|
||||||
|
The amount of data to read is variable, from ZSTDv06_frameHeaderSize_min to ZSTDv06_frameHeaderSize_max (so if `srcSize` >= ZSTDv06_frameHeaderSize_max, it will always work)
|
||||||
|
If `srcSize` is too small for operation to succeed, function will return the minimum size it requires to produce a result.
|
||||||
|
Result : 0 when successful, it means the ZSTDv06_frameParams structure has been filled.
|
||||||
|
>0 : means there is not enough data into `src`. Provides the expected size to successfully decode header.
|
||||||
|
errorCode, which can be tested using ZSTDv06_isError()
|
||||||
|
|
||||||
|
Start decompression, with ZSTDv06_decompressBegin() or ZSTDv06_decompressBegin_usingDict().
|
||||||
|
Alternatively, you can copy a prepared context, using ZSTDv06_copyDCtx().
|
||||||
|
|
||||||
|
Then use ZSTDv06_nextSrcSizeToDecompress() and ZSTDv06_decompressContinue() alternatively.
|
||||||
|
ZSTDv06_nextSrcSizeToDecompress() tells how much bytes to provide as 'srcSize' to ZSTDv06_decompressContinue().
|
||||||
|
ZSTDv06_decompressContinue() requires this exact amount of bytes, or it will fail.
|
||||||
|
ZSTDv06_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.
|
||||||
|
|
||||||
|
@result of ZSTDv06_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity)
|
||||||
|
It can be zero, which is not an error; it just means ZSTDv06_decompressContinue() has decoded some header.
|
||||||
|
|
||||||
|
A frame is fully decoded when ZSTDv06_nextSrcSizeToDecompress() returns zero.
|
||||||
|
Context can then be reset to start a new decompression.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************************
|
||||||
|
* Block functions
|
||||||
|
****************************************/
|
||||||
|
/*! Block functions produce and decode raw zstd blocks, without frame metadata.
|
||||||
|
User will have to take in charge required information to regenerate data, such as compressed and content sizes.
|
||||||
|
|
||||||
|
A few rules to respect :
|
||||||
|
- Uncompressed block size must be <= ZSTDv06_BLOCKSIZE_MAX (128 KB)
|
||||||
|
- Compressing or decompressing requires a context structure
|
||||||
|
+ Use ZSTDv06_createCCtx() and ZSTDv06_createDCtx()
|
||||||
|
- It is necessary to init context before starting
|
||||||
|
+ compression : ZSTDv06_compressBegin()
|
||||||
|
+ decompression : ZSTDv06_decompressBegin()
|
||||||
|
+ variants _usingDict() are also allowed
|
||||||
|
+ copyCCtx() and copyDCtx() work too
|
||||||
|
- When a block is considered not compressible enough, ZSTDv06_compressBlock() result will be zero.
|
||||||
|
In which case, nothing is produced into `dst`.
|
||||||
|
+ User must test for such outcome and deal directly with uncompressed data
|
||||||
|
+ ZSTDv06_decompressBlock() doesn't accept uncompressed data as input !!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ZSTDv06_BLOCKSIZE_MAX (128 * 1024) /* define, for static allocation */
|
||||||
|
ZSTDLIB_API size_t ZSTDv06_decompressBlock(ZSTDv06_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
|
||||||
|
/*-*************************************
|
||||||
|
* Error management
|
||||||
|
***************************************/
|
||||||
|
/*! ZSTDv06_getErrorCode() :
|
||||||
|
convert a `size_t` function result into a `ZSTDv06_ErrorCode` enum type,
|
||||||
|
which can be used to compare directly with enum list published into "error_public.h" */
|
||||||
|
ZSTDLIB_API ZSTDv06_ErrorCode ZSTDv06_getErrorCode(size_t functionResult);
|
||||||
|
ZSTDLIB_API const char* ZSTDv06_getErrorString(ZSTDv06_ErrorCode code);
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ZSTDv06_STATIC_H */
|
||||||
|
/* ******************************************************************
|
||||||
|
Error codes and messages
|
||||||
|
Copyright (C) 2013-2016, 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 :
|
||||||
|
- Homepage : http://www.zstd.net
|
||||||
|
****************************************************************** */
|
||||||
|
/* Note : this module is expected to remain private, do not expose it */
|
||||||
|
|
||||||
|
#ifndef ERROR_H_MODULE
|
||||||
|
#define ERROR_H_MODULE
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ****************************************
|
||||||
|
* Compiler-specific
|
||||||
|
******************************************/
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
# define ERR_STATIC static __attribute__((unused))
|
||||||
|
#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
||||||
|
# define ERR_STATIC static inline
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
# define ERR_STATIC static __inline
|
||||||
|
#else
|
||||||
|
# define ERR_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*-****************************************
|
||||||
|
* Customization (error_public.h)
|
||||||
|
******************************************/
|
||||||
|
typedef ZSTDv06_ErrorCode ERR_enum;
|
||||||
|
#define PREFIX(name) ZSTDv06_error_##name
|
||||||
|
|
||||||
|
|
||||||
|
/*-****************************************
|
||||||
|
* Error codes handling
|
||||||
|
******************************************/
|
||||||
|
#ifdef ERROR
|
||||||
|
# undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */
|
||||||
|
#endif
|
||||||
|
#define ERROR(name) ((size_t)-PREFIX(name))
|
||||||
|
|
||||||
|
ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }
|
||||||
|
|
||||||
|
ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); }
|
||||||
|
|
||||||
|
|
||||||
|
/*-****************************************
|
||||||
|
* Error Strings
|
||||||
|
******************************************/
|
||||||
|
|
||||||
|
ERR_STATIC const char* ERR_getErrorString(ERR_enum code)
|
||||||
|
{
|
||||||
|
static const char* notErrorCode = "Unspecified error code";
|
||||||
|
switch( code )
|
||||||
|
{
|
||||||
|
case PREFIX(no_error): return "No error detected";
|
||||||
|
case PREFIX(GENERIC): return "Error (generic)";
|
||||||
|
case PREFIX(prefix_unknown): return "Unknown frame descriptor";
|
||||||
|
case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter";
|
||||||
|
case PREFIX(frameParameter_unsupportedBy32bits): return "Frame parameter unsupported in 32-bits mode";
|
||||||
|
case PREFIX(compressionParameter_unsupported): return "Compression parameter is out of bound";
|
||||||
|
case PREFIX(init_missing): return "Context should be init first";
|
||||||
|
case PREFIX(memory_allocation): return "Allocation error : not enough memory";
|
||||||
|
case PREFIX(stage_wrong): return "Operation not authorized at current processing stage";
|
||||||
|
case PREFIX(dstSize_tooSmall): return "Destination buffer is too small";
|
||||||
|
case PREFIX(srcSize_wrong): return "Src size incorrect";
|
||||||
|
case PREFIX(corruption_detected): return "Corrupted block detected";
|
||||||
|
case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported";
|
||||||
|
case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large";
|
||||||
|
case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small";
|
||||||
|
case PREFIX(dictionary_corrupted): return "Dictionary is corrupted";
|
||||||
|
case PREFIX(maxCode):
|
||||||
|
default: return notErrorCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ERR_STATIC const char* ERR_getErrorName(size_t code)
|
||||||
|
{
|
||||||
|
return ERR_getErrorString(ERR_getErrorCode(code));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ERROR_H_MODULE */
|
||||||
|
/*
|
||||||
|
zstd_internal - common functions to include
|
||||||
|
Header File for include
|
||||||
|
Copyright (C) 2014-2016, 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 homepage : https://www.zstd.net
|
||||||
|
*/
|
||||||
|
#ifndef ZSTDv06_CCOMMON_H_MODULE
|
||||||
|
#define ZSTDv06_CCOMMON_H_MODULE
|
||||||
|
|
||||||
|
|
||||||
|
/*-*************************************
|
||||||
|
* Common macros
|
||||||
|
***************************************/
|
||||||
|
#define MIN(a,b) ((a)<(b) ? (a) : (b))
|
||||||
|
#define MAX(a,b) ((a)>(b) ? (a) : (b))
|
||||||
|
|
||||||
|
|
||||||
|
/*-*************************************
|
||||||
|
* Common constants
|
||||||
|
***************************************/
|
||||||
|
#define ZSTDv06_OPT_DEBUG 0 // 3 = compression stats; 5 = check encoded sequences; 9 = full logs
|
||||||
|
#include <stdio.h>
|
||||||
|
#if defined(ZSTDv06_OPT_DEBUG) && ZSTDv06_OPT_DEBUG>=9
|
||||||
|
#define ZSTDv06_LOG_PARSER(...) printf(__VA_ARGS__)
|
||||||
|
#define ZSTDv06_LOG_ENCODE(...) printf(__VA_ARGS__)
|
||||||
|
#define ZSTDv06_LOG_BLOCK(...) printf(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define ZSTDv06_LOG_PARSER(...)
|
||||||
|
#define ZSTDv06_LOG_ENCODE(...)
|
||||||
|
#define ZSTDv06_LOG_BLOCK(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ZSTDv06_OPT_NUM (1<<12)
|
||||||
|
#define ZSTDv06_DICT_MAGIC 0xEC30A436
|
||||||
|
|
||||||
|
#define ZSTDv06_REP_NUM 3
|
||||||
|
#define ZSTDv06_REP_INIT ZSTDv06_REP_NUM
|
||||||
|
#define ZSTDv06_REP_MOVE (ZSTDv06_REP_NUM-1)
|
||||||
|
|
||||||
|
#define KB *(1 <<10)
|
||||||
|
#define MB *(1 <<20)
|
||||||
|
#define GB *(1U<<30)
|
||||||
|
|
||||||
|
#define BIT7 128
|
||||||
|
#define BIT6 64
|
||||||
|
#define BIT5 32
|
||||||
|
#define BIT4 16
|
||||||
|
#define BIT1 2
|
||||||
|
#define BIT0 1
|
||||||
|
|
||||||
|
#define ZSTDv06_WINDOWLOG_ABSOLUTEMIN 12
|
||||||
|
static const size_t ZSTDv06_fcs_fieldSize[4] = { 0, 1, 2, 8 };
|
||||||
|
|
||||||
|
#define ZSTDv06_BLOCKHEADERSIZE 3 /* because C standard does not allow a static const value to be defined using another static const value .... :( */
|
||||||
|
static const size_t ZSTDv06_blockHeaderSize = ZSTDv06_BLOCKHEADERSIZE;
|
||||||
|
typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t;
|
||||||
|
|
||||||
|
#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
|
||||||
|
#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */
|
||||||
|
|
||||||
|
#define HufLog 12
|
||||||
|
|
||||||
|
#define IS_HUF 0
|
||||||
|
#define IS_PCH 1
|
||||||
|
#define IS_RAW 2
|
||||||
|
#define IS_RLE 3
|
||||||
|
|
||||||
|
#define LONGNBSEQ 0x7F00
|
||||||
|
|
||||||
|
#define MINMATCH 3
|
||||||
|
#define EQUAL_READ32 4
|
||||||
|
#define REPCODE_STARTVALUE 1
|
||||||
|
|
||||||
|
#define Litbits 8
|
||||||
|
#define MaxLit ((1<<Litbits) - 1)
|
||||||
|
#define MaxML 52
|
||||||
|
#define MaxLL 35
|
||||||
|
#define MaxOff 28
|
||||||
|
#define MaxSeq MAX(MaxLL, MaxML) /* Assumption : MaxOff < MaxLL,MaxML */
|
||||||
|
#define MLFSELog 9
|
||||||
|
#define LLFSELog 9
|
||||||
|
#define OffFSELog 8
|
||||||
|
|
||||||
|
#define FSEv06_ENCODING_RAW 0
|
||||||
|
#define FSEv06_ENCODING_RLE 1
|
||||||
|
#define FSEv06_ENCODING_STATIC 2
|
||||||
|
#define FSEv06_ENCODING_DYNAMIC 3
|
||||||
|
|
||||||
|
static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9,10,11,12,
|
||||||
|
13,14,15,16 };
|
||||||
|
static const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1,
|
||||||
|
-1,-1,-1,-1 };
|
||||||
|
static const U32 LL_defaultNormLog = 6;
|
||||||
|
|
||||||
|
static const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7, 8, 9,10,11,
|
||||||
|
12,13,14,15,16 };
|
||||||
|
static const S16 ML_defaultNorm[MaxML+1] = { 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1 };
|
||||||
|
static const U32 ML_defaultNormLog = 6;
|
||||||
|
|
||||||
|
static const S16 OF_defaultNorm[MaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1 };
|
||||||
|
static const U32 OF_defaultNormLog = 5;
|
||||||
|
|
||||||
|
|
||||||
|
/*-*******************************************
|
||||||
|
* Shared functions to include for inlining
|
||||||
|
*********************************************/
|
||||||
|
static void ZSTDv06_copy8(void* dst, const void* src) { memcpy(dst, src, 8); }
|
||||||
|
#define COPY8(d,s) { ZSTDv06_copy8(d,s); d+=8; s+=8; }
|
||||||
|
|
||||||
|
/*! ZSTDv06_wildcopy() :
|
||||||
|
* custom version of memcpy(), can copy up to 7 bytes too many (8 bytes if length==0) */
|
||||||
|
#define WILDCOPY_OVERLENGTH 8
|
||||||
|
MEM_STATIC void ZSTDv06_wildcopy(void* dst, const void* src, size_t length)
|
||||||
|
{
|
||||||
|
const BYTE* ip = (const BYTE*)src;
|
||||||
|
BYTE* op = (BYTE*)dst;
|
||||||
|
BYTE* const oend = op + length;
|
||||||
|
do
|
||||||
|
COPY8(op, ip)
|
||||||
|
while (op < oend);
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC unsigned ZSTDv06_highbit(U32 val)
|
||||||
|
{
|
||||||
|
# if defined(_MSC_VER) /* Visual */
|
||||||
|
unsigned long r=0;
|
||||||
|
_BitScanReverse(&r, val);
|
||||||
|
return (unsigned)r;
|
||||||
|
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
|
||||||
|
return 31 - __builtin_clz(val);
|
||||||
|
# else /* Software version */
|
||||||
|
static const int DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
|
||||||
|
U32 v = val;
|
||||||
|
int r;
|
||||||
|
v |= v >> 1;
|
||||||
|
v |= v >> 2;
|
||||||
|
v |= v >> 4;
|
||||||
|
v |= v >> 8;
|
||||||
|
v |= v >> 16;
|
||||||
|
r = DeBruijnClz[(U32)(v * 0x07C4ACDDU) >> 27];
|
||||||
|
return r;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-*******************************************
|
||||||
|
* Private interfaces
|
||||||
|
*********************************************/
|
||||||
|
typedef struct {
|
||||||
|
U32 off;
|
||||||
|
U32 len;
|
||||||
|
} ZSTDv06_match_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
U32 price;
|
||||||
|
U32 off;
|
||||||
|
U32 mlen;
|
||||||
|
U32 litlen;
|
||||||
|
U32 rep[ZSTDv06_REP_INIT];
|
||||||
|
} ZSTDv06_optimal_t;
|
||||||
|
|
||||||
|
#if ZSTDv06_OPT_DEBUG == 3
|
||||||
|
#include ".debug/zstd_stats.h"
|
||||||
|
#else
|
||||||
|
typedef struct { U32 unused; } ZSTDv06_stats_t;
|
||||||
|
MEM_STATIC void ZSTDv06_statsPrint(ZSTDv06_stats_t* stats, U32 searchLength) { (void)stats; (void)searchLength; }
|
||||||
|
MEM_STATIC void ZSTDv06_statsInit(ZSTDv06_stats_t* stats) { (void)stats; }
|
||||||
|
MEM_STATIC void ZSTDv06_statsResetFreqs(ZSTDv06_stats_t* stats) { (void)stats; }
|
||||||
|
MEM_STATIC void ZSTDv06_statsUpdatePrices(ZSTDv06_stats_t* stats, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) { (void)stats; (void)litLength; (void)literals; (void)offset; (void)matchLength; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void* buffer;
|
||||||
|
U32* offsetStart;
|
||||||
|
U32* offset;
|
||||||
|
BYTE* offCodeStart;
|
||||||
|
BYTE* litStart;
|
||||||
|
BYTE* lit;
|
||||||
|
U16* litLengthStart;
|
||||||
|
U16* litLength;
|
||||||
|
BYTE* llCodeStart;
|
||||||
|
U16* matchLengthStart;
|
||||||
|
U16* matchLength;
|
||||||
|
BYTE* mlCodeStart;
|
||||||
|
U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
|
||||||
|
U32 longLengthPos;
|
||||||
|
/* opt */
|
||||||
|
ZSTDv06_optimal_t* priceTable;
|
||||||
|
ZSTDv06_match_t* matchTable;
|
||||||
|
U32* matchLengthFreq;
|
||||||
|
U32* litLengthFreq;
|
||||||
|
U32* litFreq;
|
||||||
|
U32* offCodeFreq;
|
||||||
|
U32 matchLengthSum;
|
||||||
|
U32 matchSum;
|
||||||
|
U32 litLengthSum;
|
||||||
|
U32 litSum;
|
||||||
|
U32 offCodeSum;
|
||||||
|
U32 log2matchLengthSum;
|
||||||
|
U32 log2matchSum;
|
||||||
|
U32 log2litLengthSum;
|
||||||
|
U32 log2litSum;
|
||||||
|
U32 log2offCodeSum;
|
||||||
|
U32 factor;
|
||||||
|
U32 cachedPrice;
|
||||||
|
U32 cachedLitLength;
|
||||||
|
const BYTE* cachedLiterals;
|
||||||
|
ZSTDv06_stats_t stats;
|
||||||
|
} seqStore_t;
|
||||||
|
|
||||||
|
void ZSTDv06_seqToCodes(const seqStore_t* seqStorePtr, size_t const nbSeq);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ZSTDv06_CCOMMON_H_MODULE */
|
||||||
|
/* ******************************************************************
|
||||||
|
FSE : Finite State Entropy codec
|
||||||
|
Public Prototypes declaration
|
||||||
|
Copyright (C) 2013-2016, 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 :
|
||||||
|
- Source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||||
|
****************************************************************** */
|
||||||
|
#ifndef FSEv06_H
|
||||||
|
#define FSEv06_H
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-****************************************
|
||||||
|
* FSE simple functions
|
||||||
|
******************************************/
|
||||||
|
/*! FSEv06_decompress():
|
||||||
|
Decompress FSE data from buffer 'cSrc', of size 'cSrcSize',
|
||||||
|
into already allocated destination buffer 'dst', of size 'dstCapacity'.
|
||||||
|
@return : size of regenerated data (<= maxDstSize),
|
||||||
|
or an error code, which can be tested using FSEv06_isError() .
|
||||||
|
|
||||||
|
** Important ** : FSEv06_decompress() does not decompress non-compressible nor RLE data !!!
|
||||||
|
Why ? : making this distinction requires a header.
|
||||||
|
Header management is intentionally delegated to the user layer, which can better manage special cases.
|
||||||
|
*/
|
||||||
|
size_t FSEv06_decompress(void* dst, size_t dstCapacity,
|
||||||
|
const void* cSrc, size_t cSrcSize);
|
||||||
|
|
||||||
|
|
||||||
|
/*-*****************************************
|
||||||
|
* Tool functions
|
||||||
|
******************************************/
|
||||||
|
size_t FSEv06_compressBound(size_t size); /* maximum compressed size */
|
||||||
|
|
||||||
|
/* Error Management */
|
||||||
|
unsigned FSEv06_isError(size_t code); /* tells if a return value is an error code */
|
||||||
|
const char* FSEv06_getErrorName(size_t code); /* provides error code string (useful for debugging) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-*****************************************
|
||||||
|
* FSE detailed API
|
||||||
|
******************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
FSEv06_decompress() does the following:
|
||||||
|
1. read normalized counters with readNCount()
|
||||||
|
2. build decoding table 'DTable' from normalized counters
|
||||||
|
3. decode the data stream using decoding table 'DTable'
|
||||||
|
|
||||||
|
The following API allows targeting specific sub-functions for advanced tasks.
|
||||||
|
For example, it's possible to compress several blocks using the same 'CTable',
|
||||||
|
or to save and provide normalized distribution using external method.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* *** DECOMPRESSION *** */
|
||||||
|
|
||||||
|
/*! FSEv06_readNCount():
|
||||||
|
Read compactly saved 'normalizedCounter' from 'rBuffer'.
|
||||||
|
@return : size read from 'rBuffer',
|
||||||
|
or an errorCode, which can be tested using FSEv06_isError().
|
||||||
|
maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */
|
||||||
|
size_t FSEv06_readNCount (short* normalizedCounter, unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, const void* rBuffer, size_t rBuffSize);
|
||||||
|
|
||||||
|
/*! Constructor and Destructor of FSEv06_DTable.
|
||||||
|
Note that its size depends on 'tableLog' */
|
||||||
|
typedef unsigned FSEv06_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */
|
||||||
|
FSEv06_DTable* FSEv06_createDTable(unsigned tableLog);
|
||||||
|
void FSEv06_freeDTable(FSEv06_DTable* dt);
|
||||||
|
|
||||||
|
/*! FSEv06_buildDTable():
|
||||||
|
Builds 'dt', which must be already allocated, using FSEv06_createDTable().
|
||||||
|
return : 0, or an errorCode, which can be tested using FSEv06_isError() */
|
||||||
|
size_t FSEv06_buildDTable (FSEv06_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
|
||||||
|
|
||||||
|
/*! FSEv06_decompress_usingDTable():
|
||||||
|
Decompress compressed source `cSrc` of size `cSrcSize` using `dt`
|
||||||
|
into `dst` which must be already allocated.
|
||||||
|
@return : size of regenerated data (necessarily <= `dstCapacity`),
|
||||||
|
or an errorCode, which can be tested using FSEv06_isError() */
|
||||||
|
size_t FSEv06_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSEv06_DTable* dt);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Tutorial :
|
||||||
|
----------
|
||||||
|
(Note : these functions only decompress FSE-compressed blocks.
|
||||||
|
If block is uncompressed, use memcpy() instead
|
||||||
|
If block is a single repeated byte, use memset() instead )
|
||||||
|
|
||||||
|
The first step is to obtain the normalized frequencies of symbols.
|
||||||
|
This can be performed by FSEv06_readNCount() if it was saved using FSEv06_writeNCount().
|
||||||
|
'normalizedCounter' must be already allocated, and have at least 'maxSymbolValuePtr[0]+1' cells of signed short.
|
||||||
|
In practice, that means it's necessary to know 'maxSymbolValue' beforehand,
|
||||||
|
or size the table to handle worst case situations (typically 256).
|
||||||
|
FSEv06_readNCount() will provide 'tableLog' and 'maxSymbolValue'.
|
||||||
|
The result of FSEv06_readNCount() is the number of bytes read from 'rBuffer'.
|
||||||
|
Note that 'rBufferSize' must be at least 4 bytes, even if useful information is less than that.
|
||||||
|
If there is an error, the function will return an error code, which can be tested using FSEv06_isError().
|
||||||
|
|
||||||
|
The next step is to build the decompression tables 'FSEv06_DTable' from 'normalizedCounter'.
|
||||||
|
This is performed by the function FSEv06_buildDTable().
|
||||||
|
The space required by 'FSEv06_DTable' must be already allocated using FSEv06_createDTable().
|
||||||
|
If there is an error, the function will return an error code, which can be tested using FSEv06_isError().
|
||||||
|
|
||||||
|
`FSEv06_DTable` can then be used to decompress `cSrc`, with FSEv06_decompress_usingDTable().
|
||||||
|
`cSrcSize` must be strictly correct, otherwise decompression will fail.
|
||||||
|
FSEv06_decompress_usingDTable() result will tell how many bytes were regenerated (<=`dstCapacity`).
|
||||||
|
If there is an error, the function will return an error code, which can be tested using FSEv06_isError(). (ex: dst buffer too small)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* FSEv06_H */
|
||||||
|
/* ******************************************************************
|
||||||
|
bitstream
|
||||||
|
Part of FSE library
|
||||||
|
header file (to include)
|
||||||
|
Copyright (C) 2013-2016, 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 :
|
||||||
|
- Source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||||
|
****************************************************************** */
|
||||||
|
#ifndef BITSTREAM_H_MODULE
|
||||||
|
#define BITSTREAM_H_MODULE
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This API consists of small unitary functions, which must be inlined for best performance.
|
||||||
|
* Since link-time-optimization is not available for all compilers,
|
||||||
|
* these functions are defined into a .h to be included.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*=========================================
|
||||||
|
* Target specific
|
||||||
|
=========================================*/
|
||||||
|
#if defined(__BMI__) && defined(__GNUC__)
|
||||||
|
# include <immintrin.h> /* support for bextr (experimental) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-********************************************
|
||||||
|
* bitStream decoding API (read backward)
|
||||||
|
**********************************************/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
size_t bitContainer;
|
||||||
|
unsigned bitsConsumed;
|
||||||
|
const char* ptr;
|
||||||
|
const char* start;
|
||||||
|
} BITv06_DStream_t;
|
||||||
|
|
||||||
|
typedef enum { BITv06_DStream_unfinished = 0,
|
||||||
|
BITv06_DStream_endOfBuffer = 1,
|
||||||
|
BITv06_DStream_completed = 2,
|
||||||
|
BITv06_DStream_overflow = 3 } BITv06_DStream_status; /* result of BITv06_reloadDStream() */
|
||||||
|
/* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */
|
||||||
|
|
||||||
|
MEM_STATIC size_t BITv06_initDStream(BITv06_DStream_t* bitD, const void* srcBuffer, size_t srcSize);
|
||||||
|
MEM_STATIC size_t BITv06_readBits(BITv06_DStream_t* bitD, unsigned nbBits);
|
||||||
|
MEM_STATIC BITv06_DStream_status BITv06_reloadDStream(BITv06_DStream_t* bitD);
|
||||||
|
MEM_STATIC unsigned BITv06_endOfDStream(const BITv06_DStream_t* bitD);
|
||||||
|
|
||||||
|
|
||||||
|
/* Start by invoking BITv06_initDStream().
|
||||||
|
* A chunk of the bitStream is then stored into a local register.
|
||||||
|
* Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t).
|
||||||
|
* You can then retrieve bitFields stored into the local register, **in reverse order**.
|
||||||
|
* Local register is explicitly reloaded from memory by the BITv06_reloadDStream() method.
|
||||||
|
* A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BITv06_DStream_unfinished.
|
||||||
|
* Otherwise, it can be less than that, so proceed accordingly.
|
||||||
|
* Checking if DStream has reached its end can be performed with BITv06_endOfDStream().
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*-****************************************
|
||||||
|
* unsafe API
|
||||||
|
******************************************/
|
||||||
|
MEM_STATIC size_t BITv06_readBitsFast(BITv06_DStream_t* bitD, unsigned nbBits);
|
||||||
|
/* faster, but works only if nbBits >= 1 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-**************************************************************
|
||||||
|
* Internal functions
|
||||||
|
****************************************************************/
|
||||||
|
MEM_STATIC unsigned BITv06_highbit32 (register U32 val)
|
||||||
|
{
|
||||||
|
# if defined(_MSC_VER) /* Visual */
|
||||||
|
unsigned long r=0;
|
||||||
|
_BitScanReverse ( &r, val );
|
||||||
|
return (unsigned) r;
|
||||||
|
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
|
||||||
|
return 31 - __builtin_clz (val);
|
||||||
|
# else /* Software version */
|
||||||
|
static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
|
||||||
|
U32 v = val;
|
||||||
|
unsigned r;
|
||||||
|
v |= v >> 1;
|
||||||
|
v |= v >> 2;
|
||||||
|
v |= v >> 4;
|
||||||
|
v |= v >> 8;
|
||||||
|
v |= v >> 16;
|
||||||
|
r = DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
|
||||||
|
return r;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===== Local Constants =====*/
|
||||||
|
static const unsigned BITv06_mask[] = { 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF }; /* up to 26 bits */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-********************************************************
|
||||||
|
* bitStream decoding
|
||||||
|
**********************************************************/
|
||||||
|
/*! BITv06_initDStream() :
|
||||||
|
* Initialize a BITv06_DStream_t.
|
||||||
|
* `bitD` : a pointer to an already allocated BITv06_DStream_t structure.
|
||||||
|
* `srcSize` must be the *exact* size of the bitStream, in bytes.
|
||||||
|
* @return : size of stream (== srcSize) or an errorCode if a problem is detected
|
||||||
|
*/
|
||||||
|
MEM_STATIC size_t BITv06_initDStream(BITv06_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
|
||||||
|
{
|
||||||
|
if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
|
||||||
|
|
||||||
|
if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */
|
||||||
|
bitD->start = (const char*)srcBuffer;
|
||||||
|
bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
|
||||||
|
bitD->bitContainer = MEM_readLEST(bitD->ptr);
|
||||||
|
{ BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
|
||||||
|
if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */
|
||||||
|
bitD->bitsConsumed = 8 - BITv06_highbit32(lastByte); }
|
||||||
|
} else {
|
||||||
|
bitD->start = (const char*)srcBuffer;
|
||||||
|
bitD->ptr = bitD->start;
|
||||||
|
bitD->bitContainer = *(const BYTE*)(bitD->start);
|
||||||
|
switch(srcSize)
|
||||||
|
{
|
||||||
|
case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
|
||||||
|
case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
|
||||||
|
case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
|
||||||
|
case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
|
||||||
|
case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
|
||||||
|
case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
|
||||||
|
default:;
|
||||||
|
}
|
||||||
|
{ BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
|
||||||
|
if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */
|
||||||
|
bitD->bitsConsumed = 8 - BITv06_highbit32(lastByte); }
|
||||||
|
bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
|
||||||
|
}
|
||||||
|
|
||||||
|
return srcSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC size_t BITv06_getUpperBits(size_t bitContainer, U32 const start)
|
||||||
|
{
|
||||||
|
return bitContainer >> start;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC size_t BITv06_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
|
||||||
|
{
|
||||||
|
#if defined(__BMI__) && defined(__GNUC__) /* experimental */
|
||||||
|
# if defined(__x86_64__)
|
||||||
|
if (sizeof(bitContainer)==8)
|
||||||
|
return _bextr_u64(bitContainer, start, nbBits);
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
return _bextr_u32(bitContainer, start, nbBits);
|
||||||
|
#else
|
||||||
|
return (bitContainer >> start) & BITv06_mask[nbBits];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC size_t BITv06_getLowerBits(size_t bitContainer, U32 const nbBits)
|
||||||
|
{
|
||||||
|
return bitContainer & BITv06_mask[nbBits];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! BITv06_lookBits() :
|
||||||
|
* Provides next n bits from local register.
|
||||||
|
* local register is not modified.
|
||||||
|
* On 32-bits, maxNbBits==24.
|
||||||
|
* On 64-bits, maxNbBits==56.
|
||||||
|
* @return : value extracted
|
||||||
|
*/
|
||||||
|
MEM_STATIC size_t BITv06_lookBits(const BITv06_DStream_t* bitD, U32 nbBits)
|
||||||
|
{
|
||||||
|
#if defined(__BMI__) && defined(__GNUC__) /* experimental; fails if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8 */
|
||||||
|
return BITv06_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits);
|
||||||
|
#else
|
||||||
|
U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1;
|
||||||
|
return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask-nbBits) & bitMask);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! BITv06_lookBitsFast() :
|
||||||
|
* unsafe version; only works only if nbBits >= 1 */
|
||||||
|
MEM_STATIC size_t BITv06_lookBitsFast(const BITv06_DStream_t* bitD, U32 nbBits)
|
||||||
|
{
|
||||||
|
U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1;
|
||||||
|
return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask+1)-nbBits) & bitMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC void BITv06_skipBits(BITv06_DStream_t* bitD, U32 nbBits)
|
||||||
|
{
|
||||||
|
bitD->bitsConsumed += nbBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! BITv06_readBits() :
|
||||||
|
* Read (consume) next n bits from local register and update.
|
||||||
|
* Pay attention to not read more than nbBits contained into local register.
|
||||||
|
* @return : extracted value.
|
||||||
|
*/
|
||||||
|
MEM_STATIC size_t BITv06_readBits(BITv06_DStream_t* bitD, U32 nbBits)
|
||||||
|
{
|
||||||
|
size_t const value = BITv06_lookBits(bitD, nbBits);
|
||||||
|
BITv06_skipBits(bitD, nbBits);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! BITv06_readBitsFast() :
|
||||||
|
* unsafe version; only works only if nbBits >= 1 */
|
||||||
|
MEM_STATIC size_t BITv06_readBitsFast(BITv06_DStream_t* bitD, U32 nbBits)
|
||||||
|
{
|
||||||
|
size_t const value = BITv06_lookBitsFast(bitD, nbBits);
|
||||||
|
BITv06_skipBits(bitD, nbBits);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! BITv06_reloadDStream() :
|
||||||
|
* Refill `BITv06_DStream_t` from src buffer previously defined (see BITv06_initDStream() ).
|
||||||
|
* This function is safe, it guarantees it will not read beyond src buffer.
|
||||||
|
* @return : status of `BITv06_DStream_t` internal register.
|
||||||
|
if status == unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */
|
||||||
|
MEM_STATIC BITv06_DStream_status BITv06_reloadDStream(BITv06_DStream_t* bitD)
|
||||||
|
{
|
||||||
|
if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should never happen */
|
||||||
|
return BITv06_DStream_overflow;
|
||||||
|
|
||||||
|
if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) {
|
||||||
|
bitD->ptr -= bitD->bitsConsumed >> 3;
|
||||||
|
bitD->bitsConsumed &= 7;
|
||||||
|
bitD->bitContainer = MEM_readLEST(bitD->ptr);
|
||||||
|
return BITv06_DStream_unfinished;
|
||||||
|
}
|
||||||
|
if (bitD->ptr == bitD->start) {
|
||||||
|
if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BITv06_DStream_endOfBuffer;
|
||||||
|
return BITv06_DStream_completed;
|
||||||
|
}
|
||||||
|
{ U32 nbBytes = bitD->bitsConsumed >> 3;
|
||||||
|
BITv06_DStream_status result = BITv06_DStream_unfinished;
|
||||||
|
if (bitD->ptr - nbBytes < bitD->start) {
|
||||||
|
nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */
|
||||||
|
result = BITv06_DStream_endOfBuffer;
|
||||||
|
}
|
||||||
|
bitD->ptr -= nbBytes;
|
||||||
|
bitD->bitsConsumed -= nbBytes*8;
|
||||||
|
bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD) */
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! BITv06_endOfDStream() :
|
||||||
|
* @return Tells if DStream has exactly reached its end (all bits consumed).
|
||||||
|
*/
|
||||||
|
MEM_STATIC unsigned BITv06_endOfDStream(const BITv06_DStream_t* DStream)
|
||||||
|
{
|
||||||
|
return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* BITSTREAM_H_MODULE */
|
||||||
|
/* ******************************************************************
|
||||||
|
FSE : Finite State Entropy coder
|
||||||
|
header file for static linking (only)
|
||||||
|
Copyright (C) 2013-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 :
|
||||||
|
- Source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||||
|
- Public forum : https://groups.google.com/forum/#!forum/lz4c
|
||||||
|
****************************************************************** */
|
||||||
|
#ifndef FSEv06_STATIC_H
|
||||||
|
#define FSEv06_STATIC_H
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* *****************************************
|
||||||
|
* Static allocation
|
||||||
|
*******************************************/
|
||||||
|
/* FSE buffer bounds */
|
||||||
|
#define FSEv06_NCOUNTBOUND 512
|
||||||
|
#define FSEv06_BLOCKBOUND(size) (size + (size>>7))
|
||||||
|
#define FSEv06_COMPRESSBOUND(size) (FSEv06_NCOUNTBOUND + FSEv06_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
|
||||||
|
|
||||||
|
/* It is possible to statically allocate FSE CTable/DTable as a table of unsigned using below macros */
|
||||||
|
#define FSEv06_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<maxTableLog))
|
||||||
|
|
||||||
|
|
||||||
|
/* *****************************************
|
||||||
|
* FSE advanced API
|
||||||
|
*******************************************/
|
||||||
|
size_t FSEv06_countFast(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);
|
||||||
|
/* same as FSEv06_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr */
|
||||||
|
|
||||||
|
size_t FSEv06_buildDTable_raw (FSEv06_DTable* dt, unsigned nbBits);
|
||||||
|
/* build a fake FSEv06_DTable, designed to read an uncompressed bitstream where each symbol uses nbBits */
|
||||||
|
|
||||||
|
size_t FSEv06_buildDTable_rle (FSEv06_DTable* dt, unsigned char symbolValue);
|
||||||
|
/* build a fake FSEv06_DTable, designed to always generate the same symbolValue */
|
||||||
|
|
||||||
|
|
||||||
|
/* *****************************************
|
||||||
|
* FSE symbol decompression API
|
||||||
|
*******************************************/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
size_t state;
|
||||||
|
const void* table; /* precise table may vary, depending on U16 */
|
||||||
|
} FSEv06_DState_t;
|
||||||
|
|
||||||
|
|
||||||
|
static void FSEv06_initDState(FSEv06_DState_t* DStatePtr, BITv06_DStream_t* bitD, const FSEv06_DTable* dt);
|
||||||
|
|
||||||
|
static unsigned char FSEv06_decodeSymbol(FSEv06_DState_t* DStatePtr, BITv06_DStream_t* bitD);
|
||||||
|
|
||||||
|
static unsigned FSEv06_endOfDState(const FSEv06_DState_t* DStatePtr);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Let's now decompose FSEv06_decompress_usingDTable() into its unitary components.
|
||||||
|
You will decode FSE-encoded symbols from the bitStream,
|
||||||
|
and also any other bitFields you put in, **in reverse order**.
|
||||||
|
|
||||||
|
You will need a few variables to track your bitStream. They are :
|
||||||
|
|
||||||
|
BITv06_DStream_t DStream; // Stream context
|
||||||
|
FSEv06_DState_t DState; // State context. Multiple ones are possible
|
||||||
|
FSEv06_DTable* DTablePtr; // Decoding table, provided by FSEv06_buildDTable()
|
||||||
|
|
||||||
|
The first thing to do is to init the bitStream.
|
||||||
|
errorCode = BITv06_initDStream(&DStream, srcBuffer, srcSize);
|
||||||
|
|
||||||
|
You should then retrieve your initial state(s)
|
||||||
|
(in reverse flushing order if you have several ones) :
|
||||||
|
errorCode = FSEv06_initDState(&DState, &DStream, DTablePtr);
|
||||||
|
|
||||||
|
You can then decode your data, symbol after symbol.
|
||||||
|
For information the maximum number of bits read by FSEv06_decodeSymbol() is 'tableLog'.
|
||||||
|
Keep in mind that symbols are decoded in reverse order, like a LIFO stack (last in, first out).
|
||||||
|
unsigned char symbol = FSEv06_decodeSymbol(&DState, &DStream);
|
||||||
|
|
||||||
|
You can retrieve any bitfield you eventually stored into the bitStream (in reverse order)
|
||||||
|
Note : maximum allowed nbBits is 25, for 32-bits compatibility
|
||||||
|
size_t bitField = BITv06_readBits(&DStream, nbBits);
|
||||||
|
|
||||||
|
All above operations only read from local register (which size depends on size_t).
|
||||||
|
Refueling the register from memory is manually performed by the reload method.
|
||||||
|
endSignal = FSEv06_reloadDStream(&DStream);
|
||||||
|
|
||||||
|
BITv06_reloadDStream() result tells if there is still some more data to read from DStream.
|
||||||
|
BITv06_DStream_unfinished : there is still some data left into the DStream.
|
||||||
|
BITv06_DStream_endOfBuffer : Dstream reached end of buffer. Its container may no longer be completely filled.
|
||||||
|
BITv06_DStream_completed : Dstream reached its exact end, corresponding in general to decompression completed.
|
||||||
|
BITv06_DStream_tooFar : Dstream went too far. Decompression result is corrupted.
|
||||||
|
|
||||||
|
When reaching end of buffer (BITv06_DStream_endOfBuffer), progress slowly, notably if you decode multiple symbols per loop,
|
||||||
|
to properly detect the exact end of stream.
|
||||||
|
After each decoded symbol, check if DStream is fully consumed using this simple test :
|
||||||
|
BITv06_reloadDStream(&DStream) >= BITv06_DStream_completed
|
||||||
|
|
||||||
|
When it's done, verify decompression is fully completed, by checking both DStream and the relevant states.
|
||||||
|
Checking if DStream has reached its end is performed by :
|
||||||
|
BITv06_endOfDStream(&DStream);
|
||||||
|
Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible.
|
||||||
|
FSEv06_endOfDState(&DState);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* *****************************************
|
||||||
|
* FSE unsafe API
|
||||||
|
*******************************************/
|
||||||
|
static unsigned char FSEv06_decodeSymbolFast(FSEv06_DState_t* DStatePtr, BITv06_DStream_t* bitD);
|
||||||
|
/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */
|
||||||
|
|
||||||
|
|
||||||
|
/* *****************************************
|
||||||
|
* Implementation of inlined functions
|
||||||
|
*******************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*<===== Decompression =====>*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
U16 tableLog;
|
||||||
|
U16 fastMode;
|
||||||
|
} FSEv06_DTableHeader; /* sizeof U32 */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned short newState;
|
||||||
|
unsigned char symbol;
|
||||||
|
unsigned char nbBits;
|
||||||
|
} FSEv06_decode_t; /* size == U32 */
|
||||||
|
|
||||||
|
MEM_STATIC void FSEv06_initDState(FSEv06_DState_t* DStatePtr, BITv06_DStream_t* bitD, const FSEv06_DTable* dt)
|
||||||
|
{
|
||||||
|
const void* ptr = dt;
|
||||||
|
const FSEv06_DTableHeader* const DTableH = (const FSEv06_DTableHeader*)ptr;
|
||||||
|
DStatePtr->state = BITv06_readBits(bitD, DTableH->tableLog);
|
||||||
|
BITv06_reloadDStream(bitD);
|
||||||
|
DStatePtr->table = dt + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC BYTE FSEv06_peekSymbol(const FSEv06_DState_t* DStatePtr)
|
||||||
|
{
|
||||||
|
FSEv06_decode_t const DInfo = ((const FSEv06_decode_t*)(DStatePtr->table))[DStatePtr->state];
|
||||||
|
return DInfo.symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC void FSEv06_updateState(FSEv06_DState_t* DStatePtr, BITv06_DStream_t* bitD)
|
||||||
|
{
|
||||||
|
FSEv06_decode_t const DInfo = ((const FSEv06_decode_t*)(DStatePtr->table))[DStatePtr->state];
|
||||||
|
U32 const nbBits = DInfo.nbBits;
|
||||||
|
size_t const lowBits = BITv06_readBits(bitD, nbBits);
|
||||||
|
DStatePtr->state = DInfo.newState + lowBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC BYTE FSEv06_decodeSymbol(FSEv06_DState_t* DStatePtr, BITv06_DStream_t* bitD)
|
||||||
|
{
|
||||||
|
FSEv06_decode_t const DInfo = ((const FSEv06_decode_t*)(DStatePtr->table))[DStatePtr->state];
|
||||||
|
U32 const nbBits = DInfo.nbBits;
|
||||||
|
BYTE const symbol = DInfo.symbol;
|
||||||
|
size_t const lowBits = BITv06_readBits(bitD, nbBits);
|
||||||
|
|
||||||
|
DStatePtr->state = DInfo.newState + lowBits;
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! FSEv06_decodeSymbolFast() :
|
||||||
|
unsafe, only works if no symbol has a probability > 50% */
|
||||||
|
MEM_STATIC BYTE FSEv06_decodeSymbolFast(FSEv06_DState_t* DStatePtr, BITv06_DStream_t* bitD)
|
||||||
|
{
|
||||||
|
FSEv06_decode_t const DInfo = ((const FSEv06_decode_t*)(DStatePtr->table))[DStatePtr->state];
|
||||||
|
U32 const nbBits = DInfo.nbBits;
|
||||||
|
BYTE const symbol = DInfo.symbol;
|
||||||
|
size_t const lowBits = BITv06_readBitsFast(bitD, nbBits);
|
||||||
|
|
||||||
|
DStatePtr->state = DInfo.newState + lowBits;
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_STATIC unsigned FSEv06_endOfDState(const FSEv06_DState_t* DStatePtr)
|
||||||
|
{
|
||||||
|
return DStatePtr->state == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FSEv06_COMMONDEFS_ONLY
|
||||||
|
|
||||||
|
/* **************************************************************
|
||||||
|
* 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
|
||||||
|
* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */
|
||||||
|
#define FSEv06_MAX_MEMORY_USAGE 14
|
||||||
|
#define FSEv06_DEFAULT_MEMORY_USAGE 13
|
||||||
|
|
||||||
|
/*!FSEv06_MAX_SYMBOL_VALUE :
|
||||||
|
* Maximum symbol value authorized.
|
||||||
|
* Required for proper stack allocation */
|
||||||
|
#define FSEv06_MAX_SYMBOL_VALUE 255
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************************************************
|
||||||
|
* template functions type & suffix
|
||||||
|
****************************************************************/
|
||||||
|
#define FSEv06_FUNCTION_TYPE BYTE
|
||||||
|
#define FSEv06_FUNCTION_EXTENSION
|
||||||
|
#define FSEv06_DECODE_TYPE FSEv06_decode_t
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* !FSEv06_COMMONDEFS_ONLY */
|
||||||
|
|
||||||
|
|
||||||
|
/* ***************************************************************
|
||||||
|
* Constants
|
||||||
|
*****************************************************************/
|
||||||
|
#define FSEv06_MAX_TABLELOG (FSEv06_MAX_MEMORY_USAGE-2)
|
||||||
|
#define FSEv06_MAX_TABLESIZE (1U<<FSEv06_MAX_TABLELOG)
|
||||||
|
#define FSEv06_MAXTABLESIZE_MASK (FSEv06_MAX_TABLESIZE-1)
|
||||||
|
#define FSEv06_DEFAULT_TABLELOG (FSEv06_DEFAULT_MEMORY_USAGE-2)
|
||||||
|
#define FSEv06_MIN_TABLELOG 5
|
||||||
|
|
||||||
|
#define FSEv06_TABLELOG_ABSOLUTE_MAX 15
|
||||||
|
#if FSEv06_MAX_TABLELOG > FSEv06_TABLELOG_ABSOLUTE_MAX
|
||||||
|
#error "FSEv06_MAX_TABLELOG > FSEv06_TABLELOG_ABSOLUTE_MAX is not supported"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FSEv06_TABLESTEP(tableSize) ((tableSize>>1) + (tableSize>>3) + 3)
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* FSEv06_STATIC_H */
|
||||||
|
/*
|
||||||
|
Common functions of New Generation Entropy library
|
||||||
|
Copyright (C) 2016, 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 :
|
||||||
|
- FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||||
|
- Public forum : https://groups.google.com/forum/#!forum/lz4c
|
||||||
|
*************************************************************************** */
|
||||||
|
|
||||||
|
|
||||||
|
/*-****************************************
|
||||||
|
* FSE Error Management
|
||||||
|
******************************************/
|
||||||
|
unsigned FSEv06_isError(size_t code) { return ERR_isError(code); }
|
||||||
|
|
||||||
|
const char* FSEv06_getErrorName(size_t code) { return ERR_getErrorName(code); }
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************************************************
|
||||||
|
* HUF Error Management
|
||||||
|
****************************************************************/
|
||||||
|
unsigned HUFv06_isError(size_t code) { return ERR_isError(code); }
|
||||||
|
|
||||||
|
const char* HUFv06_getErrorName(size_t code) { return ERR_getErrorName(code); }
|
||||||
|
|
||||||
|
|
||||||
|
/*-**************************************************************
|
||||||
|
* FSE NCount encoding-decoding
|
||||||
|
****************************************************************/
|
||||||
|
static short FSEv06_abs(short a) { return a<0 ? -a : a; }
|
||||||
|
|
||||||
|
size_t FSEv06_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
|
||||||
|
const void* headerBuffer, size_t hbSize)
|
||||||
|
{
|
||||||
|
const BYTE* const istart = (const BYTE*) headerBuffer;
|
||||||
|
const BYTE* const iend = istart + hbSize;
|
||||||
|
const BYTE* ip = istart;
|
||||||
|
int nbBits;
|
||||||
|
int remaining;
|
||||||
|
int threshold;
|
||||||
|
U32 bitStream;
|
||||||
|
int bitCount;
|
||||||
|
unsigned charnum = 0;
|
||||||
|
int previous0 = 0;
|
||||||
|
|
||||||
|
if (hbSize < 4) return ERROR(srcSize_wrong);
|
||||||
|
bitStream = MEM_readLE32(ip);
|
||||||
|
nbBits = (bitStream & 0xF) + FSEv06_MIN_TABLELOG; /* extract tableLog */
|
||||||
|
if (nbBits > FSEv06_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge);
|
||||||
|
bitStream >>= 4;
|
||||||
|
bitCount = 4;
|
||||||
|
*tableLogPtr = nbBits;
|
||||||
|
remaining = (1<<nbBits)+1;
|
||||||
|
threshold = 1<<nbBits;
|
||||||
|
nbBits++;
|
||||||
|
|
||||||
|
while ((remaining>1) && (charnum<=*maxSVPtr)) {
|
||||||
|
if (previous0) {
|
||||||
|
unsigned n0 = charnum;
|
||||||
|
while ((bitStream & 0xFFFF) == 0xFFFF) {
|
||||||
|
n0+=24;
|
||||||
|
if (ip < iend-5) {
|
||||||
|
ip+=2;
|
||||||
|
bitStream = MEM_readLE32(ip) >> bitCount;
|
||||||
|
} else {
|
||||||
|
bitStream >>= 16;
|
||||||
|
bitCount+=16;
|
||||||
|
} }
|
||||||
|
while ((bitStream & 3) == 3) {
|
||||||
|
n0+=3;
|
||||||
|
bitStream>>=2;
|
||||||
|
bitCount+=2;
|
||||||
|
}
|
||||||
|
n0 += bitStream & 3;
|
||||||
|
bitCount += 2;
|
||||||
|
if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall);
|
||||||
|
while (charnum < n0) normalizedCounter[charnum++] = 0;
|
||||||
|
if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
|
||||||
|
ip += bitCount>>3;
|
||||||
|
bitCount &= 7;
|
||||||
|
bitStream = MEM_readLE32(ip) >> bitCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bitStream >>= 2;
|
||||||
|
}
|
||||||
|
{ short const max = (short)((2*threshold-1)-remaining);
|
||||||
|
short count;
|
||||||
|
|
||||||
|
if ((bitStream & (threshold-1)) < (U32)max) {
|
||||||
|
count = (short)(bitStream & (threshold-1));
|
||||||
|
bitCount += nbBits-1;
|
||||||
|
} else {
|
||||||
|
count = (short)(bitStream & (2*threshold-1));
|
||||||
|
if (count >= threshold) count -= max;
|
||||||
|
bitCount += nbBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
count--; /* extra accuracy */
|
||||||
|
remaining -= FSEv06_abs(count);
|
||||||
|
normalizedCounter[charnum++] = count;
|
||||||
|
previous0 = !count;
|
||||||
|
while (remaining < threshold) {
|
||||||
|
nbBits--;
|
||||||
|
threshold >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
|
||||||
|
ip += bitCount>>3;
|
||||||
|
bitCount &= 7;
|
||||||
|
} else {
|
||||||
|
bitCount -= (int)(8 * (iend - 4 - ip));
|
||||||
|
ip = iend - 4;
|
||||||
|
}
|
||||||
|
bitStream = MEM_readLE32(ip) >> (bitCount & 31);
|
||||||
|
} } /* while ((remaining>1) && (charnum<=*maxSVPtr)) */
|
||||||
|
if (remaining != 1) return ERROR(GENERIC);
|
||||||
|
*maxSVPtr = charnum-1;
|
||||||
|
|
||||||
|
ip += (bitCount+7)>>3;
|
||||||
|
if ((size_t)(ip-istart) > hbSize) return ERROR(srcSize_wrong);
|
||||||
|
return ip-istart;
|
||||||
|
}
|
||||||
|
/* ******************************************************************
|
||||||
|
FSE : Finite State Entropy decoder
|
||||||
|
Copyright (C) 2013-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 :
|
||||||
|
- FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||||
|
- Public forum : https://groups.google.com/forum/#!forum/lz4c
|
||||||
|
****************************************************************** */
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************************************************
|
||||||
|
* Compiler specifics
|
||||||
|
****************************************************************/
|
||||||
|
#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 : 4214) /* disable: C4214: non-int bitfields */
|
||||||
|
#else
|
||||||
|
# ifdef __GNUC__
|
||||||
|
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||||
|
# define FORCE_INLINE static inline __attribute__((always_inline))
|
||||||
|
# else
|
||||||
|
# define FORCE_INLINE static inline
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************************************************
|
||||||
|
* Error Management
|
||||||
|
****************************************************************/
|
||||||
|
#define FSEv06_isError ERR_isError
|
||||||
|
#define FSEv06_STATIC_ASSERT(c) { enum { FSEv06_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************************************************
|
||||||
|
* Complex types
|
||||||
|
****************************************************************/
|
||||||
|
typedef U32 DTable_max_t[FSEv06_DTABLE_SIZE_U32(FSEv06_MAX_TABLELOG)];
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************************************************
|
||||||
|
* Templates
|
||||||
|
****************************************************************/
|
||||||
|
/*
|
||||||
|
designed to be included
|
||||||
|
for type-specific functions (template emulation in C)
|
||||||
|
Objective is to write these functions only once, for improved maintenance
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* safety checks */
|
||||||
|
#ifndef FSEv06_FUNCTION_EXTENSION
|
||||||
|
# error "FSEv06_FUNCTION_EXTENSION must be defined"
|
||||||
|
#endif
|
||||||
|
#ifndef FSEv06_FUNCTION_TYPE
|
||||||
|
# error "FSEv06_FUNCTION_TYPE must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Function names */
|
||||||
|
#define FSEv06_CAT(X,Y) X##Y
|
||||||
|
#define FSEv06_FUNCTION_NAME(X,Y) FSEv06_CAT(X,Y)
|
||||||
|
#define FSEv06_TYPE_NAME(X,Y) FSEv06_CAT(X,Y)
|
||||||
|
|
||||||
|
|
||||||
|
/* Function templates */
|
||||||
|
FSEv06_DTable* FSEv06_createDTable (unsigned tableLog)
|
||||||
|
{
|
||||||
|
if (tableLog > FSEv06_TABLELOG_ABSOLUTE_MAX) tableLog = FSEv06_TABLELOG_ABSOLUTE_MAX;
|
||||||
|
return (FSEv06_DTable*)malloc( FSEv06_DTABLE_SIZE_U32(tableLog) * sizeof (U32) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSEv06_freeDTable (FSEv06_DTable* dt)
|
||||||
|
{
|
||||||
|
free(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FSEv06_buildDTable(FSEv06_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
|
||||||
|
{
|
||||||
|
void* const tdPtr = dt+1; /* because *dt is unsigned, 32-bits aligned on 32-bits */
|
||||||
|
FSEv06_DECODE_TYPE* const tableDecode = (FSEv06_DECODE_TYPE*) (tdPtr);
|
||||||
|
U16 symbolNext[FSEv06_MAX_SYMBOL_VALUE+1];
|
||||||
|
|
||||||
|
U32 const maxSV1 = maxSymbolValue + 1;
|
||||||
|
U32 const tableSize = 1 << tableLog;
|
||||||
|
U32 highThreshold = tableSize-1;
|
||||||
|
|
||||||
|
/* Sanity Checks */
|
||||||
|
if (maxSymbolValue > FSEv06_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge);
|
||||||
|
if (tableLog > FSEv06_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
|
||||||
|
|
||||||
|
/* Init, lay down lowprob symbols */
|
||||||
|
{ FSEv06_DTableHeader DTableH;
|
||||||
|
DTableH.tableLog = (U16)tableLog;
|
||||||
|
DTableH.fastMode = 1;
|
||||||
|
{ S16 const largeLimit= (S16)(1 << (tableLog-1));
|
||||||
|
U32 s;
|
||||||
|
for (s=0; s<maxSV1; s++) {
|
||||||
|
if (normalizedCounter[s]==-1) {
|
||||||
|
tableDecode[highThreshold--].symbol = (FSEv06_FUNCTION_TYPE)s;
|
||||||
|
symbolNext[s] = 1;
|
||||||
|
} else {
|
||||||
|
if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;
|
||||||
|
symbolNext[s] = normalizedCounter[s];
|
||||||
|
} } }
|
||||||
|
memcpy(dt, &DTableH, sizeof(DTableH));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Spread symbols */
|
||||||
|
{ U32 const tableMask = tableSize-1;
|
||||||
|
U32 const step = FSEv06_TABLESTEP(tableSize);
|
||||||
|
U32 s, position = 0;
|
||||||
|
for (s=0; s<maxSV1; s++) {
|
||||||
|
int i;
|
||||||
|
for (i=0; i<normalizedCounter[s]; i++) {
|
||||||
|
tableDecode[position].symbol = (FSEv06_FUNCTION_TYPE)s;
|
||||||
|
position = (position + step) & tableMask;
|
||||||
|
while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */
|
||||||
|
} }
|
||||||
|
|
||||||
|
if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build Decoding table */
|
||||||
|
{ U32 u;
|
||||||
|
for (u=0; u<tableSize; u++) {
|
||||||
|
FSEv06_FUNCTION_TYPE const symbol = (FSEv06_FUNCTION_TYPE)(tableDecode[u].symbol);
|
||||||
|
U16 nextState = symbolNext[symbol]++;
|
||||||
|
tableDecode[u].nbBits = (BYTE) (tableLog - BITv06_highbit32 ((U32)nextState) );
|
||||||
|
tableDecode[u].newState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize);
|
||||||
|
} }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FSEv06_COMMONDEFS_ONLY
|
||||||
|
|
||||||
|
/*-*******************************************************
|
||||||
|
* Decompression (Byte symbols)
|
||||||
|
*********************************************************/
|
||||||
|
size_t FSEv06_buildDTable_rle (FSEv06_DTable* dt, BYTE symbolValue)
|
||||||
|
{
|
||||||
|
void* ptr = dt;
|
||||||
|
FSEv06_DTableHeader* const DTableH = (FSEv06_DTableHeader*)ptr;
|
||||||
|
void* dPtr = dt + 1;
|
||||||
|
FSEv06_decode_t* const cell = (FSEv06_decode_t*)dPtr;
|
||||||
|
|
||||||
|
DTableH->tableLog = 0;
|
||||||
|
DTableH->fastMode = 0;
|
||||||
|
|
||||||
|
cell->newState = 0;
|
||||||
|
cell->symbol = symbolValue;
|
||||||
|
cell->nbBits = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t FSEv06_buildDTable_raw (FSEv06_DTable* dt, unsigned nbBits)
|
||||||
|
{
|
||||||
|
void* ptr = dt;
|
||||||
|
FSEv06_DTableHeader* const DTableH = (FSEv06_DTableHeader*)ptr;
|
||||||
|
void* dPtr = dt + 1;
|
||||||
|
FSEv06_decode_t* const dinfo = (FSEv06_decode_t*)dPtr;
|
||||||
|
const unsigned tableSize = 1 << nbBits;
|
||||||
|
const unsigned tableMask = tableSize - 1;
|
||||||
|
const unsigned maxSV1 = tableMask+1;
|
||||||
|
unsigned s;
|
||||||
|
|
||||||
|
/* Sanity checks */
|
||||||
|
if (nbBits < 1) return ERROR(GENERIC); /* min size */
|
||||||
|
|
||||||
|
/* Build Decoding Table */
|
||||||
|
DTableH->tableLog = (U16)nbBits;
|
||||||
|
DTableH->fastMode = 1;
|
||||||
|
for (s=0; s<maxSV1; s++) {
|
||||||
|
dinfo[s].newState = 0;
|
||||||
|
dinfo[s].symbol = (BYTE)s;
|
||||||
|
dinfo[s].nbBits = (BYTE)nbBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE size_t FSEv06_decompress_usingDTable_generic(
|
||||||
|
void* dst, size_t maxDstSize,
|
||||||
|
const void* cSrc, size_t cSrcSize,
|
||||||
|
const FSEv06_DTable* dt, const unsigned fast)
|
||||||
|
{
|
||||||
|
BYTE* const ostart = (BYTE*) dst;
|
||||||
|
BYTE* op = ostart;
|
||||||
|
BYTE* const omax = op + maxDstSize;
|
||||||
|
BYTE* const olimit = omax-3;
|
||||||
|
|
||||||
|
BITv06_DStream_t bitD;
|
||||||
|
FSEv06_DState_t state1;
|
||||||
|
FSEv06_DState_t state2;
|
||||||
|
|
||||||
|
/* Init */
|
||||||
|
{ size_t const errorCode = BITv06_initDStream(&bitD, cSrc, cSrcSize); /* replaced last arg by maxCompressed Size */
|
||||||
|
if (FSEv06_isError(errorCode)) return errorCode; }
|
||||||
|
|
||||||
|
FSEv06_initDState(&state1, &bitD, dt);
|
||||||
|
FSEv06_initDState(&state2, &bitD, dt);
|
||||||
|
|
||||||
|
#define FSEv06_GETSYMBOL(statePtr) fast ? FSEv06_decodeSymbolFast(statePtr, &bitD) : FSEv06_decodeSymbol(statePtr, &bitD)
|
||||||
|
|
||||||
|
/* 4 symbols per loop */
|
||||||
|
for ( ; (BITv06_reloadDStream(&bitD)==BITv06_DStream_unfinished) && (op<olimit) ; op+=4) {
|
||||||
|
op[0] = FSEv06_GETSYMBOL(&state1);
|
||||||
|
|
||||||
|
if (FSEv06_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
|
||||||
|
BITv06_reloadDStream(&bitD);
|
||||||
|
|
||||||
|
op[1] = FSEv06_GETSYMBOL(&state2);
|
||||||
|
|
||||||
|
if (FSEv06_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
|
||||||
|
{ if (BITv06_reloadDStream(&bitD) > BITv06_DStream_unfinished) { op+=2; break; } }
|
||||||
|
|
||||||
|
op[2] = FSEv06_GETSYMBOL(&state1);
|
||||||
|
|
||||||
|
if (FSEv06_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
|
||||||
|
BITv06_reloadDStream(&bitD);
|
||||||
|
|
||||||
|
op[3] = FSEv06_GETSYMBOL(&state2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tail */
|
||||||
|
/* note : BITv06_reloadDStream(&bitD) >= FSEv06_DStream_partiallyFilled; Ends at exactly BITv06_DStream_completed */
|
||||||
|
while (1) {
|
||||||
|
if (op>(omax-2)) return ERROR(dstSize_tooSmall);
|
||||||
|
|
||||||
|
*op++ = FSEv06_GETSYMBOL(&state1);
|
||||||
|
|
||||||
|
if (BITv06_reloadDStream(&bitD)==BITv06_DStream_overflow) {
|
||||||
|
*op++ = FSEv06_GETSYMBOL(&state2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op>(omax-2)) return ERROR(dstSize_tooSmall);
|
||||||
|
|
||||||
|
*op++ = FSEv06_GETSYMBOL(&state2);
|
||||||
|
|
||||||
|
if (BITv06_reloadDStream(&bitD)==BITv06_DStream_overflow) {
|
||||||
|
*op++ = FSEv06_GETSYMBOL(&state1);
|
||||||
|
break;
|
||||||
|
} }
|
||||||
|
|
||||||
|
return op-ostart;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t FSEv06_decompress_usingDTable(void* dst, size_t originalSize,
|
||||||
|
const void* cSrc, size_t cSrcSize,
|
||||||
|
const FSEv06_DTable* dt)
|
||||||
|
{
|
||||||
|
const void* ptr = dt;
|
||||||
|
const FSEv06_DTableHeader* DTableH = (const FSEv06_DTableHeader*)ptr;
|
||||||
|
const U32 fastMode = DTableH->fastMode;
|
||||||
|
|
||||||
|
/* select fast mode (static) */
|
||||||
|
if (fastMode) return FSEv06_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1);
|
||||||
|
return FSEv06_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t FSEv06_decompress(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize)
|
||||||
|
{
|
||||||
|
const BYTE* const istart = (const BYTE*)cSrc;
|
||||||
|
const BYTE* ip = istart;
|
||||||
|
short counting[FSEv06_MAX_SYMBOL_VALUE+1];
|
||||||
|
DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */
|
||||||
|
unsigned tableLog;
|
||||||
|
unsigned maxSymbolValue = FSEv06_MAX_SYMBOL_VALUE;
|
||||||
|
|
||||||
|
if (cSrcSize<2) return ERROR(srcSize_wrong); /* too small input size */
|
||||||
|
|
||||||
|
/* normal FSE decoding mode */
|
||||||
|
{ size_t const NCountLength = FSEv06_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize);
|
||||||
|
if (FSEv06_isError(NCountLength)) return NCountLength;
|
||||||
|
if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size */
|
||||||
|
ip += NCountLength;
|
||||||
|
cSrcSize -= NCountLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
{ size_t const errorCode = FSEv06_buildDTable (dt, counting, maxSymbolValue, tableLog);
|
||||||
|
if (FSEv06_isError(errorCode)) return errorCode; }
|
||||||
|
|
||||||
|
return FSEv06_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, dt); /* always return, even if it is an error code */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* FSEv06_COMMONDEFS_ONLY */
|
||||||
|
/* ******************************************************************
|
||||||
|
Huffman coder, part of New Generation Entropy library
|
||||||
|
header file
|
||||||
|
Copyright (C) 2013-2016, 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 :
|
||||||
|
- Source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||||
|
****************************************************************** */
|
||||||
|
#ifndef HUFv06_H
|
||||||
|
#define HUFv06_H
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ****************************************
|
||||||
|
* HUF simple functions
|
||||||
|
******************************************/
|
||||||
|
size_t HUFv06_decompress(void* dst, size_t dstSize,
|
||||||
|
const void* cSrc, size_t cSrcSize);
|
||||||
|
/*
|
||||||
|
HUFv06_decompress() :
|
||||||
|
Decompress HUF data from buffer 'cSrc', of size 'cSrcSize',
|
||||||
|
into already allocated destination buffer 'dst', of size 'dstSize'.
|
||||||
|
`dstSize` : must be the **exact** size of original (uncompressed) data.
|
||||||
|
Note : in contrast with FSE, HUFv06_decompress can regenerate
|
||||||
|
RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data,
|
||||||
|
because it knows size to regenerate.
|
||||||
|
@return : size of regenerated data (== dstSize)
|
||||||
|
or an error code, which can be tested using HUFv06_isError()
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* ****************************************
|
||||||
|
* Tool functions
|
||||||
|
******************************************/
|
||||||
|
size_t HUFv06_compressBound(size_t size); /**< maximum compressed size */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HUFv06_H */
|
||||||
|
/* ******************************************************************
|
||||||
|
Huffman codec, part of New Generation Entropy library
|
||||||
|
header file, for static linking only
|
||||||
|
Copyright (C) 2013-2016, 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 :
|
||||||
|
- Source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||||
|
****************************************************************** */
|
||||||
|
#ifndef HUFv06_STATIC_H
|
||||||
|
#define HUFv06_STATIC_H
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ****************************************
|
||||||
|
* Static allocation
|
||||||
|
******************************************/
|
||||||
|
/* HUF buffer bounds */
|
||||||
|
#define HUFv06_CTABLEBOUND 129
|
||||||
|
#define HUFv06_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true if incompressible pre-filtered with fast heuristic */
|
||||||
|
#define HUFv06_COMPRESSBOUND(size) (HUFv06_CTABLEBOUND + HUFv06_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
|
||||||
|
|
||||||
|
/* static allocation of HUF's DTable */
|
||||||
|
#define HUFv06_DTABLE_SIZE(maxTableLog) (1 + (1<<maxTableLog))
|
||||||
|
#define HUFv06_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \
|
||||||
|
unsigned short DTable[HUFv06_DTABLE_SIZE(maxTableLog)] = { maxTableLog }
|
||||||
|
#define HUFv06_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) \
|
||||||
|
unsigned int DTable[HUFv06_DTABLE_SIZE(maxTableLog)] = { maxTableLog }
|
||||||
|
#define HUFv06_CREATE_STATIC_DTABLEX6(DTable, maxTableLog) \
|
||||||
|
unsigned int DTable[HUFv06_DTABLE_SIZE(maxTableLog) * 3 / 2] = { maxTableLog }
|
||||||
|
|
||||||
|
|
||||||
|
/* ****************************************
|
||||||
|
* Advanced decompression functions
|
||||||
|
******************************************/
|
||||||
|
size_t HUFv06_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */
|
||||||
|
size_t HUFv06_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbols decoder */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
HUFv06_decompress() does the following:
|
||||||
|
1. select the decompression algorithm (X2, X4, X6) based on pre-computed heuristics
|
||||||
|
2. build Huffman table from save, using HUFv06_readDTableXn()
|
||||||
|
3. decode 1 or 4 segments in parallel using HUFv06_decompressSXn_usingDTable
|
||||||
|
*/
|
||||||
|
size_t HUFv06_readDTableX2 (unsigned short* DTable, const void* src, size_t srcSize);
|
||||||
|
size_t HUFv06_readDTableX4 (unsigned* DTable, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
size_t HUFv06_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned short* DTable);
|
||||||
|
size_t HUFv06_decompress4X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned* DTable);
|
||||||
|
|
||||||
|
|
||||||
|
/* single stream variants */
|
||||||
|
size_t HUFv06_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */
|
||||||
|
size_t HUFv06_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */
|
||||||
|
|
||||||
|
size_t HUFv06_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned short* DTable);
|
||||||
|
size_t HUFv06_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned* DTable);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************************************************
|
||||||
|
* Constants
|
||||||
|
****************************************************************/
|
||||||
|
#define HUFv06_ABSOLUTEMAX_TABLELOG 16 /* absolute limit of HUFv06_MAX_TABLELOG. Beyond that value, code does not work */
|
||||||
|
#define HUFv06_MAX_TABLELOG 12 /* max configured tableLog (for static allocation); can be modified up to HUFv06_ABSOLUTEMAX_TABLELOG */
|
||||||
|
#define HUFv06_DEFAULT_TABLELOG HUFv06_MAX_TABLELOG /* tableLog by default, when not specified */
|
||||||
|
#define HUFv06_MAX_SYMBOL_VALUE 255
|
||||||
|
#if (HUFv06_MAX_TABLELOG > HUFv06_ABSOLUTEMAX_TABLELOG)
|
||||||
|
# error "HUFv06_MAX_TABLELOG is too large !"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! HUFv06_readStats() :
|
||||||
|
Read compact Huffman tree, saved by HUFv06_writeCTable().
|
||||||
|
`huffWeight` is destination buffer.
|
||||||
|
@return : size read from `src`
|
||||||
|
*/
|
||||||
|
MEM_STATIC size_t HUFv06_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
||||||
|
U32* nbSymbolsPtr, U32* tableLogPtr,
|
||||||
|
const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
U32 weightTotal;
|
||||||
|
const BYTE* ip = (const BYTE*) src;
|
||||||
|
size_t iSize = ip[0];
|
||||||
|
size_t oSize;
|
||||||
|
|
||||||
|
//memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
|
if (iSize >= 128) { /* special header */
|
||||||
|
if (iSize >= (242)) { /* RLE */
|
||||||
|
static U32 l[14] = { 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 127, 128 };
|
||||||
|
oSize = l[iSize-242];
|
||||||
|
memset(huffWeight, 1, hwSize);
|
||||||
|
iSize = 0;
|
||||||
|
}
|
||||||
|
else { /* Incompressible */
|
||||||
|
oSize = iSize - 127;
|
||||||
|
iSize = ((oSize+1)/2);
|
||||||
|
if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
|
||||||
|
if (oSize >= hwSize) return ERROR(corruption_detected);
|
||||||
|
ip += 1;
|
||||||
|
{ U32 n;
|
||||||
|
for (n=0; n<oSize; n+=2) {
|
||||||
|
huffWeight[n] = ip[n/2] >> 4;
|
||||||
|
huffWeight[n+1] = ip[n/2] & 15;
|
||||||
|
} } } }
|
||||||
|
else { /* header compressed with FSE (normal case) */
|
||||||
|
if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
|
||||||
|
oSize = FSEv06_decompress(huffWeight, hwSize-1, ip+1, iSize); /* max (hwSize-1) values decoded, as last one is implied */
|
||||||
|
if (FSEv06_isError(oSize)) return oSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* collect weight stats */
|
||||||
|
memset(rankStats, 0, (HUFv06_ABSOLUTEMAX_TABLELOG + 1) * sizeof(U32));
|
||||||
|
weightTotal = 0;
|
||||||
|
{ U32 n; for (n=0; n<oSize; n++) {
|
||||||
|
if (huffWeight[n] >= HUFv06_ABSOLUTEMAX_TABLELOG) return ERROR(corruption_detected);
|
||||||
|
rankStats[huffWeight[n]]++;
|
||||||
|
weightTotal += (1 << huffWeight[n]) >> 1;
|
||||||
|
} }
|
||||||
|
|
||||||
|
/* get last non-null symbol weight (implied, total must be 2^n) */
|
||||||
|
{ U32 const tableLog = BITv06_highbit32(weightTotal) + 1;
|
||||||
|
if (tableLog > HUFv06_ABSOLUTEMAX_TABLELOG) return ERROR(corruption_detected);
|
||||||
|
*tableLogPtr = tableLog;
|
||||||
|
/* determine last weight */
|
||||||
|
{ U32 const total = 1 << tableLog;
|
||||||
|
U32 const rest = total - weightTotal;
|
||||||
|
U32 const verif = 1 << BITv06_highbit32(rest);
|
||||||
|
U32 const lastWeight = BITv06_highbit32(rest) + 1;
|
||||||
|
if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */
|
||||||
|
huffWeight[oSize] = (BYTE)lastWeight;
|
||||||
|
rankStats[lastWeight]++;
|
||||||
|
} }
|
||||||
|
|
||||||
|
/* check tree construction validity */
|
||||||
|
if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */
|
||||||
|
|
||||||
|
/* results */
|
||||||
|
*nbSymbolsPtr = (U32)(oSize+1);
|
||||||
|
return iSize+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HUFv06_STATIC_H */
|
||||||
|
/* ******************************************************************
|
||||||
|
Huffman decoder, part of New Generation Entropy library
|
||||||
|
Copyright (C) 2013-2016, 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 :
|
||||||
|
- FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||||
|
- Public forum : https://groups.google.com/forum/#!forum/lz4c
|
||||||
|
****************************************************************** */
|
||||||
|
|
||||||
|
/* **************************************************************
|
||||||
|
* Compiler specifics
|
||||||
|
****************************************************************/
|
||||||
|
#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
||||||
|
/* inline is defined */
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
# define inline __inline
|
||||||
|
#else
|
||||||
|
# define inline /* disable inline */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
|
# define FORCE_INLINE static __forceinline
|
||||||
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
|
#else
|
||||||
|
# ifdef __GNUC__
|
||||||
|
# define FORCE_INLINE static inline __attribute__((always_inline))
|
||||||
|
# else
|
||||||
|
# define FORCE_INLINE static inline
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************************************************
|
||||||
|
* Error Management
|
||||||
|
****************************************************************/
|
||||||
|
#define HUFv06_STATIC_ASSERT(c) { enum { HUFv06_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* *******************************************************
|
||||||
|
* HUF : Huffman block decompression
|
||||||
|
*********************************************************/
|
||||||
|
typedef struct { BYTE byte; BYTE nbBits; } HUFv06_DEltX2; /* single-symbol decoding */
|
||||||
|
|
||||||
|
typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUFv06_DEltX4; /* double-symbols decoding */
|
||||||
|
|
||||||
|
typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-***************************/
|
||||||
|
/* single-symbol decoding */
|
||||||
|
/*-***************************/
|
||||||
|
|
||||||
|
size_t HUFv06_readDTableX2 (U16* DTable, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
BYTE huffWeight[HUFv06_MAX_SYMBOL_VALUE + 1];
|
||||||
|
U32 rankVal[HUFv06_ABSOLUTEMAX_TABLELOG + 1]; /* large enough for values from 0 to 16 */
|
||||||
|
U32 tableLog = 0;
|
||||||
|
size_t iSize;
|
||||||
|
U32 nbSymbols = 0;
|
||||||
|
U32 n;
|
||||||
|
U32 nextRankStart;
|
||||||
|
void* const dtPtr = DTable + 1;
|
||||||
|
HUFv06_DEltX2* const dt = (HUFv06_DEltX2*)dtPtr;
|
||||||
|
|
||||||
|
HUFv06_STATIC_ASSERT(sizeof(HUFv06_DEltX2) == sizeof(U16)); /* if compilation fails here, assertion is false */
|
||||||
|
//memset(huffWeight, 0, sizeof(huffWeight)); /* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
|
iSize = HUFv06_readStats(huffWeight, HUFv06_MAX_SYMBOL_VALUE + 1, rankVal, &nbSymbols, &tableLog, src, srcSize);
|
||||||
|
if (HUFv06_isError(iSize)) return iSize;
|
||||||
|
|
||||||
|
/* check result */
|
||||||
|
if (tableLog > DTable[0]) return ERROR(tableLog_tooLarge); /* DTable is too small */
|
||||||
|
DTable[0] = (U16)tableLog; /* maybe should separate sizeof allocated DTable, from used size of DTable, in case of re-use */
|
||||||
|
|
||||||
|
/* Prepare ranks */
|
||||||
|
nextRankStart = 0;
|
||||||
|
for (n=1; n<tableLog+1; n++) {
|
||||||
|
U32 current = nextRankStart;
|
||||||
|
nextRankStart += (rankVal[n] << (n-1));
|
||||||
|
rankVal[n] = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill DTable */
|
||||||
|
for (n=0; n<nbSymbols; n++) {
|
||||||
|
const U32 w = huffWeight[n];
|
||||||
|
const U32 length = (1 << w) >> 1;
|
||||||
|
U32 i;
|
||||||
|
HUFv06_DEltX2 D;
|
||||||
|
D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w);
|
||||||
|
for (i = rankVal[w]; i < rankVal[w] + length; i++)
|
||||||
|
dt[i] = D;
|
||||||
|
rankVal[w] += length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return iSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static BYTE HUFv06_decodeSymbolX2(BITv06_DStream_t* Dstream, const HUFv06_DEltX2* dt, const U32 dtLog)
|
||||||
|
{
|
||||||
|
const size_t val = BITv06_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */
|
||||||
|
const BYTE c = dt[val].byte;
|
||||||
|
BITv06_skipBits(Dstream, dt[val].nbBits);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HUFv06_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \
|
||||||
|
*ptr++ = HUFv06_decodeSymbolX2(DStreamPtr, dt, dtLog)
|
||||||
|
|
||||||
|
#define HUFv06_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \
|
||||||
|
if (MEM_64bits() || (HUFv06_MAX_TABLELOG<=12)) \
|
||||||
|
HUFv06_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
|
||||||
|
|
||||||
|
#define HUFv06_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \
|
||||||
|
if (MEM_64bits()) \
|
||||||
|
HUFv06_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
|
||||||
|
|
||||||
|
static inline size_t HUFv06_decodeStreamX2(BYTE* p, BITv06_DStream_t* const bitDPtr, BYTE* const pEnd, const HUFv06_DEltX2* const dt, const U32 dtLog)
|
||||||
|
{
|
||||||
|
BYTE* const pStart = p;
|
||||||
|
|
||||||
|
/* up to 4 symbols at a time */
|
||||||
|
while ((BITv06_reloadDStream(bitDPtr) == BITv06_DStream_unfinished) && (p <= pEnd-4)) {
|
||||||
|
HUFv06_DECODE_SYMBOLX2_2(p, bitDPtr);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_1(p, bitDPtr);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_2(p, bitDPtr);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_0(p, bitDPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* closer to the end */
|
||||||
|
while ((BITv06_reloadDStream(bitDPtr) == BITv06_DStream_unfinished) && (p < pEnd))
|
||||||
|
HUFv06_DECODE_SYMBOLX2_0(p, bitDPtr);
|
||||||
|
|
||||||
|
/* no more data to retrieve from bitstream, hence no need to reload */
|
||||||
|
while (p < pEnd)
|
||||||
|
HUFv06_DECODE_SYMBOLX2_0(p, bitDPtr);
|
||||||
|
|
||||||
|
return pEnd-pStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HUFv06_decompress1X2_usingDTable(
|
||||||
|
void* dst, size_t dstSize,
|
||||||
|
const void* cSrc, size_t cSrcSize,
|
||||||
|
const U16* DTable)
|
||||||
|
{
|
||||||
|
BYTE* op = (BYTE*)dst;
|
||||||
|
BYTE* const oend = op + dstSize;
|
||||||
|
const U32 dtLog = DTable[0];
|
||||||
|
const void* dtPtr = DTable;
|
||||||
|
const HUFv06_DEltX2* const dt = ((const HUFv06_DEltX2*)dtPtr)+1;
|
||||||
|
BITv06_DStream_t bitD;
|
||||||
|
|
||||||
|
{ size_t const errorCode = BITv06_initDStream(&bitD, cSrc, cSrcSize);
|
||||||
|
if (HUFv06_isError(errorCode)) return errorCode; }
|
||||||
|
|
||||||
|
HUFv06_decodeStreamX2(op, &bitD, oend, dt, dtLog);
|
||||||
|
|
||||||
|
/* check */
|
||||||
|
if (!BITv06_endOfDStream(&bitD)) return ERROR(corruption_detected);
|
||||||
|
|
||||||
|
return dstSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HUFv06_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
|
{
|
||||||
|
HUFv06_CREATE_STATIC_DTABLEX2(DTable, HUFv06_MAX_TABLELOG);
|
||||||
|
const BYTE* ip = (const BYTE*) cSrc;
|
||||||
|
|
||||||
|
size_t const errorCode = HUFv06_readDTableX2 (DTable, cSrc, cSrcSize);
|
||||||
|
if (HUFv06_isError(errorCode)) return errorCode;
|
||||||
|
if (errorCode >= cSrcSize) return ERROR(srcSize_wrong);
|
||||||
|
ip += errorCode;
|
||||||
|
cSrcSize -= errorCode;
|
||||||
|
|
||||||
|
return HUFv06_decompress1X2_usingDTable (dst, dstSize, ip, cSrcSize, DTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t HUFv06_decompress4X2_usingDTable(
|
||||||
|
void* dst, size_t dstSize,
|
||||||
|
const void* cSrc, size_t cSrcSize,
|
||||||
|
const U16* DTable)
|
||||||
|
{
|
||||||
|
/* Check */
|
||||||
|
if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
|
||||||
|
|
||||||
|
{ const BYTE* const istart = (const BYTE*) cSrc;
|
||||||
|
BYTE* const ostart = (BYTE*) dst;
|
||||||
|
BYTE* const oend = ostart + dstSize;
|
||||||
|
const void* const dtPtr = DTable;
|
||||||
|
const HUFv06_DEltX2* const dt = ((const HUFv06_DEltX2*)dtPtr) +1;
|
||||||
|
const U32 dtLog = DTable[0];
|
||||||
|
size_t errorCode;
|
||||||
|
|
||||||
|
/* Init */
|
||||||
|
BITv06_DStream_t bitD1;
|
||||||
|
BITv06_DStream_t bitD2;
|
||||||
|
BITv06_DStream_t bitD3;
|
||||||
|
BITv06_DStream_t bitD4;
|
||||||
|
const size_t length1 = MEM_readLE16(istart);
|
||||||
|
const size_t length2 = MEM_readLE16(istart+2);
|
||||||
|
const size_t length3 = MEM_readLE16(istart+4);
|
||||||
|
size_t length4;
|
||||||
|
const BYTE* const istart1 = istart + 6; /* jumpTable */
|
||||||
|
const BYTE* const istart2 = istart1 + length1;
|
||||||
|
const BYTE* const istart3 = istart2 + length2;
|
||||||
|
const BYTE* const istart4 = istart3 + length3;
|
||||||
|
const size_t segmentSize = (dstSize+3) / 4;
|
||||||
|
BYTE* const opStart2 = ostart + segmentSize;
|
||||||
|
BYTE* const opStart3 = opStart2 + segmentSize;
|
||||||
|
BYTE* const opStart4 = opStart3 + segmentSize;
|
||||||
|
BYTE* op1 = ostart;
|
||||||
|
BYTE* op2 = opStart2;
|
||||||
|
BYTE* op3 = opStart3;
|
||||||
|
BYTE* op4 = opStart4;
|
||||||
|
U32 endSignal;
|
||||||
|
|
||||||
|
length4 = cSrcSize - (length1 + length2 + length3 + 6);
|
||||||
|
if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
|
||||||
|
errorCode = BITv06_initDStream(&bitD1, istart1, length1);
|
||||||
|
if (HUFv06_isError(errorCode)) return errorCode;
|
||||||
|
errorCode = BITv06_initDStream(&bitD2, istart2, length2);
|
||||||
|
if (HUFv06_isError(errorCode)) return errorCode;
|
||||||
|
errorCode = BITv06_initDStream(&bitD3, istart3, length3);
|
||||||
|
if (HUFv06_isError(errorCode)) return errorCode;
|
||||||
|
errorCode = BITv06_initDStream(&bitD4, istart4, length4);
|
||||||
|
if (HUFv06_isError(errorCode)) return errorCode;
|
||||||
|
|
||||||
|
/* 16-32 symbols per loop (4-8 symbols per stream) */
|
||||||
|
endSignal = BITv06_reloadDStream(&bitD1) | BITv06_reloadDStream(&bitD2) | BITv06_reloadDStream(&bitD3) | BITv06_reloadDStream(&bitD4);
|
||||||
|
for ( ; (endSignal==BITv06_DStream_unfinished) && (op4<(oend-7)) ; ) {
|
||||||
|
HUFv06_DECODE_SYMBOLX2_2(op1, &bitD1);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_2(op2, &bitD2);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_2(op3, &bitD3);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_2(op4, &bitD4);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_1(op1, &bitD1);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_1(op2, &bitD2);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_1(op3, &bitD3);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_1(op4, &bitD4);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_2(op1, &bitD1);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_2(op2, &bitD2);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_2(op3, &bitD3);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_2(op4, &bitD4);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_0(op1, &bitD1);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_0(op2, &bitD2);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_0(op3, &bitD3);
|
||||||
|
HUFv06_DECODE_SYMBOLX2_0(op4, &bitD4);
|
||||||
|
endSignal = BITv06_reloadDStream(&bitD1) | BITv06_reloadDStream(&bitD2) | BITv06_reloadDStream(&bitD3) | BITv06_reloadDStream(&bitD4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check corruption */
|
||||||
|
if (op1 > opStart2) return ERROR(corruption_detected);
|
||||||
|
if (op2 > opStart3) return ERROR(corruption_detected);
|
||||||
|
if (op3 > opStart4) return ERROR(corruption_detected);
|
||||||
|
/* note : op4 supposed already verified within main loop */
|
||||||
|
|
||||||
|
/* finish bitStreams one by one */
|
||||||
|
HUFv06_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
|
||||||
|
HUFv06_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
|
||||||
|
HUFv06_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
|
||||||
|
HUFv06_decodeStreamX2(op4, &bitD4, oend, dt, dtLog);
|
||||||
|
|
||||||
|
/* check */
|
||||||
|
endSignal = BITv06_endOfDStream(&bitD1) & BITv06_endOfDStream(&bitD2) & BITv06_endOfDStream(&bitD3) & BITv06_endOfDStream(&bitD4);
|
||||||
|
if (!endSignal) return ERROR(corruption_detected);
|
||||||
|
|
||||||
|
/* decoded size */
|
||||||
|
return dstSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t HUFv06_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
|
{
|
||||||
|
HUFv06_CREATE_STATIC_DTABLEX2(DTable, HUFv06_MAX_TABLELOG);
|
||||||
|
const BYTE* ip = (const BYTE*) cSrc;
|
||||||
|
|
||||||
|
size_t const errorCode = HUFv06_readDTableX2 (DTable, cSrc, cSrcSize);
|
||||||
|
if (HUFv06_isError(errorCode)) return errorCode;
|
||||||
|
if (errorCode >= cSrcSize) return ERROR(srcSize_wrong);
|
||||||
|
ip += errorCode;
|
||||||
|
cSrcSize -= errorCode;
|
||||||
|
|
||||||
|
return HUFv06_decompress4X2_usingDTable (dst, dstSize, ip, cSrcSize, DTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************/
|
||||||
|
/* double-symbols decoding */
|
||||||
|
/* *************************/
|
||||||
|
|
||||||
|
static void HUFv06_fillDTableX4Level2(HUFv06_DEltX4* DTable, U32 sizeLog, const U32 consumed,
|
||||||
|
const U32* rankValOrigin, const int minWeight,
|
||||||
|
const sortedSymbol_t* sortedSymbols, const U32 sortedListSize,
|
||||||
|
U32 nbBitsBaseline, U16 baseSeq)
|
||||||
|
{
|
||||||
|
HUFv06_DEltX4 DElt;
|
||||||
|
U32 rankVal[HUFv06_ABSOLUTEMAX_TABLELOG + 1];
|
||||||
|
|
||||||
|
/* get pre-calculated rankVal */
|
||||||
|
memcpy(rankVal, rankValOrigin, sizeof(rankVal));
|
||||||
|
|
||||||
|
/* fill skipped values */
|
||||||
|
if (minWeight>1) {
|
||||||
|
U32 i, skipSize = rankVal[minWeight];
|
||||||
|
MEM_writeLE16(&(DElt.sequence), baseSeq);
|
||||||
|
DElt.nbBits = (BYTE)(consumed);
|
||||||
|
DElt.length = 1;
|
||||||
|
for (i = 0; i < skipSize; i++)
|
||||||
|
DTable[i] = DElt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill DTable */
|
||||||
|
{ U32 s; for (s=0; s<sortedListSize; s++) { /* note : sortedSymbols already skipped */
|
||||||
|
const U32 symbol = sortedSymbols[s].symbol;
|
||||||
|
const U32 weight = sortedSymbols[s].weight;
|
||||||
|
const U32 nbBits = nbBitsBaseline - weight;
|
||||||
|
const U32 length = 1 << (sizeLog-nbBits);
|
||||||
|
const U32 start = rankVal[weight];
|
||||||
|
U32 i = start;
|
||||||
|
const U32 end = start + length;
|
||||||
|
|
||||||
|
MEM_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8)));
|
||||||
|
DElt.nbBits = (BYTE)(nbBits + consumed);
|
||||||
|
DElt.length = 2;
|
||||||
|
do { DTable[i++] = DElt; } while (i<end); /* since length >= 1 */
|
||||||
|
|
||||||
|
rankVal[weight] += length;
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef U32 rankVal_t[HUFv06_ABSOLUTEMAX_TABLELOG][HUFv06_ABSOLUTEMAX_TABLELOG + 1];
|
||||||
|
|
||||||
|
static void HUFv06_fillDTableX4(HUFv06_DEltX4* DTable, const U32 targetLog,
|
||||||
|
const sortedSymbol_t* sortedList, const U32 sortedListSize,
|
||||||
|
const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
|
||||||
|
const U32 nbBitsBaseline)
|
||||||
|
{
|
||||||
|
U32 rankVal[HUFv06_ABSOLUTEMAX_TABLELOG + 1];
|
||||||
|
const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */
|
||||||
|
const U32 minBits = nbBitsBaseline - maxWeight;
|
||||||
|
U32 s;
|
||||||
|
|
||||||
|
memcpy(rankVal, rankValOrigin, sizeof(rankVal));
|
||||||
|
|
||||||
|
/* fill DTable */
|
||||||
|
for (s=0; s<sortedListSize; s++) {
|
||||||
|
const U16 symbol = sortedList[s].symbol;
|
||||||
|
const U32 weight = sortedList[s].weight;
|
||||||
|
const U32 nbBits = nbBitsBaseline - weight;
|
||||||
|
const U32 start = rankVal[weight];
|
||||||
|
const U32 length = 1 << (targetLog-nbBits);
|
||||||
|
|
||||||
|
if (targetLog-nbBits >= minBits) { /* enough room for a second symbol */
|
||||||
|
U32 sortedRank;
|
||||||
|
int minWeight = nbBits + scaleLog;
|
||||||
|
if (minWeight < 1) minWeight = 1;
|
||||||
|
sortedRank = rankStart[minWeight];
|
||||||
|
HUFv06_fillDTableX4Level2(DTable+start, targetLog-nbBits, nbBits,
|
||||||
|
rankValOrigin[nbBits], minWeight,
|
||||||
|
sortedList+sortedRank, sortedListSize-sortedRank,
|
||||||
|
nbBitsBaseline, symbol);
|
||||||
|
} else {
|
||||||
|
HUFv06_DEltX4 DElt;
|
||||||
|
MEM_writeLE16(&(DElt.sequence), symbol);
|
||||||
|
DElt.nbBits = (BYTE)(nbBits);
|
||||||
|
DElt.length = 1;
|
||||||
|
{ U32 u;
|
||||||
|
const U32 end = start + length;
|
||||||
|
for (u = start; u < end; u++) DTable[u] = DElt;
|
||||||
|
} }
|
||||||
|
rankVal[weight] += length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HUFv06_readDTableX4 (U32* DTable, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
BYTE weightList[HUFv06_MAX_SYMBOL_VALUE + 1];
|
||||||
|
sortedSymbol_t sortedSymbol[HUFv06_MAX_SYMBOL_VALUE + 1];
|
||||||
|
U32 rankStats[HUFv06_ABSOLUTEMAX_TABLELOG + 1] = { 0 };
|
||||||
|
U32 rankStart0[HUFv06_ABSOLUTEMAX_TABLELOG + 2] = { 0 };
|
||||||
|
U32* const rankStart = rankStart0+1;
|
||||||
|
rankVal_t rankVal;
|
||||||
|
U32 tableLog, maxW, sizeOfSort, nbSymbols;
|
||||||
|
const U32 memLog = DTable[0];
|
||||||
|
size_t iSize;
|
||||||
|
void* dtPtr = DTable;
|
||||||
|
HUFv06_DEltX4* const dt = ((HUFv06_DEltX4*)dtPtr) + 1;
|
||||||
|
|
||||||
|
HUFv06_STATIC_ASSERT(sizeof(HUFv06_DEltX4) == sizeof(U32)); /* if compilation fails here, assertion is false */
|
||||||
|
if (memLog > HUFv06_ABSOLUTEMAX_TABLELOG) return ERROR(tableLog_tooLarge);
|
||||||
|
//memset(weightList, 0, sizeof(weightList)); /* is not necessary, even though some analyzer complain ... */
|
||||||
|
|
||||||
|
iSize = HUFv06_readStats(weightList, HUFv06_MAX_SYMBOL_VALUE + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
|
||||||
|
if (HUFv06_isError(iSize)) return iSize;
|
||||||
|
|
||||||
|
/* check result */
|
||||||
|
if (tableLog > memLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */
|
||||||
|
|
||||||
|
/* find maxWeight */
|
||||||
|
for (maxW = tableLog; rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */
|
||||||
|
|
||||||
|
/* Get start index of each weight */
|
||||||
|
{ U32 w, nextRankStart = 0;
|
||||||
|
for (w=1; w<maxW+1; w++) {
|
||||||
|
U32 current = nextRankStart;
|
||||||
|
nextRankStart += rankStats[w];
|
||||||
|
rankStart[w] = current;
|
||||||
|
}
|
||||||
|
rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/
|
||||||
|
sizeOfSort = nextRankStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sort symbols by weight */
|
||||||
|
{ U32 s;
|
||||||
|
for (s=0; s<nbSymbols; s++) {
|
||||||
|
U32 const w = weightList[s];
|
||||||
|
U32 const r = rankStart[w]++;
|
||||||
|
sortedSymbol[r].symbol = (BYTE)s;
|
||||||
|
sortedSymbol[r].weight = (BYTE)w;
|
||||||
|
}
|
||||||
|
rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build rankVal */
|
||||||
|
{ U32* const rankVal0 = rankVal[0];
|
||||||
|
{ int const rescale = (memLog-tableLog) - 1; /* tableLog <= memLog */
|
||||||
|
U32 nextRankVal = 0;
|
||||||
|
U32 w;
|
||||||
|
for (w=1; w<maxW+1; w++) {
|
||||||
|
U32 current = nextRankVal;
|
||||||
|
nextRankVal += rankStats[w] << (w+rescale);
|
||||||
|
rankVal0[w] = current;
|
||||||
|
} }
|
||||||
|
{ U32 const minBits = tableLog+1 - maxW;
|
||||||
|
U32 consumed;
|
||||||
|
for (consumed = minBits; consumed < memLog - minBits + 1; consumed++) {
|
||||||
|
U32* const rankValPtr = rankVal[consumed];
|
||||||
|
U32 w;
|
||||||
|
for (w = 1; w < maxW+1; w++) {
|
||||||
|
rankValPtr[w] = rankVal0[w] >> consumed;
|
||||||
|
} } } }
|
||||||
|
|
||||||
|
HUFv06_fillDTableX4(dt, memLog,
|
||||||
|
sortedSymbol, sizeOfSort,
|
||||||
|
rankStart0, rankVal, maxW,
|
||||||
|
tableLog+1);
|
||||||
|
|
||||||
|
return iSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static U32 HUFv06_decodeSymbolX4(void* op, BITv06_DStream_t* DStream, const HUFv06_DEltX4* dt, const U32 dtLog)
|
||||||
|
{
|
||||||
|
const size_t val = BITv06_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
|
||||||
|
memcpy(op, dt+val, 2);
|
||||||
|
BITv06_skipBits(DStream, dt[val].nbBits);
|
||||||
|
return dt[val].length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static U32 HUFv06_decodeLastSymbolX4(void* op, BITv06_DStream_t* DStream, const HUFv06_DEltX4* dt, const U32 dtLog)
|
||||||
|
{
|
||||||
|
const size_t val = BITv06_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
|
||||||
|
memcpy(op, dt+val, 1);
|
||||||
|
if (dt[val].length==1) BITv06_skipBits(DStream, dt[val].nbBits);
|
||||||
|
else {
|
||||||
|
if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
|
||||||
|
BITv06_skipBits(DStream, dt[val].nbBits);
|
||||||
|
if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))
|
||||||
|
DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8); /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
|
||||||
|
} }
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define HUFv06_DECODE_SYMBOLX4_0(ptr, DStreamPtr) \
|
||||||
|
ptr += HUFv06_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
|
||||||
|
|
||||||
|
#define HUFv06_DECODE_SYMBOLX4_1(ptr, DStreamPtr) \
|
||||||
|
if (MEM_64bits() || (HUFv06_MAX_TABLELOG<=12)) \
|
||||||
|
ptr += HUFv06_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
|
||||||
|
|
||||||
|
#define HUFv06_DECODE_SYMBOLX4_2(ptr, DStreamPtr) \
|
||||||
|
if (MEM_64bits()) \
|
||||||
|
ptr += HUFv06_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
|
||||||
|
|
||||||
|
static inline size_t HUFv06_decodeStreamX4(BYTE* p, BITv06_DStream_t* bitDPtr, BYTE* const pEnd, const HUFv06_DEltX4* const dt, const U32 dtLog)
|
||||||
|
{
|
||||||
|
BYTE* const pStart = p;
|
||||||
|
|
||||||
|
/* up to 8 symbols at a time */
|
||||||
|
while ((BITv06_reloadDStream(bitDPtr) == BITv06_DStream_unfinished) && (p < pEnd-7)) {
|
||||||
|
HUFv06_DECODE_SYMBOLX4_2(p, bitDPtr);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_1(p, bitDPtr);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_2(p, bitDPtr);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_0(p, bitDPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* closer to the end */
|
||||||
|
while ((BITv06_reloadDStream(bitDPtr) == BITv06_DStream_unfinished) && (p <= pEnd-2))
|
||||||
|
HUFv06_DECODE_SYMBOLX4_0(p, bitDPtr);
|
||||||
|
|
||||||
|
while (p <= pEnd-2)
|
||||||
|
HUFv06_DECODE_SYMBOLX4_0(p, bitDPtr); /* no need to reload : reached the end of DStream */
|
||||||
|
|
||||||
|
if (p < pEnd)
|
||||||
|
p += HUFv06_decodeLastSymbolX4(p, bitDPtr, dt, dtLog);
|
||||||
|
|
||||||
|
return p-pStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t HUFv06_decompress1X4_usingDTable(
|
||||||
|
void* dst, size_t dstSize,
|
||||||
|
const void* cSrc, size_t cSrcSize,
|
||||||
|
const U32* DTable)
|
||||||
|
{
|
||||||
|
const BYTE* const istart = (const BYTE*) cSrc;
|
||||||
|
BYTE* const ostart = (BYTE*) dst;
|
||||||
|
BYTE* const oend = ostart + dstSize;
|
||||||
|
|
||||||
|
const U32 dtLog = DTable[0];
|
||||||
|
const void* const dtPtr = DTable;
|
||||||
|
const HUFv06_DEltX4* const dt = ((const HUFv06_DEltX4*)dtPtr) +1;
|
||||||
|
|
||||||
|
/* Init */
|
||||||
|
BITv06_DStream_t bitD;
|
||||||
|
{ size_t const errorCode = BITv06_initDStream(&bitD, istart, cSrcSize);
|
||||||
|
if (HUFv06_isError(errorCode)) return errorCode; }
|
||||||
|
|
||||||
|
/* decode */
|
||||||
|
HUFv06_decodeStreamX4(ostart, &bitD, oend, dt, dtLog);
|
||||||
|
|
||||||
|
/* check */
|
||||||
|
if (!BITv06_endOfDStream(&bitD)) return ERROR(corruption_detected);
|
||||||
|
|
||||||
|
/* decoded size */
|
||||||
|
return dstSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HUFv06_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
|
{
|
||||||
|
HUFv06_CREATE_STATIC_DTABLEX4(DTable, HUFv06_MAX_TABLELOG);
|
||||||
|
const BYTE* ip = (const BYTE*) cSrc;
|
||||||
|
|
||||||
|
size_t const hSize = HUFv06_readDTableX4 (DTable, cSrc, cSrcSize);
|
||||||
|
if (HUFv06_isError(hSize)) return hSize;
|
||||||
|
if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
|
||||||
|
ip += hSize;
|
||||||
|
cSrcSize -= hSize;
|
||||||
|
|
||||||
|
return HUFv06_decompress1X4_usingDTable (dst, dstSize, ip, cSrcSize, DTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HUFv06_decompress4X4_usingDTable(
|
||||||
|
void* dst, size_t dstSize,
|
||||||
|
const void* cSrc, size_t cSrcSize,
|
||||||
|
const U32* DTable)
|
||||||
|
{
|
||||||
|
if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
|
||||||
|
|
||||||
|
{ const BYTE* const istart = (const BYTE*) cSrc;
|
||||||
|
BYTE* const ostart = (BYTE*) dst;
|
||||||
|
BYTE* const oend = ostart + dstSize;
|
||||||
|
const void* const dtPtr = DTable;
|
||||||
|
const HUFv06_DEltX4* const dt = ((const HUFv06_DEltX4*)dtPtr) +1;
|
||||||
|
const U32 dtLog = DTable[0];
|
||||||
|
size_t errorCode;
|
||||||
|
|
||||||
|
/* Init */
|
||||||
|
BITv06_DStream_t bitD1;
|
||||||
|
BITv06_DStream_t bitD2;
|
||||||
|
BITv06_DStream_t bitD3;
|
||||||
|
BITv06_DStream_t bitD4;
|
||||||
|
const size_t length1 = MEM_readLE16(istart);
|
||||||
|
const size_t length2 = MEM_readLE16(istart+2);
|
||||||
|
const size_t length3 = MEM_readLE16(istart+4);
|
||||||
|
size_t length4;
|
||||||
|
const BYTE* const istart1 = istart + 6; /* jumpTable */
|
||||||
|
const BYTE* const istart2 = istart1 + length1;
|
||||||
|
const BYTE* const istart3 = istart2 + length2;
|
||||||
|
const BYTE* const istart4 = istart3 + length3;
|
||||||
|
const size_t segmentSize = (dstSize+3) / 4;
|
||||||
|
BYTE* const opStart2 = ostart + segmentSize;
|
||||||
|
BYTE* const opStart3 = opStart2 + segmentSize;
|
||||||
|
BYTE* const opStart4 = opStart3 + segmentSize;
|
||||||
|
BYTE* op1 = ostart;
|
||||||
|
BYTE* op2 = opStart2;
|
||||||
|
BYTE* op3 = opStart3;
|
||||||
|
BYTE* op4 = opStart4;
|
||||||
|
U32 endSignal;
|
||||||
|
|
||||||
|
length4 = cSrcSize - (length1 + length2 + length3 + 6);
|
||||||
|
if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
|
||||||
|
errorCode = BITv06_initDStream(&bitD1, istart1, length1);
|
||||||
|
if (HUFv06_isError(errorCode)) return errorCode;
|
||||||
|
errorCode = BITv06_initDStream(&bitD2, istart2, length2);
|
||||||
|
if (HUFv06_isError(errorCode)) return errorCode;
|
||||||
|
errorCode = BITv06_initDStream(&bitD3, istart3, length3);
|
||||||
|
if (HUFv06_isError(errorCode)) return errorCode;
|
||||||
|
errorCode = BITv06_initDStream(&bitD4, istart4, length4);
|
||||||
|
if (HUFv06_isError(errorCode)) return errorCode;
|
||||||
|
|
||||||
|
/* 16-32 symbols per loop (4-8 symbols per stream) */
|
||||||
|
endSignal = BITv06_reloadDStream(&bitD1) | BITv06_reloadDStream(&bitD2) | BITv06_reloadDStream(&bitD3) | BITv06_reloadDStream(&bitD4);
|
||||||
|
for ( ; (endSignal==BITv06_DStream_unfinished) && (op4<(oend-7)) ; ) {
|
||||||
|
HUFv06_DECODE_SYMBOLX4_2(op1, &bitD1);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_2(op2, &bitD2);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_2(op3, &bitD3);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_2(op4, &bitD4);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_1(op1, &bitD1);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_1(op2, &bitD2);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_1(op3, &bitD3);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_1(op4, &bitD4);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_2(op1, &bitD1);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_2(op2, &bitD2);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_2(op3, &bitD3);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_2(op4, &bitD4);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_0(op1, &bitD1);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_0(op2, &bitD2);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_0(op3, &bitD3);
|
||||||
|
HUFv06_DECODE_SYMBOLX4_0(op4, &bitD4);
|
||||||
|
|
||||||
|
endSignal = BITv06_reloadDStream(&bitD1) | BITv06_reloadDStream(&bitD2) | BITv06_reloadDStream(&bitD3) | BITv06_reloadDStream(&bitD4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check corruption */
|
||||||
|
if (op1 > opStart2) return ERROR(corruption_detected);
|
||||||
|
if (op2 > opStart3) return ERROR(corruption_detected);
|
||||||
|
if (op3 > opStart4) return ERROR(corruption_detected);
|
||||||
|
/* note : op4 supposed already verified within main loop */
|
||||||
|
|
||||||
|
/* finish bitStreams one by one */
|
||||||
|
HUFv06_decodeStreamX4(op1, &bitD1, opStart2, dt, dtLog);
|
||||||
|
HUFv06_decodeStreamX4(op2, &bitD2, opStart3, dt, dtLog);
|
||||||
|
HUFv06_decodeStreamX4(op3, &bitD3, opStart4, dt, dtLog);
|
||||||
|
HUFv06_decodeStreamX4(op4, &bitD4, oend, dt, dtLog);
|
||||||
|
|
||||||
|
/* check */
|
||||||
|
endSignal = BITv06_endOfDStream(&bitD1) & BITv06_endOfDStream(&bitD2) & BITv06_endOfDStream(&bitD3) & BITv06_endOfDStream(&bitD4);
|
||||||
|
if (!endSignal) return ERROR(corruption_detected);
|
||||||
|
|
||||||
|
/* decoded size */
|
||||||
|
return dstSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t HUFv06_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
|
{
|
||||||
|
HUFv06_CREATE_STATIC_DTABLEX4(DTable, HUFv06_MAX_TABLELOG);
|
||||||
|
const BYTE* ip = (const BYTE*) cSrc;
|
||||||
|
|
||||||
|
size_t hSize = HUFv06_readDTableX4 (DTable, cSrc, cSrcSize);
|
||||||
|
if (HUFv06_isError(hSize)) return hSize;
|
||||||
|
if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
|
||||||
|
ip += hSize;
|
||||||
|
cSrcSize -= hSize;
|
||||||
|
|
||||||
|
return HUFv06_decompress4X4_usingDTable (dst, dstSize, ip, cSrcSize, DTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ********************************/
|
||||||
|
/* Generic decompression selector */
|
||||||
|
/* ********************************/
|
||||||
|
|
||||||
|
typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;
|
||||||
|
static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] =
|
||||||
|
{
|
||||||
|
/* single, double, quad */
|
||||||
|
{{0,0}, {1,1}, {2,2}}, /* Q==0 : impossible */
|
||||||
|
{{0,0}, {1,1}, {2,2}}, /* Q==1 : impossible */
|
||||||
|
{{ 38,130}, {1313, 74}, {2151, 38}}, /* Q == 2 : 12-18% */
|
||||||
|
{{ 448,128}, {1353, 74}, {2238, 41}}, /* Q == 3 : 18-25% */
|
||||||
|
{{ 556,128}, {1353, 74}, {2238, 47}}, /* Q == 4 : 25-32% */
|
||||||
|
{{ 714,128}, {1418, 74}, {2436, 53}}, /* Q == 5 : 32-38% */
|
||||||
|
{{ 883,128}, {1437, 74}, {2464, 61}}, /* Q == 6 : 38-44% */
|
||||||
|
{{ 897,128}, {1515, 75}, {2622, 68}}, /* Q == 7 : 44-50% */
|
||||||
|
{{ 926,128}, {1613, 75}, {2730, 75}}, /* Q == 8 : 50-56% */
|
||||||
|
{{ 947,128}, {1729, 77}, {3359, 77}}, /* Q == 9 : 56-62% */
|
||||||
|
{{1107,128}, {2083, 81}, {4006, 84}}, /* Q ==10 : 62-69% */
|
||||||
|
{{1177,128}, {2379, 87}, {4785, 88}}, /* Q ==11 : 69-75% */
|
||||||
|
{{1242,128}, {2415, 93}, {5155, 84}}, /* Q ==12 : 75-81% */
|
||||||
|
{{1349,128}, {2644,106}, {5260,106}}, /* Q ==13 : 81-87% */
|
||||||
|
{{1455,128}, {2422,124}, {4174,124}}, /* Q ==14 : 87-93% */
|
||||||
|
{{ 722,128}, {1891,145}, {1936,146}}, /* Q ==15 : 93-99% */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
|
||||||
|
|
||||||
|
size_t HUFv06_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
|
{
|
||||||
|
static const decompressionAlgo decompress[3] = { HUFv06_decompress4X2, HUFv06_decompress4X4, NULL };
|
||||||
|
U32 Dtime[3]; /* decompression time estimation */
|
||||||
|
|
||||||
|
/* validation checks */
|
||||||
|
if (dstSize == 0) return ERROR(dstSize_tooSmall);
|
||||||
|
if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
|
||||||
|
if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
|
||||||
|
if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
|
||||||
|
|
||||||
|
/* decoder timing evaluation */
|
||||||
|
{ U32 const Q = (U32)(cSrcSize * 16 / dstSize); /* Q < 16 since dstSize > cSrcSize */
|
||||||
|
U32 const D256 = (U32)(dstSize >> 8);
|
||||||
|
U32 n; for (n=0; n<3; n++)
|
||||||
|
Dtime[n] = algoTime[Q][n].tableTime + (algoTime[Q][n].decode256Time * D256);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dtime[1] += Dtime[1] >> 4; Dtime[2] += Dtime[2] >> 3; /* advantage to algorithms using less memory, for cache eviction */
|
||||||
|
|
||||||
|
{ U32 algoNb = 0;
|
||||||
|
if (Dtime[1] < Dtime[0]) algoNb = 1;
|
||||||
|
// if (Dtime[2] < Dtime[algoNb]) algoNb = 2; /* current speed of HUFv06_decompress4X6 is not good */
|
||||||
|
return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//return HUFv06_decompress4X2(dst, dstSize, cSrc, cSrcSize); /* multi-streams single-symbol decoding */
|
||||||
|
//return HUFv06_decompress4X4(dst, dstSize, cSrc, cSrcSize); /* multi-streams double-symbols decoding */
|
||||||
|
//return HUFv06_decompress4X6(dst, dstSize, cSrc, cSrcSize); /* multi-streams quad-symbols decoding */
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Common functions of Zstd compression library
|
||||||
|
Copyright (C) 2015-2016, 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 homepage : http://www.zstd.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*-****************************************
|
||||||
|
* Version
|
||||||
|
******************************************/
|
||||||
|
|
||||||
|
/*-****************************************
|
||||||
|
* ZSTD Error Management
|
||||||
|
******************************************/
|
||||||
|
/*! ZSTDv06_isError() :
|
||||||
|
* tells if a return value is an error code */
|
||||||
|
unsigned ZSTDv06_isError(size_t code) { return ERR_isError(code); }
|
||||||
|
|
||||||
|
/*! ZSTDv06_getErrorName() :
|
||||||
|
* provides error code string from function result (useful for debugging) */
|
||||||
|
const char* ZSTDv06_getErrorName(size_t code) { return ERR_getErrorName(code); }
|
||||||
|
|
||||||
|
/*! ZSTDv06_getError() :
|
||||||
|
* convert a `size_t` function result into a proper ZSTDv06_errorCode enum */
|
||||||
|
ZSTDv06_ErrorCode ZSTDv06_getErrorCode(size_t code) { return ERR_getErrorCode(code); }
|
||||||
|
|
||||||
|
/*! ZSTDv06_getErrorString() :
|
||||||
|
* provides error code string from enum */
|
||||||
|
const char* ZSTDv06_getErrorString(ZSTDv06_ErrorCode code) { return ERR_getErrorName(code); }
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************************************************
|
||||||
|
* ZBUFF Error Management
|
||||||
|
****************************************************************/
|
||||||
|
unsigned ZBUFFv06_isError(size_t errorCode) { return ERR_isError(errorCode); }
|
||||||
|
|
||||||
|
const char* ZBUFFv06_getErrorName(size_t errorCode) { return ERR_getErrorName(errorCode); }
|
||||||
|
/*
|
||||||
|
zstd - standard compression library
|
||||||
|
Copyright (C) 2014-2016, 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 homepage : http://www.zstd.net
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ***************************************************************
|
||||||
|
* Tuning parameters
|
||||||
|
*****************************************************************/
|
||||||
|
/*!
|
||||||
|
* HEAPMODE :
|
||||||
|
* Select how default decompression function ZSTDv06_decompress() will allocate memory,
|
||||||
|
* in memory stack (0), or in memory heap (1, requires malloc())
|
||||||
|
*/
|
||||||
|
#ifndef ZSTDv06_HEAPMODE
|
||||||
|
# define ZSTDv06_HEAPMODE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-*******************************************************
|
||||||
|
* Compiler specifics
|
||||||
|
*********************************************************/
|
||||||
|
#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
|
||||||
|
# ifdef __GNUC__
|
||||||
|
# define FORCE_INLINE static inline __attribute__((always_inline))
|
||||||
|
# else
|
||||||
|
# define FORCE_INLINE static inline
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*-*************************************
|
||||||
|
* Macros
|
||||||
|
***************************************/
|
||||||
|
#define ZSTDv06_isError ERR_isError /* for inlining */
|
||||||
|
#define FSEv06_isError ERR_isError
|
||||||
|
#define HUFv06_isError ERR_isError
|
||||||
|
|
||||||
|
|
||||||
|
/*_*******************************************************
|
||||||
|
* Memory operations
|
||||||
|
**********************************************************/
|
||||||
|
static void ZSTDv06_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
|
||||||
|
|
||||||
|
|
||||||
|
/*-*************************************************************
|
||||||
|
* Context management
|
||||||
|
***************************************************************/
|
||||||
|
typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
|
||||||
|
ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock } ZSTDv06_dStage;
|
||||||
|
|
||||||
|
struct ZSTDv06_DCtx_s
|
||||||
|
{
|
||||||
|
FSEv06_DTable LLTable[FSEv06_DTABLE_SIZE_U32(LLFSELog)];
|
||||||
|
FSEv06_DTable OffTable[FSEv06_DTABLE_SIZE_U32(OffFSELog)];
|
||||||
|
FSEv06_DTable MLTable[FSEv06_DTABLE_SIZE_U32(MLFSELog)];
|
||||||
|
unsigned hufTableX4[HUFv06_DTABLE_SIZE(HufLog)];
|
||||||
|
const void* previousDstEnd;
|
||||||
|
const void* base;
|
||||||
|
const void* vBase;
|
||||||
|
const void* dictEnd;
|
||||||
|
size_t expected;
|
||||||
|
size_t headerSize;
|
||||||
|
ZSTDv06_frameParams fParams;
|
||||||
|
blockType_t bType; /* used in ZSTDv06_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
|
||||||
|
ZSTDv06_dStage stage;
|
||||||
|
U32 flagRepeatTable;
|
||||||
|
const BYTE* litPtr;
|
||||||
|
size_t litBufSize;
|
||||||
|
size_t litSize;
|
||||||
|
BYTE litBuffer[ZSTDv06_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH];
|
||||||
|
BYTE headerBuffer[ZSTDv06_FRAMEHEADERSIZE_MAX];
|
||||||
|
}; /* typedef'd to ZSTDv06_DCtx within "zstd_static.h" */
|
||||||
|
|
||||||
|
size_t ZSTDv06_sizeofDCtx (void) { return sizeof(ZSTDv06_DCtx); } /* non published interface */
|
||||||
|
|
||||||
|
size_t ZSTDv06_decompressBegin(ZSTDv06_DCtx* dctx)
|
||||||
|
{
|
||||||
|
dctx->expected = ZSTDv06_frameHeaderSize_min;
|
||||||
|
dctx->stage = ZSTDds_getFrameHeaderSize;
|
||||||
|
dctx->previousDstEnd = NULL;
|
||||||
|
dctx->base = NULL;
|
||||||
|
dctx->vBase = NULL;
|
||||||
|
dctx->dictEnd = NULL;
|
||||||
|
dctx->hufTableX4[0] = HufLog;
|
||||||
|
dctx->flagRepeatTable = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZSTDv06_DCtx* ZSTDv06_createDCtx(void)
|
||||||
|
{
|
||||||
|
ZSTDv06_DCtx* dctx = (ZSTDv06_DCtx*)malloc(sizeof(ZSTDv06_DCtx));
|
||||||
|
if (dctx==NULL) return NULL;
|
||||||
|
ZSTDv06_decompressBegin(dctx);
|
||||||
|
return dctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ZSTDv06_freeDCtx(ZSTDv06_DCtx* dctx)
|
||||||
|
{
|
||||||
|
free(dctx);
|
||||||
|
return 0; /* reserved as a potential error code in the future */
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZSTDv06_copyDCtx(ZSTDv06_DCtx* dstDCtx, const ZSTDv06_DCtx* srcDCtx)
|
||||||
|
{
|
||||||
|
memcpy(dstDCtx, srcDCtx,
|
||||||
|
sizeof(ZSTDv06_DCtx) - (ZSTDv06_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH + ZSTDv06_frameHeaderSize_max)); /* no need to copy workspace */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-*************************************************************
|
||||||
|
* Decompression section
|
||||||
|
***************************************************************/
|
||||||
|
|
||||||
|
/* Frame format description
|
||||||
|
Frame Header - [ Block Header - Block ] - Frame End
|
||||||
|
1) Frame Header
|
||||||
|
- 4 bytes - Magic Number : ZSTDv06_MAGICNUMBER (defined within zstd_static.h)
|
||||||
|
- 1 byte - Frame Descriptor
|
||||||
|
2) Block Header
|
||||||
|
- 3 bytes, starting with a 2-bits descriptor
|
||||||
|
Uncompressed, Compressed, Frame End, unused
|
||||||
|
3) Block
|
||||||
|
See Block Format Description
|
||||||
|
4) Frame End
|
||||||
|
- 3 bytes, compatible with Block Header
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Frame descriptor
|
||||||
|
|
||||||
|
1 byte, using :
|
||||||
|
bit 0-3 : windowLog - ZSTDv06_WINDOWLOG_ABSOLUTEMIN (see zstd_internal.h)
|
||||||
|
bit 4 : minmatch 4(0) or 3(1)
|
||||||
|
bit 5 : reserved (must be zero)
|
||||||
|
bit 6-7 : Frame content size : unknown, 1 byte, 2 bytes, 8 bytes
|
||||||
|
|
||||||
|
Optional : content size (0, 1, 2 or 8 bytes)
|
||||||
|
0 : unknown
|
||||||
|
1 : 0-255 bytes
|
||||||
|
2 : 256 - 65535+256
|
||||||
|
8 : up to 16 exa
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Compressed Block, format description
|
||||||
|
|
||||||
|
Block = Literal Section - Sequences Section
|
||||||
|
Prerequisite : size of (compressed) block, maximum size of regenerated data
|
||||||
|
|
||||||
|
1) Literal Section
|
||||||
|
|
||||||
|
1.1) Header : 1-5 bytes
|
||||||
|
flags: 2 bits
|
||||||
|
00 compressed by Huff0
|
||||||
|
01 unused
|
||||||
|
10 is Raw (uncompressed)
|
||||||
|
11 is Rle
|
||||||
|
Note : using 01 => Huff0 with precomputed table ?
|
||||||
|
Note : delta map ? => compressed ?
|
||||||
|
|
||||||
|
1.1.1) Huff0-compressed literal block : 3-5 bytes
|
||||||
|
srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
|
||||||
|
srcSize < 1 KB => 3 bytes (2-2-10-10)
|
||||||
|
srcSize < 16KB => 4 bytes (2-2-14-14)
|
||||||
|
else => 5 bytes (2-2-18-18)
|
||||||
|
big endian convention
|
||||||
|
|
||||||
|
1.1.2) Raw (uncompressed) literal block header : 1-3 bytes
|
||||||
|
size : 5 bits: (IS_RAW<<6) + (0<<4) + size
|
||||||
|
12 bits: (IS_RAW<<6) + (2<<4) + (size>>8)
|
||||||
|
size&255
|
||||||
|
20 bits: (IS_RAW<<6) + (3<<4) + (size>>16)
|
||||||
|
size>>8&255
|
||||||
|
size&255
|
||||||
|
|
||||||
|
1.1.3) Rle (repeated single byte) literal block header : 1-3 bytes
|
||||||
|
size : 5 bits: (IS_RLE<<6) + (0<<4) + size
|
||||||
|
12 bits: (IS_RLE<<6) + (2<<4) + (size>>8)
|
||||||
|
size&255
|
||||||
|
20 bits: (IS_RLE<<6) + (3<<4) + (size>>16)
|
||||||
|
size>>8&255
|
||||||
|
size&255
|
||||||
|
|
||||||
|
1.1.4) Huff0-compressed literal block, using precomputed CTables : 3-5 bytes
|
||||||
|
srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
|
||||||
|
srcSize < 1 KB => 3 bytes (2-2-10-10)
|
||||||
|
srcSize < 16KB => 4 bytes (2-2-14-14)
|
||||||
|
else => 5 bytes (2-2-18-18)
|
||||||
|
big endian convention
|
||||||
|
|
||||||
|
1- CTable available (stored into workspace ?)
|
||||||
|
2- Small input (fast heuristic ? Full comparison ? depend on clevel ?)
|
||||||
|
|
||||||
|
|
||||||
|
1.2) Literal block content
|
||||||
|
|
||||||
|
1.2.1) Huff0 block, using sizes from header
|
||||||
|
See Huff0 format
|
||||||
|
|
||||||
|
1.2.2) Huff0 block, using prepared table
|
||||||
|
|
||||||
|
1.2.3) Raw content
|
||||||
|
|
||||||
|
1.2.4) single byte
|
||||||
|
|
||||||
|
|
||||||
|
2) Sequences section
|
||||||
|
TO DO
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** ZSTDv06_frameHeaderSize() :
|
||||||
|
* srcSize must be >= ZSTDv06_frameHeaderSize_min.
|
||||||
|
* @return : size of the Frame Header */
|
||||||
|
static size_t ZSTDv06_frameHeaderSize(const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
if (srcSize < ZSTDv06_frameHeaderSize_min) return ERROR(srcSize_wrong);
|
||||||
|
{ U32 const fcsId = (((const BYTE*)src)[4]) >> 6;
|
||||||
|
return ZSTDv06_frameHeaderSize_min + ZSTDv06_fcs_fieldSize[fcsId]; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** ZSTDv06_getFrameParams() :
|
||||||
|
* decode Frame Header, or provide expected `srcSize`.
|
||||||
|
* @return : 0, `fparamsPtr` is correctly filled,
|
||||||
|
* >0, `srcSize` is too small, result is expected `srcSize`,
|
||||||
|
* or an error code, which can be tested using ZSTDv06_isError() */
|
||||||
|
size_t ZSTDv06_getFrameParams(ZSTDv06_frameParams* fparamsPtr, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
const BYTE* ip = (const BYTE*)src;
|
||||||
|
|
||||||
|
if (srcSize < ZSTDv06_frameHeaderSize_min) return ZSTDv06_frameHeaderSize_min;
|
||||||
|
if (MEM_readLE32(src) != ZSTDv06_MAGICNUMBER) return ERROR(prefix_unknown);
|
||||||
|
|
||||||
|
/* ensure there is enough `srcSize` to fully read/decode frame header */
|
||||||
|
{ size_t const fhsize = ZSTDv06_frameHeaderSize(src, srcSize);
|
||||||
|
if (srcSize < fhsize) return fhsize; }
|
||||||
|
|
||||||
|
memset(fparamsPtr, 0, sizeof(*fparamsPtr));
|
||||||
|
{ BYTE const frameDesc = ip[4];
|
||||||
|
fparamsPtr->windowLog = (frameDesc & 0xF) + ZSTDv06_WINDOWLOG_ABSOLUTEMIN;
|
||||||
|
if ((frameDesc & 0x20) != 0) return ERROR(frameParameter_unsupported); /* reserved 1 bit */
|
||||||
|
switch(frameDesc >> 6) /* fcsId */
|
||||||
|
{
|
||||||
|
default: /* impossible */
|
||||||
|
case 0 : fparamsPtr->frameContentSize = 0; break;
|
||||||
|
case 1 : fparamsPtr->frameContentSize = ip[5]; break;
|
||||||
|
case 2 : fparamsPtr->frameContentSize = MEM_readLE16(ip+5)+256; break;
|
||||||
|
case 3 : fparamsPtr->frameContentSize = MEM_readLE64(ip+5); break;
|
||||||
|
} }
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** ZSTDv06_decodeFrameHeader() :
|
||||||
|
* `srcSize` must be the size provided by ZSTDv06_frameHeaderSize().
|
||||||
|
* @return : 0 if success, or an error code, which can be tested using ZSTDv06_isError() */
|
||||||
|
static size_t ZSTDv06_decodeFrameHeader(ZSTDv06_DCtx* zc, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
size_t const result = ZSTDv06_getFrameParams(&(zc->fParams), src, srcSize);
|
||||||
|
if ((MEM_32bits()) && (zc->fParams.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bits);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
blockType_t blockType;
|
||||||
|
U32 origSize;
|
||||||
|
} blockProperties_t;
|
||||||
|
|
||||||
|
/*! ZSTDv06_getcBlockSize() :
|
||||||
|
* Provides the size of compressed block from block header `src` */
|
||||||
|
size_t ZSTDv06_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
|
||||||
|
{
|
||||||
|
const BYTE* const in = (const BYTE* const)src;
|
||||||
|
U32 cSize;
|
||||||
|
|
||||||
|
if (srcSize < ZSTDv06_blockHeaderSize) return ERROR(srcSize_wrong);
|
||||||
|
|
||||||
|
bpPtr->blockType = (blockType_t)((*in) >> 6);
|
||||||
|
cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
|
||||||
|
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 ZSTDv06_copyRawBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
if (srcSize > dstCapacity) return ERROR(dstSize_tooSmall);
|
||||||
|
memcpy(dst, src, srcSize);
|
||||||
|
return srcSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! ZSTDv06_decodeLiteralsBlock() :
|
||||||
|
@return : nb of bytes read from src (< srcSize ) */
|
||||||
|
size_t ZSTDv06_decodeLiteralsBlock(ZSTDv06_DCtx* dctx,
|
||||||
|
const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
|
||||||
|
{
|
||||||
|
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[0]>> 6)
|
||||||
|
{
|
||||||
|
case IS_HUF:
|
||||||
|
{ size_t litSize, litCSize, singleStream=0;
|
||||||
|
U32 lhSize = ((istart[0]) >> 4) & 3;
|
||||||
|
if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for lhSize, + cSize (+nbSeq) */
|
||||||
|
switch(lhSize)
|
||||||
|
{
|
||||||
|
case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
|
||||||
|
/* 2 - 2 - 10 - 10 */
|
||||||
|
lhSize=3;
|
||||||
|
singleStream = istart[0] & 16;
|
||||||
|
litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
|
||||||
|
litCSize = ((istart[1] & 3) << 8) + istart[2];
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
/* 2 - 2 - 14 - 14 */
|
||||||
|
lhSize=4;
|
||||||
|
litSize = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6);
|
||||||
|
litCSize = ((istart[2] & 63) << 8) + istart[3];
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
/* 2 - 2 - 18 - 18 */
|
||||||
|
lhSize=5;
|
||||||
|
litSize = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2);
|
||||||
|
litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (litSize > ZSTDv06_BLOCKSIZE_MAX) return ERROR(corruption_detected);
|
||||||
|
if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
|
||||||
|
|
||||||
|
if (HUFv06_isError(singleStream ?
|
||||||
|
HUFv06_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
|
||||||
|
HUFv06_decompress (dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
|
||||||
|
return ERROR(corruption_detected);
|
||||||
|
|
||||||
|
dctx->litPtr = dctx->litBuffer;
|
||||||
|
dctx->litBufSize = ZSTDv06_BLOCKSIZE_MAX+8;
|
||||||
|
dctx->litSize = litSize;
|
||||||
|
return litCSize + lhSize;
|
||||||
|
}
|
||||||
|
case IS_PCH:
|
||||||
|
{ size_t litSize, litCSize;
|
||||||
|
U32 lhSize = ((istart[0]) >> 4) & 3;
|
||||||
|
if (lhSize != 1) /* only case supported for now : small litSize, single stream */
|
||||||
|
return ERROR(corruption_detected);
|
||||||
|
if (!dctx->flagRepeatTable)
|
||||||
|
return ERROR(dictionary_corrupted);
|
||||||
|
|
||||||
|
/* 2 - 2 - 10 - 10 */
|
||||||
|
lhSize=3;
|
||||||
|
litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
|
||||||
|
litCSize = ((istart[1] & 3) << 8) + istart[2];
|
||||||
|
|
||||||
|
{ size_t const errorCode = HUFv06_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
|
||||||
|
if (HUFv06_isError(errorCode)) return ERROR(corruption_detected);
|
||||||
|
}
|
||||||
|
dctx->litPtr = dctx->litBuffer;
|
||||||
|
dctx->litBufSize = ZSTDv06_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH;
|
||||||
|
dctx->litSize = litSize;
|
||||||
|
return litCSize + lhSize;
|
||||||
|
}
|
||||||
|
case IS_RAW:
|
||||||
|
{ size_t litSize;
|
||||||
|
U32 lhSize = ((istart[0]) >> 4) & 3;
|
||||||
|
switch(lhSize)
|
||||||
|
{
|
||||||
|
case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
|
||||||
|
lhSize=1;
|
||||||
|
litSize = istart[0] & 31;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
litSize = ((istart[0] & 15) << 8) + istart[1];
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
|
||||||
|
if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
|
||||||
|
memcpy(dctx->litBuffer, istart+lhSize, litSize);
|
||||||
|
dctx->litPtr = dctx->litBuffer;
|
||||||
|
dctx->litBufSize = ZSTDv06_BLOCKSIZE_MAX+8;
|
||||||
|
dctx->litSize = litSize;
|
||||||
|
return lhSize+litSize;
|
||||||
|
}
|
||||||
|
/* direct reference into compressed stream */
|
||||||
|
dctx->litPtr = istart+lhSize;
|
||||||
|
dctx->litBufSize = srcSize-lhSize;
|
||||||
|
dctx->litSize = litSize;
|
||||||
|
return lhSize+litSize;
|
||||||
|
}
|
||||||
|
case IS_RLE:
|
||||||
|
{ size_t litSize;
|
||||||
|
U32 lhSize = ((istart[0]) >> 4) & 3;
|
||||||
|
switch(lhSize)
|
||||||
|
{
|
||||||
|
case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
|
||||||
|
lhSize = 1;
|
||||||
|
litSize = istart[0] & 31;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
litSize = ((istart[0] & 15) << 8) + istart[1];
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
|
||||||
|
if (srcSize<4) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (litSize > ZSTDv06_BLOCKSIZE_MAX) return ERROR(corruption_detected);
|
||||||
|
memset(dctx->litBuffer, istart[lhSize], litSize);
|
||||||
|
dctx->litPtr = dctx->litBuffer;
|
||||||
|
dctx->litBufSize = ZSTDv06_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH;
|
||||||
|
dctx->litSize = litSize;
|
||||||
|
return lhSize+1;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return ERROR(corruption_detected); /* impossible */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! ZSTDv06_buildSeqTable() :
|
||||||
|
@return : nb bytes read from src,
|
||||||
|
or an error code if it fails, testable with ZSTDv06_isError()
|
||||||
|
*/
|
||||||
|
size_t ZSTDv06_buildSeqTable(FSEv06_DTable* DTable, U32 type, U32 max, U32 maxLog,
|
||||||
|
const void* src, size_t srcSize,
|
||||||
|
const S16* defaultNorm, U32 defaultLog, U32 flagRepeatTable)
|
||||||
|
{
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case FSEv06_ENCODING_RLE :
|
||||||
|
if (!srcSize) return ERROR(srcSize_wrong);
|
||||||
|
if ( (*(const BYTE*)src) > max) return ERROR(corruption_detected);
|
||||||
|
FSEv06_buildDTable_rle(DTable, *(const BYTE*)src); /* if *src > max, data is corrupted */
|
||||||
|
return 1;
|
||||||
|
case FSEv06_ENCODING_RAW :
|
||||||
|
FSEv06_buildDTable(DTable, defaultNorm, max, defaultLog);
|
||||||
|
return 0;
|
||||||
|
case FSEv06_ENCODING_STATIC:
|
||||||
|
if (!flagRepeatTable) return ERROR(corruption_detected);
|
||||||
|
return 0;
|
||||||
|
default : /* impossible */
|
||||||
|
case FSEv06_ENCODING_DYNAMIC :
|
||||||
|
{ U32 tableLog;
|
||||||
|
S16 norm[MaxSeq+1];
|
||||||
|
size_t const headerSize = FSEv06_readNCount(norm, &max, &tableLog, src, srcSize);
|
||||||
|
if (FSEv06_isError(headerSize)) return ERROR(corruption_detected);
|
||||||
|
if (tableLog > maxLog) return ERROR(corruption_detected);
|
||||||
|
FSEv06_buildDTable(DTable, norm, max, tableLog);
|
||||||
|
return headerSize;
|
||||||
|
} }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t ZSTDv06_decodeSeqHeaders(int* nbSeqPtr,
|
||||||
|
FSEv06_DTable* DTableLL, FSEv06_DTable* DTableML, FSEv06_DTable* DTableOffb, U32 flagRepeatTable,
|
||||||
|
const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
const BYTE* const istart = (const BYTE* const)src;
|
||||||
|
const BYTE* const iend = istart + srcSize;
|
||||||
|
const BYTE* ip = istart;
|
||||||
|
|
||||||
|
/* check */
|
||||||
|
if (srcSize < MIN_SEQUENCES_SIZE) return ERROR(srcSize_wrong);
|
||||||
|
|
||||||
|
/* SeqHead */
|
||||||
|
{ int nbSeq = *ip++;
|
||||||
|
if (!nbSeq) { *nbSeqPtr=0; return 1; }
|
||||||
|
if (nbSeq > 0x7F) {
|
||||||
|
if (nbSeq == 0xFF)
|
||||||
|
nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
|
||||||
|
else
|
||||||
|
nbSeq = ((nbSeq-0x80)<<8) + *ip++;
|
||||||
|
}
|
||||||
|
*nbSeqPtr = nbSeq;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FSE table descriptors */
|
||||||
|
{ U32 const LLtype = *ip >> 6;
|
||||||
|
U32 const Offtype = (*ip >> 4) & 3;
|
||||||
|
U32 const MLtype = (*ip >> 2) & 3;
|
||||||
|
ip++;
|
||||||
|
|
||||||
|
/* check */
|
||||||
|
if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
|
||||||
|
|
||||||
|
/* Build DTables */
|
||||||
|
{ size_t const bhSize = ZSTDv06_buildSeqTable(DTableLL, LLtype, MaxLL, LLFSELog, ip, iend-ip, LL_defaultNorm, LL_defaultNormLog, flagRepeatTable);
|
||||||
|
if (ZSTDv06_isError(bhSize)) return ERROR(corruption_detected);
|
||||||
|
ip += bhSize;
|
||||||
|
}
|
||||||
|
{ size_t const bhSize = ZSTDv06_buildSeqTable(DTableOffb, Offtype, MaxOff, OffFSELog, ip, iend-ip, OF_defaultNorm, OF_defaultNormLog, flagRepeatTable);
|
||||||
|
if (ZSTDv06_isError(bhSize)) return ERROR(corruption_detected);
|
||||||
|
ip += bhSize;
|
||||||
|
}
|
||||||
|
{ size_t const bhSize = ZSTDv06_buildSeqTable(DTableML, MLtype, MaxML, MLFSELog, ip, iend-ip, ML_defaultNorm, ML_defaultNormLog, flagRepeatTable);
|
||||||
|
if (ZSTDv06_isError(bhSize)) return ERROR(corruption_detected);
|
||||||
|
ip += bhSize;
|
||||||
|
} }
|
||||||
|
|
||||||
|
return ip-istart;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t litLength;
|
||||||
|
size_t matchLength;
|
||||||
|
size_t offset;
|
||||||
|
} seq_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
BITv06_DStream_t DStream;
|
||||||
|
FSEv06_DState_t stateLL;
|
||||||
|
FSEv06_DState_t stateOffb;
|
||||||
|
FSEv06_DState_t stateML;
|
||||||
|
size_t prevOffset[ZSTDv06_REP_INIT];
|
||||||
|
} seqState_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void ZSTDv06_decodeSequence(seq_t* seq, seqState_t* seqState)
|
||||||
|
{
|
||||||
|
/* Literal length */
|
||||||
|
U32 const llCode = FSEv06_peekSymbol(&(seqState->stateLL));
|
||||||
|
U32 const mlCode = FSEv06_peekSymbol(&(seqState->stateML));
|
||||||
|
U32 const ofCode = FSEv06_peekSymbol(&(seqState->stateOffb)); /* <= maxOff, by table construction */
|
||||||
|
|
||||||
|
U32 const llBits = LL_bits[llCode];
|
||||||
|
U32 const mlBits = ML_bits[mlCode];
|
||||||
|
U32 const ofBits = ofCode;
|
||||||
|
U32 const totalBits = llBits+mlBits+ofBits;
|
||||||
|
|
||||||
|
static const U32 LL_base[MaxLL+1] = {
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||||
|
16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
|
||||||
|
0x2000, 0x4000, 0x8000, 0x10000 };
|
||||||
|
|
||||||
|
static const U32 ML_base[MaxML+1] = {
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||||
|
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||||
|
32, 34, 36, 38, 40, 44, 48, 56, 64, 80, 96, 0x80, 0x100, 0x200, 0x400, 0x800,
|
||||||
|
0x1000, 0x2000, 0x4000, 0x8000, 0x10000 };
|
||||||
|
|
||||||
|
static const U32 OF_base[MaxOff+1] = {
|
||||||
|
0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F,
|
||||||
|
0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF,
|
||||||
|
0xFFFF, 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF,
|
||||||
|
0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, /*fake*/ 1, 1 };
|
||||||
|
|
||||||
|
/* sequence */
|
||||||
|
{ size_t offset;
|
||||||
|
if (!ofCode)
|
||||||
|
offset = 0;
|
||||||
|
else {
|
||||||
|
offset = OF_base[ofCode] + BITv06_readBits(&(seqState->DStream), ofBits); /* <= 26 bits */
|
||||||
|
if (MEM_32bits()) BITv06_reloadDStream(&(seqState->DStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset < ZSTDv06_REP_NUM) {
|
||||||
|
if (llCode == 0 && offset <= 1) offset = 1-offset;
|
||||||
|
|
||||||
|
if (offset != 0) {
|
||||||
|
size_t temp = seqState->prevOffset[offset];
|
||||||
|
if (offset != 1) {
|
||||||
|
seqState->prevOffset[2] = seqState->prevOffset[1];
|
||||||
|
}
|
||||||
|
seqState->prevOffset[1] = seqState->prevOffset[0];
|
||||||
|
seqState->prevOffset[0] = offset = temp;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
offset = seqState->prevOffset[0];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
offset -= ZSTDv06_REP_MOVE;
|
||||||
|
seqState->prevOffset[2] = seqState->prevOffset[1];
|
||||||
|
seqState->prevOffset[1] = seqState->prevOffset[0];
|
||||||
|
seqState->prevOffset[0] = offset;
|
||||||
|
}
|
||||||
|
seq->offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
seq->matchLength = ML_base[mlCode] + MINMATCH + ((mlCode>31) ? BITv06_readBits(&(seqState->DStream), mlBits) : 0); /* <= 16 bits */
|
||||||
|
if (MEM_32bits() && (mlBits+llBits>24)) BITv06_reloadDStream(&(seqState->DStream));
|
||||||
|
|
||||||
|
seq->litLength = LL_base[llCode] + ((llCode>15) ? BITv06_readBits(&(seqState->DStream), llBits) : 0); /* <= 16 bits */
|
||||||
|
if (MEM_32bits() ||
|
||||||
|
(totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BITv06_reloadDStream(&(seqState->DStream));
|
||||||
|
|
||||||
|
/* ANS state update */
|
||||||
|
FSEv06_updateState(&(seqState->stateLL), &(seqState->DStream)); /* <= 9 bits */
|
||||||
|
FSEv06_updateState(&(seqState->stateML), &(seqState->DStream)); /* <= 9 bits */
|
||||||
|
if (MEM_32bits()) BITv06_reloadDStream(&(seqState->DStream)); /* <= 18 bits */
|
||||||
|
FSEv06_updateState(&(seqState->stateOffb), &(seqState->DStream)); /* <= 8 bits */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t ZSTDv06_execSequence(BYTE* op,
|
||||||
|
BYTE* const oend, seq_t sequence,
|
||||||
|
const BYTE** litPtr, const BYTE* const litLimit_8,
|
||||||
|
const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
|
||||||
|
{
|
||||||
|
BYTE* const oLitEnd = op + sequence.litLength;
|
||||||
|
size_t const sequenceLength = sequence.litLength + sequence.matchLength;
|
||||||
|
BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
|
||||||
|
BYTE* const oend_8 = oend-8;
|
||||||
|
const BYTE* const iLitEnd = *litPtr + sequence.litLength;
|
||||||
|
const BYTE* match = oLitEnd - sequence.offset;
|
||||||
|
|
||||||
|
/* check */
|
||||||
|
if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
|
||||||
|
if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
|
||||||
|
if (iLitEnd > litLimit_8) return ERROR(corruption_detected); /* over-read beyond lit buffer */
|
||||||
|
|
||||||
|
/* copy Literals */
|
||||||
|
ZSTDv06_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
|
||||||
|
op = oLitEnd;
|
||||||
|
*litPtr = iLitEnd; /* update for next sequence */
|
||||||
|
|
||||||
|
/* copy Match */
|
||||||
|
if (sequence.offset > (size_t)(oLitEnd - base)) {
|
||||||
|
/* offset beyond prefix */
|
||||||
|
if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
|
||||||
|
match = dictEnd - (base-match);
|
||||||
|
if (match + sequence.matchLength <= dictEnd) {
|
||||||
|
memmove(oLitEnd, match, sequence.matchLength);
|
||||||
|
return sequenceLength;
|
||||||
|
}
|
||||||
|
/* span extDict & currentPrefixSegment */
|
||||||
|
{ size_t const length1 = dictEnd - match;
|
||||||
|
memmove(oLitEnd, match, length1);
|
||||||
|
op = oLitEnd + length1;
|
||||||
|
sequence.matchLength -= length1;
|
||||||
|
match = base;
|
||||||
|
} }
|
||||||
|
|
||||||
|
/* match within prefix */
|
||||||
|
if (sequence.offset < 8) {
|
||||||
|
/* close range match, overlap */
|
||||||
|
static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
|
||||||
|
static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
|
||||||
|
int const sub2 = dec64table[sequence.offset];
|
||||||
|
op[0] = match[0];
|
||||||
|
op[1] = match[1];
|
||||||
|
op[2] = match[2];
|
||||||
|
op[3] = match[3];
|
||||||
|
match += dec32table[sequence.offset];
|
||||||
|
ZSTDv06_copy4(op+4, match);
|
||||||
|
match -= sub2;
|
||||||
|
} else {
|
||||||
|
ZSTDv06_copy8(op, match);
|
||||||
|
}
|
||||||
|
op += 8; match += 8;
|
||||||
|
|
||||||
|
if (oMatchEnd > oend-(16-MINMATCH)) {
|
||||||
|
if (op < oend_8) {
|
||||||
|
ZSTDv06_wildcopy(op, match, oend_8 - op);
|
||||||
|
match += oend_8 - op;
|
||||||
|
op = oend_8;
|
||||||
|
}
|
||||||
|
while (op < oMatchEnd) *op++ = *match++;
|
||||||
|
} else {
|
||||||
|
ZSTDv06_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
|
||||||
|
}
|
||||||
|
return sequenceLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t ZSTDv06_decompressSequences(
|
||||||
|
ZSTDv06_DCtx* dctx,
|
||||||
|
void* dst, size_t maxDstSize,
|
||||||
|
const void* seqStart, size_t seqSize)
|
||||||
|
{
|
||||||
|
const BYTE* ip = (const BYTE*)seqStart;
|
||||||
|
const BYTE* const iend = ip + seqSize;
|
||||||
|
BYTE* const ostart = (BYTE* const)dst;
|
||||||
|
BYTE* const oend = ostart + maxDstSize;
|
||||||
|
BYTE* op = ostart;
|
||||||
|
const BYTE* litPtr = dctx->litPtr;
|
||||||
|
const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
|
||||||
|
const BYTE* const litEnd = litPtr + dctx->litSize;
|
||||||
|
FSEv06_DTable* DTableLL = dctx->LLTable;
|
||||||
|
FSEv06_DTable* DTableML = dctx->MLTable;
|
||||||
|
FSEv06_DTable* DTableOffb = dctx->OffTable;
|
||||||
|
const BYTE* const base = (const BYTE*) (dctx->base);
|
||||||
|
const BYTE* const vBase = (const BYTE*) (dctx->vBase);
|
||||||
|
const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
|
||||||
|
int nbSeq;
|
||||||
|
|
||||||
|
/* Build Decoding Tables */
|
||||||
|
{ size_t const seqHSize = ZSTDv06_decodeSeqHeaders(&nbSeq, DTableLL, DTableML, DTableOffb, dctx->flagRepeatTable, ip, seqSize);
|
||||||
|
if (ZSTDv06_isError(seqHSize)) return seqHSize;
|
||||||
|
ip += seqHSize;
|
||||||
|
dctx->flagRepeatTable = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Regen sequences */
|
||||||
|
if (nbSeq) {
|
||||||
|
seq_t sequence;
|
||||||
|
seqState_t seqState;
|
||||||
|
|
||||||
|
memset(&sequence, 0, sizeof(sequence));
|
||||||
|
sequence.offset = REPCODE_STARTVALUE;
|
||||||
|
{ U32 i; for (i=0; i<ZSTDv06_REP_INIT; i++) seqState.prevOffset[i] = REPCODE_STARTVALUE; }
|
||||||
|
{ size_t const errorCode = BITv06_initDStream(&(seqState.DStream), ip, iend-ip);
|
||||||
|
if (ERR_isError(errorCode)) return ERROR(corruption_detected); }
|
||||||
|
FSEv06_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
|
||||||
|
FSEv06_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
|
||||||
|
FSEv06_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
|
||||||
|
|
||||||
|
for ( ; (BITv06_reloadDStream(&(seqState.DStream)) <= BITv06_DStream_completed) && nbSeq ; ) {
|
||||||
|
nbSeq--;
|
||||||
|
ZSTDv06_decodeSequence(&sequence, &seqState);
|
||||||
|
|
||||||
|
#if 0 /* debug */
|
||||||
|
static BYTE* start = NULL;
|
||||||
|
if (start==NULL) start = op;
|
||||||
|
size_t pos = (size_t)(op-start);
|
||||||
|
if ((pos >= 5810037) && (pos < 5810400))
|
||||||
|
printf("Dpos %6u :%5u literals & match %3u bytes at distance %6u \n",
|
||||||
|
pos, (U32)sequence.litLength, (U32)sequence.matchLength, (U32)sequence.offset);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{ size_t const oneSeqSize = ZSTDv06_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
|
||||||
|
if (ZSTDv06_isError(oneSeqSize)) return oneSeqSize;
|
||||||
|
op += oneSeqSize;
|
||||||
|
} }
|
||||||
|
|
||||||
|
/* check if reached exact end */
|
||||||
|
if (nbSeq) return ERROR(corruption_detected);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* last literal segment */
|
||||||
|
{ size_t const lastLLSize = litEnd - litPtr;
|
||||||
|
if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
|
||||||
|
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
||||||
|
memcpy(op, litPtr, lastLLSize);
|
||||||
|
op += lastLLSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return op-ostart;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ZSTDv06_checkContinuity(ZSTDv06_DCtx* dctx, const void* dst)
|
||||||
|
{
|
||||||
|
if (dst != dctx->previousDstEnd) { /* not contiguous */
|
||||||
|
dctx->dictEnd = dctx->previousDstEnd;
|
||||||
|
dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
|
||||||
|
dctx->base = dst;
|
||||||
|
dctx->previousDstEnd = dst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t ZSTDv06_decompressBlock_internal(ZSTDv06_DCtx* dctx,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t srcSize)
|
||||||
|
{ /* blockType == blockCompressed */
|
||||||
|
const BYTE* ip = (const BYTE*)src;
|
||||||
|
|
||||||
|
if (srcSize >= ZSTDv06_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);
|
||||||
|
|
||||||
|
/* Decode literals sub-block */
|
||||||
|
{ size_t const litCSize = ZSTDv06_decodeLiteralsBlock(dctx, src, srcSize);
|
||||||
|
if (ZSTDv06_isError(litCSize)) return litCSize;
|
||||||
|
ip += litCSize;
|
||||||
|
srcSize -= litCSize;
|
||||||
|
}
|
||||||
|
return ZSTDv06_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t ZSTDv06_decompressBlock(ZSTDv06_DCtx* dctx,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
ZSTDv06_checkContinuity(dctx, dst);
|
||||||
|
return ZSTDv06_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! ZSTDv06_decompressFrame() :
|
||||||
|
* `dctx` must be properly initialized */
|
||||||
|
static size_t ZSTDv06_decompressFrame(ZSTDv06_DCtx* dctx,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
const BYTE* ip = (const BYTE*)src;
|
||||||
|
const BYTE* const iend = ip + srcSize;
|
||||||
|
BYTE* const ostart = (BYTE* const)dst;
|
||||||
|
BYTE* op = ostart;
|
||||||
|
BYTE* const oend = ostart + dstCapacity;
|
||||||
|
size_t remainingSize = srcSize;
|
||||||
|
blockProperties_t blockProperties = { bt_compressed, 0 };
|
||||||
|
|
||||||
|
/* check */
|
||||||
|
if (srcSize < ZSTDv06_frameHeaderSize_min+ZSTDv06_blockHeaderSize) return ERROR(srcSize_wrong);
|
||||||
|
|
||||||
|
/* Frame Header */
|
||||||
|
{ size_t const frameHeaderSize = ZSTDv06_frameHeaderSize(src, ZSTDv06_frameHeaderSize_min);
|
||||||
|
if (ZSTDv06_isError(frameHeaderSize)) return frameHeaderSize;
|
||||||
|
if (srcSize < frameHeaderSize+ZSTDv06_blockHeaderSize) return ERROR(srcSize_wrong);
|
||||||
|
if (ZSTDv06_decodeFrameHeader(dctx, src, frameHeaderSize)) return ERROR(corruption_detected);
|
||||||
|
ip += frameHeaderSize; remainingSize -= frameHeaderSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop on each block */
|
||||||
|
while (1) {
|
||||||
|
size_t decodedSize=0;
|
||||||
|
size_t const cBlockSize = ZSTDv06_getcBlockSize(ip, iend-ip, &blockProperties);
|
||||||
|
if (ZSTDv06_isError(cBlockSize)) return cBlockSize;
|
||||||
|
|
||||||
|
ip += ZSTDv06_blockHeaderSize;
|
||||||
|
remainingSize -= ZSTDv06_blockHeaderSize;
|
||||||
|
if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
|
||||||
|
|
||||||
|
switch(blockProperties.blockType)
|
||||||
|
{
|
||||||
|
case bt_compressed:
|
||||||
|
decodedSize = ZSTDv06_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
|
||||||
|
break;
|
||||||
|
case bt_raw :
|
||||||
|
decodedSize = ZSTDv06_copyRawBlock(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 (ZSTDv06_isError(decodedSize)) return decodedSize;
|
||||||
|
op += decodedSize;
|
||||||
|
ip += cBlockSize;
|
||||||
|
remainingSize -= cBlockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return op-ostart;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t ZSTDv06_decompress_usingPreparedDCtx(ZSTDv06_DCtx* dctx, const ZSTDv06_DCtx* refDCtx,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
ZSTDv06_copyDCtx(dctx, refDCtx);
|
||||||
|
ZSTDv06_checkContinuity(dctx, dst);
|
||||||
|
return ZSTDv06_decompressFrame(dctx, dst, dstCapacity, src, srcSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t ZSTDv06_decompress_usingDict(ZSTDv06_DCtx* dctx,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t srcSize,
|
||||||
|
const void* dict, size_t dictSize)
|
||||||
|
{
|
||||||
|
ZSTDv06_decompressBegin_usingDict(dctx, dict, dictSize);
|
||||||
|
ZSTDv06_checkContinuity(dctx, dst);
|
||||||
|
return ZSTDv06_decompressFrame(dctx, dst, dstCapacity, src, srcSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t ZSTDv06_decompressDCtx(ZSTDv06_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
return ZSTDv06_decompress_usingDict(dctx, dst, dstCapacity, src, srcSize, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t ZSTDv06_decompress(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
#if defined(ZSTDv06_HEAPMODE) && (ZSTDv06_HEAPMODE==1)
|
||||||
|
size_t regenSize;
|
||||||
|
ZSTDv06_DCtx* dctx = ZSTDv06_createDCtx();
|
||||||
|
if (dctx==NULL) return ERROR(memory_allocation);
|
||||||
|
regenSize = ZSTDv06_decompressDCtx(dctx, dst, dstCapacity, src, srcSize);
|
||||||
|
ZSTDv06_freeDCtx(dctx);
|
||||||
|
return regenSize;
|
||||||
|
#else /* stack mode */
|
||||||
|
ZSTDv06_DCtx dctx;
|
||||||
|
return ZSTDv06_decompressDCtx(&dctx, dst, dstCapacity, src, srcSize);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*_******************************
|
||||||
|
* Streaming Decompression API
|
||||||
|
********************************/
|
||||||
|
size_t ZSTDv06_nextSrcSizeToDecompress(ZSTDv06_DCtx* dctx)
|
||||||
|
{
|
||||||
|
return dctx->expected;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ZSTDv06_decompressContinue(ZSTDv06_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
/* Sanity check */
|
||||||
|
if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
|
||||||
|
if (dstCapacity) ZSTDv06_checkContinuity(dctx, dst);
|
||||||
|
|
||||||
|
/* Decompress : frame header; part 1 */
|
||||||
|
switch (dctx->stage)
|
||||||
|
{
|
||||||
|
case ZSTDds_getFrameHeaderSize :
|
||||||
|
if (srcSize != ZSTDv06_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
|
||||||
|
dctx->headerSize = ZSTDv06_frameHeaderSize(src, ZSTDv06_frameHeaderSize_min);
|
||||||
|
if (ZSTDv06_isError(dctx->headerSize)) return dctx->headerSize;
|
||||||
|
memcpy(dctx->headerBuffer, src, ZSTDv06_frameHeaderSize_min);
|
||||||
|
if (dctx->headerSize > ZSTDv06_frameHeaderSize_min) {
|
||||||
|
dctx->expected = dctx->headerSize - ZSTDv06_frameHeaderSize_min;
|
||||||
|
dctx->stage = ZSTDds_decodeFrameHeader;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dctx->expected = 0; /* not necessary to copy more */
|
||||||
|
|
||||||
|
case ZSTDds_decodeFrameHeader:
|
||||||
|
{ size_t result;
|
||||||
|
memcpy(dctx->headerBuffer + ZSTDv06_frameHeaderSize_min, src, dctx->expected);
|
||||||
|
result = ZSTDv06_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize);
|
||||||
|
if (ZSTDv06_isError(result)) return result;
|
||||||
|
dctx->expected = ZSTDv06_blockHeaderSize;
|
||||||
|
dctx->stage = ZSTDds_decodeBlockHeader;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case ZSTDds_decodeBlockHeader:
|
||||||
|
{ blockProperties_t bp;
|
||||||
|
size_t const cBlockSize = ZSTDv06_getcBlockSize(src, ZSTDv06_blockHeaderSize, &bp);
|
||||||
|
if (ZSTDv06_isError(cBlockSize)) return cBlockSize;
|
||||||
|
if (bp.blockType == bt_end) {
|
||||||
|
dctx->expected = 0;
|
||||||
|
dctx->stage = ZSTDds_getFrameHeaderSize;
|
||||||
|
} else {
|
||||||
|
dctx->expected = cBlockSize;
|
||||||
|
dctx->bType = bp.blockType;
|
||||||
|
dctx->stage = ZSTDds_decompressBlock;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case ZSTDds_decompressBlock:
|
||||||
|
{ size_t rSize;
|
||||||
|
switch(dctx->bType)
|
||||||
|
{
|
||||||
|
case bt_compressed:
|
||||||
|
rSize = ZSTDv06_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
|
||||||
|
break;
|
||||||
|
case bt_raw :
|
||||||
|
rSize = ZSTDv06_copyRawBlock(dst, dstCapacity, 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); /* impossible */
|
||||||
|
}
|
||||||
|
dctx->stage = ZSTDds_decodeBlockHeader;
|
||||||
|
dctx->expected = ZSTDv06_blockHeaderSize;
|
||||||
|
dctx->previousDstEnd = (char*)dst + rSize;
|
||||||
|
return rSize;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return ERROR(GENERIC); /* impossible */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ZSTDv06_refDictContent(ZSTDv06_DCtx* dctx, const void* dict, size_t dictSize)
|
||||||
|
{
|
||||||
|
dctx->dictEnd = dctx->previousDstEnd;
|
||||||
|
dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
|
||||||
|
dctx->base = dict;
|
||||||
|
dctx->previousDstEnd = (const char*)dict + dictSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t ZSTDv06_loadEntropy(ZSTDv06_DCtx* dctx, const void* dict, size_t dictSize)
|
||||||
|
{
|
||||||
|
size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, litlengthHeaderSize;
|
||||||
|
|
||||||
|
hSize = HUFv06_readDTableX4(dctx->hufTableX4, dict, dictSize);
|
||||||
|
if (HUFv06_isError(hSize)) return ERROR(dictionary_corrupted);
|
||||||
|
dict = (const char*)dict + hSize;
|
||||||
|
dictSize -= hSize;
|
||||||
|
|
||||||
|
{ short offcodeNCount[MaxOff+1];
|
||||||
|
U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
|
||||||
|
offcodeHeaderSize = FSEv06_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
|
||||||
|
if (FSEv06_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
{ size_t const errorCode = FSEv06_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
|
||||||
|
if (FSEv06_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
|
dict = (const char*)dict + offcodeHeaderSize;
|
||||||
|
dictSize -= offcodeHeaderSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
{ short matchlengthNCount[MaxML+1];
|
||||||
|
unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
|
||||||
|
matchlengthHeaderSize = FSEv06_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
|
||||||
|
if (FSEv06_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
{ size_t const errorCode = FSEv06_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
|
||||||
|
if (FSEv06_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
|
dict = (const char*)dict + matchlengthHeaderSize;
|
||||||
|
dictSize -= matchlengthHeaderSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
{ short litlengthNCount[MaxLL+1];
|
||||||
|
unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
|
||||||
|
litlengthHeaderSize = FSEv06_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
|
||||||
|
if (FSEv06_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
|
{ size_t const errorCode = FSEv06_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
|
||||||
|
if (FSEv06_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
||||||
|
}
|
||||||
|
|
||||||
|
dctx->flagRepeatTable = 1;
|
||||||
|
return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t ZSTDv06_decompress_insertDictionary(ZSTDv06_DCtx* dctx, const void* dict, size_t dictSize)
|
||||||
|
{
|
||||||
|
size_t eSize;
|
||||||
|
U32 const magic = MEM_readLE32(dict);
|
||||||
|
if (magic != ZSTDv06_DICT_MAGIC) {
|
||||||
|
/* pure content mode */
|
||||||
|
ZSTDv06_refDictContent(dctx, dict, dictSize);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* load entropy tables */
|
||||||
|
dict = (const char*)dict + 4;
|
||||||
|
dictSize -= 4;
|
||||||
|
eSize = ZSTDv06_loadEntropy(dctx, dict, dictSize);
|
||||||
|
if (ZSTDv06_isError(eSize)) return ERROR(dictionary_corrupted);
|
||||||
|
|
||||||
|
/* reference dictionary content */
|
||||||
|
dict = (const char*)dict + eSize;
|
||||||
|
dictSize -= eSize;
|
||||||
|
ZSTDv06_refDictContent(dctx, dict, dictSize);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t ZSTDv06_decompressBegin_usingDict(ZSTDv06_DCtx* dctx, const void* dict, size_t dictSize)
|
||||||
|
{
|
||||||
|
{ size_t const errorCode = ZSTDv06_decompressBegin(dctx);
|
||||||
|
if (ZSTDv06_isError(errorCode)) return errorCode; }
|
||||||
|
|
||||||
|
if (dict && dictSize) {
|
||||||
|
size_t const errorCode = ZSTDv06_decompress_insertDictionary(dctx, dict, dictSize);
|
||||||
|
if (ZSTDv06_isError(errorCode)) return ERROR(dictionary_corrupted);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Buffered version of Zstd compression library
|
||||||
|
Copyright (C) 2015-2016, 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 homepage : http://www.zstd.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*-***************************************************************************
|
||||||
|
* Streaming decompression howto
|
||||||
|
*
|
||||||
|
* A ZBUFFv06_DCtx object is required to track streaming operations.
|
||||||
|
* Use ZBUFFv06_createDCtx() and ZBUFFv06_freeDCtx() to create/release resources.
|
||||||
|
* Use ZBUFFv06_decompressInit() to start a new decompression operation,
|
||||||
|
* or ZBUFFv06_decompressInitDictionary() if decompression requires a dictionary.
|
||||||
|
* Note that ZBUFFv06_DCtx objects can be re-init multiple times.
|
||||||
|
*
|
||||||
|
* Use ZBUFFv06_decompressContinue() repetitively to consume your input.
|
||||||
|
* *srcSizePtr and *dstCapacityPtr can be any size.
|
||||||
|
* The function will report how many bytes were read or written by modifying *srcSizePtr and *dstCapacityPtr.
|
||||||
|
* Note that it may not consume the entire input, in which case it's up to the caller to present remaining input again.
|
||||||
|
* The content of @dst will be overwritten (up to *dstCapacityPtr) at each function call, so save its content if it matters, or change @dst.
|
||||||
|
* @return : a hint to preferred nb of bytes to use as input for next function call (it's only a hint, to help latency),
|
||||||
|
* or 0 when a frame is completely decoded,
|
||||||
|
* or an error code, which can be tested using ZBUFFv06_isError().
|
||||||
|
*
|
||||||
|
* Hint : recommended buffer sizes (not compulsory) : ZBUFFv06_recommendedDInSize() and ZBUFFv06_recommendedDOutSize()
|
||||||
|
* output : ZBUFFv06_recommendedDOutSize==128 KB block size is the internal unit, it ensures it's always possible to write a full block when decoded.
|
||||||
|
* input : ZBUFFv06_recommendedDInSize == 128KB + 3;
|
||||||
|
* just follow indications from ZBUFFv06_decompressContinue() to minimize latency. It should always be <= 128 KB + 3 .
|
||||||
|
* *******************************************************************************/
|
||||||
|
|
||||||
|
typedef enum { ZBUFFds_init, ZBUFFds_loadHeader,
|
||||||
|
ZBUFFds_read, ZBUFFds_load, ZBUFFds_flush } ZBUFFv06_dStage;
|
||||||
|
|
||||||
|
/* *** Resource management *** */
|
||||||
|
struct ZBUFFv06_DCtx_s {
|
||||||
|
ZSTDv06_DCtx* zd;
|
||||||
|
ZSTDv06_frameParams fParams;
|
||||||
|
ZBUFFv06_dStage stage;
|
||||||
|
char* inBuff;
|
||||||
|
size_t inBuffSize;
|
||||||
|
size_t inPos;
|
||||||
|
char* outBuff;
|
||||||
|
size_t outBuffSize;
|
||||||
|
size_t outStart;
|
||||||
|
size_t outEnd;
|
||||||
|
size_t blockSize;
|
||||||
|
BYTE headerBuffer[ZSTDv06_FRAMEHEADERSIZE_MAX];
|
||||||
|
size_t lhSize;
|
||||||
|
}; /* typedef'd to ZBUFFv06_DCtx within "zstd_buffered.h" */
|
||||||
|
|
||||||
|
|
||||||
|
ZBUFFv06_DCtx* ZBUFFv06_createDCtx(void)
|
||||||
|
{
|
||||||
|
ZBUFFv06_DCtx* zbd = (ZBUFFv06_DCtx*)malloc(sizeof(ZBUFFv06_DCtx));
|
||||||
|
if (zbd==NULL) return NULL;
|
||||||
|
memset(zbd, 0, sizeof(*zbd));
|
||||||
|
zbd->zd = ZSTDv06_createDCtx();
|
||||||
|
zbd->stage = ZBUFFds_init;
|
||||||
|
return zbd;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ZBUFFv06_freeDCtx(ZBUFFv06_DCtx* zbd)
|
||||||
|
{
|
||||||
|
if (zbd==NULL) return 0; /* support free on null */
|
||||||
|
ZSTDv06_freeDCtx(zbd->zd);
|
||||||
|
free(zbd->inBuff);
|
||||||
|
free(zbd->outBuff);
|
||||||
|
free(zbd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* *** Initialization *** */
|
||||||
|
|
||||||
|
size_t ZBUFFv06_decompressInitDictionary(ZBUFFv06_DCtx* zbd, const void* dict, size_t dictSize)
|
||||||
|
{
|
||||||
|
zbd->stage = ZBUFFds_loadHeader;
|
||||||
|
zbd->lhSize = zbd->inPos = zbd->outStart = zbd->outEnd = 0;
|
||||||
|
return ZSTDv06_decompressBegin_usingDict(zbd->zd, dict, dictSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ZBUFFv06_decompressInit(ZBUFFv06_DCtx* zbd)
|
||||||
|
{
|
||||||
|
return ZBUFFv06_decompressInitDictionary(zbd, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MEM_STATIC size_t ZBUFFv06_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
size_t length = MIN(dstCapacity, srcSize);
|
||||||
|
memcpy(dst, src, length);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* *** Decompression *** */
|
||||||
|
|
||||||
|
size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* zbd,
|
||||||
|
void* dst, size_t* dstCapacityPtr,
|
||||||
|
const void* src, size_t* srcSizePtr)
|
||||||
|
{
|
||||||
|
const char* const istart = (const char*)src;
|
||||||
|
const char* const iend = istart + *srcSizePtr;
|
||||||
|
const char* ip = istart;
|
||||||
|
char* const ostart = (char*)dst;
|
||||||
|
char* const oend = ostart + *dstCapacityPtr;
|
||||||
|
char* op = ostart;
|
||||||
|
U32 notDone = 1;
|
||||||
|
|
||||||
|
while (notDone) {
|
||||||
|
switch(zbd->stage)
|
||||||
|
{
|
||||||
|
case ZBUFFds_init :
|
||||||
|
return ERROR(init_missing);
|
||||||
|
|
||||||
|
case ZBUFFds_loadHeader :
|
||||||
|
{ size_t const hSize = ZSTDv06_getFrameParams(&(zbd->fParams), zbd->headerBuffer, zbd->lhSize);
|
||||||
|
if (hSize != 0) {
|
||||||
|
size_t const toLoad = hSize - zbd->lhSize; /* if hSize!=0, hSize > zbd->lhSize */
|
||||||
|
if (ZSTDv06_isError(hSize)) return hSize;
|
||||||
|
if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */
|
||||||
|
memcpy(zbd->headerBuffer + zbd->lhSize, ip, iend-ip);
|
||||||
|
zbd->lhSize += iend-ip; ip = iend; notDone = 0;
|
||||||
|
*dstCapacityPtr = 0;
|
||||||
|
return (hSize - zbd->lhSize) + ZSTDv06_blockHeaderSize; /* remaining header bytes + next block header */
|
||||||
|
}
|
||||||
|
memcpy(zbd->headerBuffer + zbd->lhSize, ip, toLoad); zbd->lhSize = hSize; ip += toLoad;
|
||||||
|
break;
|
||||||
|
} }
|
||||||
|
|
||||||
|
/* Consume header */
|
||||||
|
{ size_t const h1Size = ZSTDv06_nextSrcSizeToDecompress(zbd->zd); /* == ZSTDv06_frameHeaderSize_min */
|
||||||
|
size_t const h1Result = ZSTDv06_decompressContinue(zbd->zd, NULL, 0, zbd->headerBuffer, h1Size);
|
||||||
|
if (ZSTDv06_isError(h1Result)) return h1Result;
|
||||||
|
if (h1Size < zbd->lhSize) { /* long header */
|
||||||
|
size_t const h2Size = ZSTDv06_nextSrcSizeToDecompress(zbd->zd);
|
||||||
|
size_t const h2Result = ZSTDv06_decompressContinue(zbd->zd, NULL, 0, zbd->headerBuffer+h1Size, h2Size);
|
||||||
|
if (ZSTDv06_isError(h2Result)) return h2Result;
|
||||||
|
} }
|
||||||
|
|
||||||
|
/* Frame header instruct buffer sizes */
|
||||||
|
{ size_t const blockSize = MIN(1 << zbd->fParams.windowLog, ZSTDv06_BLOCKSIZE_MAX);
|
||||||
|
zbd->blockSize = blockSize;
|
||||||
|
if (zbd->inBuffSize < blockSize) {
|
||||||
|
free(zbd->inBuff);
|
||||||
|
zbd->inBuffSize = blockSize;
|
||||||
|
zbd->inBuff = (char*)malloc(blockSize);
|
||||||
|
if (zbd->inBuff == NULL) return ERROR(memory_allocation);
|
||||||
|
}
|
||||||
|
{ size_t const neededOutSize = ((size_t)1 << zbd->fParams.windowLog) + blockSize;
|
||||||
|
if (zbd->outBuffSize < neededOutSize) {
|
||||||
|
free(zbd->outBuff);
|
||||||
|
zbd->outBuffSize = neededOutSize;
|
||||||
|
zbd->outBuff = (char*)malloc(neededOutSize);
|
||||||
|
if (zbd->outBuff == NULL) return ERROR(memory_allocation);
|
||||||
|
} } }
|
||||||
|
zbd->stage = ZBUFFds_read;
|
||||||
|
|
||||||
|
case ZBUFFds_read:
|
||||||
|
{ size_t const neededInSize = ZSTDv06_nextSrcSizeToDecompress(zbd->zd);
|
||||||
|
if (neededInSize==0) { /* end of frame */
|
||||||
|
zbd->stage = ZBUFFds_init;
|
||||||
|
notDone = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */
|
||||||
|
size_t const decodedSize = ZSTDv06_decompressContinue(zbd->zd,
|
||||||
|
zbd->outBuff + zbd->outStart, zbd->outBuffSize - zbd->outStart,
|
||||||
|
ip, neededInSize);
|
||||||
|
if (ZSTDv06_isError(decodedSize)) return decodedSize;
|
||||||
|
ip += neededInSize;
|
||||||
|
if (!decodedSize) break; /* this was just a header */
|
||||||
|
zbd->outEnd = zbd->outStart + decodedSize;
|
||||||
|
zbd->stage = ZBUFFds_flush;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ip==iend) { notDone = 0; break; } /* no more input */
|
||||||
|
zbd->stage = ZBUFFds_load;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ZBUFFds_load:
|
||||||
|
{ size_t const neededInSize = ZSTDv06_nextSrcSizeToDecompress(zbd->zd);
|
||||||
|
size_t const toLoad = neededInSize - zbd->inPos; /* should always be <= remaining space within inBuff */
|
||||||
|
size_t loadedSize;
|
||||||
|
if (toLoad > zbd->inBuffSize - zbd->inPos) return ERROR(corruption_detected); /* should never happen */
|
||||||
|
loadedSize = ZBUFFv06_limitCopy(zbd->inBuff + zbd->inPos, toLoad, ip, iend-ip);
|
||||||
|
ip += loadedSize;
|
||||||
|
zbd->inPos += loadedSize;
|
||||||
|
if (loadedSize < toLoad) { notDone = 0; break; } /* not enough input, wait for more */
|
||||||
|
|
||||||
|
/* decode loaded input */
|
||||||
|
{ size_t const decodedSize = ZSTDv06_decompressContinue(zbd->zd,
|
||||||
|
zbd->outBuff + zbd->outStart, zbd->outBuffSize - zbd->outStart,
|
||||||
|
zbd->inBuff, neededInSize);
|
||||||
|
if (ZSTDv06_isError(decodedSize)) return decodedSize;
|
||||||
|
zbd->inPos = 0; /* input is consumed */
|
||||||
|
if (!decodedSize) { zbd->stage = ZBUFFds_read; break; } /* this was just a header */
|
||||||
|
zbd->outEnd = zbd->outStart + decodedSize;
|
||||||
|
zbd->stage = ZBUFFds_flush;
|
||||||
|
// break; /* ZBUFFds_flush follows */
|
||||||
|
} }
|
||||||
|
|
||||||
|
case ZBUFFds_flush:
|
||||||
|
{ size_t const toFlushSize = zbd->outEnd - zbd->outStart;
|
||||||
|
size_t const flushedSize = ZBUFFv06_limitCopy(op, oend-op, zbd->outBuff + zbd->outStart, toFlushSize);
|
||||||
|
op += flushedSize;
|
||||||
|
zbd->outStart += flushedSize;
|
||||||
|
if (flushedSize == toFlushSize) {
|
||||||
|
zbd->stage = ZBUFFds_read;
|
||||||
|
if (zbd->outStart + zbd->blockSize > zbd->outBuffSize)
|
||||||
|
zbd->outStart = zbd->outEnd = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* cannot flush everything */
|
||||||
|
notDone = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: return ERROR(GENERIC); /* impossible */
|
||||||
|
} }
|
||||||
|
|
||||||
|
/* result */
|
||||||
|
*srcSizePtr = ip-istart;
|
||||||
|
*dstCapacityPtr = op-ostart;
|
||||||
|
{ size_t nextSrcSizeHint = ZSTDv06_nextSrcSizeToDecompress(zbd->zd);
|
||||||
|
if (nextSrcSizeHint > ZSTDv06_blockHeaderSize) nextSrcSizeHint+= ZSTDv06_blockHeaderSize; /* get following block header too */
|
||||||
|
nextSrcSizeHint -= zbd->inPos; /* already loaded*/
|
||||||
|
return nextSrcSizeHint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* Tool functions
|
||||||
|
***************************************/
|
||||||
|
size_t ZBUFFv06_recommendedDInSize(void) { return ZSTDv06_BLOCKSIZE_MAX + ZSTDv06_blockHeaderSize /* block header size*/ ; }
|
||||||
|
size_t ZBUFFv06_recommendedDOutSize(void) { return ZSTDv06_BLOCKSIZE_MAX; }
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
zstd_v06 - decoder for 0.6 format
|
||||||
|
Header File
|
||||||
|
Copyright (C) 2014-2016, 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
|
||||||
|
*/
|
||||||
|
#ifndef ZSTDv06_H
|
||||||
|
#define ZSTDv06_H
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-*************************************
|
||||||
|
* Dependencies
|
||||||
|
***************************************/
|
||||||
|
#include <stddef.h> /* size_t */
|
||||||
|
|
||||||
|
|
||||||
|
/*-***************************************************************
|
||||||
|
* Export parameters
|
||||||
|
*****************************************************************/
|
||||||
|
/*!
|
||||||
|
* ZSTDv06_DLL_EXPORT :
|
||||||
|
* Enable exporting of functions when building a Windows DLL
|
||||||
|
*/
|
||||||
|
#if defined(_WIN32) && defined(ZSTDv06_DLL_EXPORT) && (ZSTDv06_DLL_EXPORT==1)
|
||||||
|
# define ZSTDLIB_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
# define ZSTDLIB_API
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* Simple functions
|
||||||
|
***************************************/
|
||||||
|
/*! ZSTDv06_decompress() :
|
||||||
|
`compressedSize` : is the _exact_ size of the compressed blob, otherwise decompression will fail.
|
||||||
|
`dstCapacity` must be large enough, equal or larger than originalSize.
|
||||||
|
@return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
|
||||||
|
or an errorCode if it fails (which can be tested using ZSTDv06_isError()) */
|
||||||
|
ZSTDLIB_API size_t ZSTDv06_decompress( void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t compressedSize);
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* Helper functions
|
||||||
|
***************************************/
|
||||||
|
ZSTDLIB_API size_t ZSTDv06_compressBound(size_t srcSize); /*!< maximum compressed size (worst case scenario) */
|
||||||
|
|
||||||
|
/* Error Management */
|
||||||
|
ZSTDLIB_API unsigned ZSTDv06_isError(size_t code); /*!< tells if a `size_t` function result is an error code */
|
||||||
|
ZSTDLIB_API const char* ZSTDv06_getErrorName(size_t code); /*!< provides readable string for an error code */
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* Explicit memory management
|
||||||
|
***************************************/
|
||||||
|
/** Decompression context */
|
||||||
|
typedef struct ZSTDv06_DCtx_s ZSTDv06_DCtx;
|
||||||
|
ZSTDLIB_API ZSTDv06_DCtx* ZSTDv06_createDCtx(void);
|
||||||
|
ZSTDLIB_API size_t ZSTDv06_freeDCtx(ZSTDv06_DCtx* dctx); /*!< @return : errorCode */
|
||||||
|
|
||||||
|
/** ZSTDv06_decompressDCtx() :
|
||||||
|
* Same as ZSTDv06_decompress(), but requires an already allocated ZSTDv06_DCtx (see ZSTDv06_createDCtx()) */
|
||||||
|
ZSTDLIB_API size_t ZSTDv06_decompressDCtx(ZSTDv06_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
|
||||||
|
/*-***********************
|
||||||
|
* Dictionary API
|
||||||
|
*************************/
|
||||||
|
/*! ZSTDv06_decompress_usingDict() :
|
||||||
|
* Decompression using a pre-defined Dictionary content (see dictBuilder).
|
||||||
|
* Dictionary must be identical to the one used during compression, otherwise regenerated data will be corrupted.
|
||||||
|
* Note : dict can be NULL, in which case, it's equivalent to ZSTDv06_decompressDCtx() */
|
||||||
|
ZSTDLIB_API size_t ZSTDv06_decompress_usingDict(ZSTDv06_DCtx* dctx,
|
||||||
|
void* dst, size_t dstCapacity,
|
||||||
|
const void* src, size_t srcSize,
|
||||||
|
const void* dict,size_t dictSize);
|
||||||
|
|
||||||
|
|
||||||
|
/*-************************
|
||||||
|
* Advanced Streaming API
|
||||||
|
***************************/
|
||||||
|
|
||||||
|
typedef struct ZSTDv06_frameParams_s ZSTDv06_frameParams;
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZSTDv06_getFrameParams(ZSTDv06_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input */
|
||||||
|
ZSTDLIB_API size_t ZSTDv06_decompressBegin_usingDict(ZSTDv06_DCtx* dctx, const void* dict, size_t dictSize);
|
||||||
|
ZSTDLIB_API void ZSTDv06_copyDCtx(ZSTDv06_DCtx* dctx, const ZSTDv06_DCtx* preparedDCtx);
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZSTDv06_nextSrcSizeToDecompress(ZSTDv06_DCtx* dctx);
|
||||||
|
ZSTDLIB_API size_t ZSTDv06_decompressContinue(ZSTDv06_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* ZBUFF API
|
||||||
|
***************************************/
|
||||||
|
|
||||||
|
typedef struct ZBUFFv06_DCtx_s ZBUFFv06_DCtx;
|
||||||
|
ZSTDLIB_API ZBUFFv06_DCtx* ZBUFFv06_createDCtx(void);
|
||||||
|
ZSTDLIB_API size_t ZBUFFv06_freeDCtx(ZBUFFv06_DCtx* dctx);
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZBUFFv06_decompressInit(ZBUFFv06_DCtx* dctx);
|
||||||
|
ZSTDLIB_API size_t ZBUFFv06_decompressInitDictionary(ZBUFFv06_DCtx* dctx, const void* dict, size_t dictSize);
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* dctx,
|
||||||
|
void* dst, size_t* dstCapacityPtr,
|
||||||
|
const void* src, size_t* srcSizePtr);
|
||||||
|
|
||||||
|
/*-***************************************************************************
|
||||||
|
* Streaming decompression howto
|
||||||
|
*
|
||||||
|
* A ZBUFFv06_DCtx object is required to track streaming operations.
|
||||||
|
* Use ZBUFFv06_createDCtx() and ZBUFFv06_freeDCtx() to create/release resources.
|
||||||
|
* Use ZBUFFv06_decompressInit() to start a new decompression operation,
|
||||||
|
* or ZBUFFv06_decompressInitDictionary() if decompression requires a dictionary.
|
||||||
|
* Note that ZBUFFv06_DCtx objects can be re-init multiple times.
|
||||||
|
*
|
||||||
|
* Use ZBUFFv06_decompressContinue() repetitively to consume your input.
|
||||||
|
* *srcSizePtr and *dstCapacityPtr can be any size.
|
||||||
|
* The function will report how many bytes were read or written by modifying *srcSizePtr and *dstCapacityPtr.
|
||||||
|
* Note that it may not consume the entire input, in which case it's up to the caller to present remaining input again.
|
||||||
|
* The content of `dst` will be overwritten (up to *dstCapacityPtr) at each function call, so save its content if it matters, or change `dst`.
|
||||||
|
* @return : a hint to preferred nb of bytes to use as input for next function call (it's only a hint, to help latency),
|
||||||
|
* or 0 when a frame is completely decoded,
|
||||||
|
* or an error code, which can be tested using ZBUFFv06_isError().
|
||||||
|
*
|
||||||
|
* Hint : recommended buffer sizes (not compulsory) : ZBUFFv06_recommendedDInSize() and ZBUFFv06_recommendedDOutSize()
|
||||||
|
* output : ZBUFFv06_recommendedDOutSize== 128 KB block size is the internal unit, it ensures it's always possible to write a full block when decoded.
|
||||||
|
* input : ZBUFFv06_recommendedDInSize == 128KB + 3;
|
||||||
|
* just follow indications from ZBUFFv06_decompressContinue() to minimize latency. It should always be <= 128 KB + 3 .
|
||||||
|
* *******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* Tool functions
|
||||||
|
***************************************/
|
||||||
|
ZSTDLIB_API unsigned ZBUFFv06_isError(size_t errorCode);
|
||||||
|
ZSTDLIB_API const char* ZBUFFv06_getErrorName(size_t errorCode);
|
||||||
|
|
||||||
|
/** Functions below provide recommended buffer sizes for Compression or Decompression operations.
|
||||||
|
* These sizes are just hints, they tend to offer better latency */
|
||||||
|
ZSTDLIB_API size_t ZBUFFv06_recommendedDInSize(void);
|
||||||
|
ZSTDLIB_API size_t ZBUFFv06_recommendedDOutSize(void);
|
||||||
|
|
||||||
|
|
||||||
|
/*-*************************************
|
||||||
|
* Constants
|
||||||
|
***************************************/
|
||||||
|
#define ZSTDv06_MAGICNUMBER 0xFD2FB526 /* v0.6 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ZSTDv06_BUFFERED_H */
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
# local binary (Makefile)
|
# local binary (Makefile)
|
||||||
zstd
|
zstd
|
||||||
zstd32
|
zstd32
|
||||||
|
zstd-compress
|
||||||
|
zstd-decompress
|
||||||
fullbench
|
fullbench
|
||||||
fullbench32
|
fullbench32
|
||||||
fuzzer
|
fuzzer
|
||||||
@@ -9,6 +11,7 @@ zbufftest
|
|||||||
zbufftest32
|
zbufftest32
|
||||||
datagen
|
datagen
|
||||||
paramgrill
|
paramgrill
|
||||||
|
roundTripCrash
|
||||||
|
|
||||||
# Object files
|
# Object files
|
||||||
*.o
|
*.o
|
||||||
@@ -37,6 +40,9 @@ paramgrill
|
|||||||
dictionary
|
dictionary
|
||||||
grillResults.txt
|
grillResults.txt
|
||||||
_*
|
_*
|
||||||
|
tmp*
|
||||||
|
*.zst
|
||||||
|
result
|
||||||
|
|
||||||
# fuzzer
|
# fuzzer
|
||||||
afl
|
afl
|
||||||
|
|||||||
+66
-61
@@ -31,42 +31,33 @@
|
|||||||
# 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 numbers
|
|
||||||
LIBVER_MAJOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ../lib/common/zstd.h`
|
|
||||||
LIBVER_MINOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ../lib/common/zstd.h`
|
|
||||||
LIBVER_PATCH_SCRIPT:=`sed -n '/define ZSTD_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ../lib/common/zstd.h`
|
|
||||||
LIBVER_SCRIPT:= $(LIBVER_MAJOR_SCRIPT).$(LIBVER_MINOR_SCRIPT).$(LIBVER_PATCH_SCRIPT)
|
|
||||||
LIBVER_MAJOR := $(shell echo $(LIBVER_MAJOR_SCRIPT))
|
|
||||||
LIBVER_MINOR := $(shell echo $(LIBVER_MINOR_SCRIPT))
|
|
||||||
LIBVER_PATCH := $(shell echo $(LIBVER_PATCH_SCRIPT))
|
|
||||||
LIBVER := $(shell echo $(LIBVER_SCRIPT))
|
|
||||||
VERSION?= $(LIBVER)
|
|
||||||
|
|
||||||
DESTDIR?=
|
DESTDIR?=
|
||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
CPPFLAGS= -I../lib/common -DZSTD_VERSION=\"$(VERSION)\"
|
|
||||||
CFLAGS ?= -O3 # -falign-loops=32 # not always beneficial
|
|
||||||
CFLAGS += -std=c99 -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 -Wswitch-enum -Wstrict-prototypes -Wundef
|
|
||||||
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MOREFLAGS)
|
|
||||||
|
|
||||||
BINDIR = $(PREFIX)/bin
|
BINDIR = $(PREFIX)/bin
|
||||||
MANDIR = $(PREFIX)/share/man/man1
|
MANDIR = $(PREFIX)/share/man/man1
|
||||||
|
|
||||||
ZSTDDIR = ../lib
|
ZSTDDIR = ../lib
|
||||||
|
|
||||||
ZSTDCOMP_FILES := $(ZSTDDIR)/common/fse_decompress.c $(ZSTDDIR)/compress/zstd_compress.c $(ZSTDDIR)/compress/fse_compress.c $(ZSTDDIR)/compress/huf_compress.c $(ZSTDDIR)/common/zstd_common.c $(ZSTDDIR)/common/entropy_common.c
|
CPPFLAGS= -I$(ZSTDDIR)/common -I$(ZSTDDIR)/dictBuilder -DXXH_NAMESPACE=ZSTD_
|
||||||
ZSTDDECOMP_FILES := $(ZSTDDIR)/decompress/zstd_decompress.c $(ZSTDDIR)/common/fse_decompress.c $(ZSTDDIR)/decompress/huf_decompress.c $(ZSTDDIR)/common/zstd_common.c $(ZSTDDIR)/common/entropy_common.c
|
CFLAGS ?= -O3 # -falign-loops=32 # not always beneficial
|
||||||
ZDICT_FILES := $(ZSTDDIR)/dictBuilder/zdict.c $(ZSTDDIR)/dictBuilder/divsufsort.c
|
CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef
|
||||||
|
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MOREFLAGS)
|
||||||
|
|
||||||
|
|
||||||
|
ZSTDCOMMON_FILES := $(ZSTDDIR)/common/*.c
|
||||||
|
ZSTDCOMP_FILES := $(ZSTDDIR)/compress/zstd_compress.c $(ZSTDDIR)/compress/fse_compress.c $(ZSTDDIR)/compress/huf_compress.c
|
||||||
|
ZSTDDECOMP_FILES := $(ZSTDDIR)/decompress/huf_decompress.c $(ZSTDDIR)/decompress/zstd_decompress.c
|
||||||
|
ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES)
|
||||||
ZBUFF_FILES := $(ZSTDDIR)/compress/zbuff_compress.c $(ZSTDDIR)/decompress/zbuff_decompress.c
|
ZBUFF_FILES := $(ZSTDDIR)/compress/zbuff_compress.c $(ZSTDDIR)/decompress/zbuff_decompress.c
|
||||||
ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMP_FILES)
|
ZDICT_FILES := $(ZSTDDIR)/dictBuilder/*.c
|
||||||
|
|
||||||
ifeq ($(ZSTD_LEGACY_SUPPORT), 0)
|
ifeq ($(ZSTD_LEGACY_SUPPORT), 0)
|
||||||
CPPFLAGS += -DZSTD_LEGACY_SUPPORT=0
|
CPPFLAGS += -DZSTD_LEGACY_SUPPORT=0
|
||||||
ZSTD_FILES_LEGACY:=
|
ZSTDLEGACY_FILES:=
|
||||||
else
|
else
|
||||||
ZSTD_LEGACY_SUPPORT:=1
|
ZSTD_LEGACY_SUPPORT:=1
|
||||||
CPPFLAGS += -I../lib/legacy -I./legacy
|
CPPFLAGS += -I$(ZSTDDIR)/legacy -I./legacy
|
||||||
ZSTD_FILES_LEGACY:= $(ZSTDDIR)/legacy/zstd_v01.c $(ZSTDDIR)/legacy/zstd_v02.c $(ZSTDDIR)/legacy/zstd_v03.c \
|
ZSTDLEGACY_FILES:= $(ZSTDDIR)/legacy/*.c legacy/fileio_legacy.c
|
||||||
$(ZSTDDIR)/legacy/zstd_v04.c $(ZSTDDIR)/legacy/zstd_v05.c legacy/fileio_legacy.c
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
@@ -89,12 +80,12 @@ default: zstd
|
|||||||
|
|
||||||
all: zstd fullbench fuzzer zbufftest paramgrill datagen zstd32 fullbench32 fuzzer32 zbufftest32
|
all: zstd fullbench fuzzer zbufftest paramgrill datagen zstd32 fullbench32 fuzzer32 zbufftest32
|
||||||
|
|
||||||
zstd : $(ZSTD_FILES) $(ZSTD_FILES_LEGACY) $(ZBUFF_FILES) $(ZDICT_FILES) \
|
zstd : $(ZSTD_FILES) $(ZSTDLEGACY_FILES) $(ZBUFF_FILES) $(ZDICT_FILES) \
|
||||||
zstdcli.c fileio.c bench.c xxhash.c datagen.c dibio.c
|
zstdcli.c fileio.c bench.c datagen.c dibio.c
|
||||||
$(CC) $(FLAGS) -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) $^ -o $@$(EXT)
|
$(CC) $(FLAGS) -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) $^ -o $@$(EXT)
|
||||||
|
|
||||||
zstd32: $(ZSTD_FILES) $(ZSTD_FILES_LEGACY) $(ZBUFF_FILES) $(ZDICT_FILES) \
|
zstd32: $(ZSTD_FILES) $(ZSTDLEGACY_FILES) $(ZBUFF_FILES) $(ZDICT_FILES) \
|
||||||
zstdcli.c fileio.c bench.c xxhash.c datagen.c dibio.c
|
zstdcli.c fileio.c bench.c datagen.c dibio.c
|
||||||
$(CC) -m32 $(FLAGS) -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) $^ -o $@$(EXT)
|
$(CC) -m32 $(FLAGS) -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) $^ -o $@$(EXT)
|
||||||
|
|
||||||
zstd_nolegacy :
|
zstd_nolegacy :
|
||||||
@@ -114,10 +105,12 @@ zstd-pgo : clean zstd
|
|||||||
zstd-frugal: $(ZSTD_FILES) $(ZBUFF_FILES) zstdcli.c fileio.c
|
zstd-frugal: $(ZSTD_FILES) $(ZBUFF_FILES) zstdcli.c fileio.c
|
||||||
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_LEGACY_SUPPORT=0 $^ -o zstd$(EXT)
|
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_LEGACY_SUPPORT=0 $^ -o zstd$(EXT)
|
||||||
|
|
||||||
zstd-compress: $(ZSTDCOMP_FILES) $(ZSTDDIR)/compress/zbuff_compress.c zstdcli.c fileio.c
|
zstd-compress: $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) \
|
||||||
|
$(ZSTDDIR)/compress/zbuff_compress.c zstdcli.c fileio.c
|
||||||
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS -DZSTD_LEGACY_SUPPORT=0 $^ -o $@$(EXT)
|
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS -DZSTD_LEGACY_SUPPORT=0 $^ -o $@$(EXT)
|
||||||
|
|
||||||
zstd-decompress: $(ZSTDDECOMP_FILES) $(ZSTDDIR)/decompress/zbuff_decompress.c zstdcli.c fileio.c
|
zstd-decompress: $(ZSTDCOMMON_FILES) $(ZSTDDECOMP_FILES) \
|
||||||
|
$(ZSTDDIR)/decompress/zbuff_decompress.c zstdcli.c fileio.c
|
||||||
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOCOMPRESS -DZSTD_LEGACY_SUPPORT=0 $^ -o $@$(EXT)
|
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOCOMPRESS -DZSTD_LEGACY_SUPPORT=0 $^ -o $@$(EXT)
|
||||||
|
|
||||||
zstd-small: clean
|
zstd-small: clean
|
||||||
@@ -129,42 +122,43 @@ fullbench : $(ZSTD_FILES) $(ZBUFF_FILES) datagen.c fullbench.c
|
|||||||
fullbench32: $(ZSTD_FILES) $(ZBUFF_FILES) datagen.c fullbench.c
|
fullbench32: $(ZSTD_FILES) $(ZBUFF_FILES) datagen.c fullbench.c
|
||||||
$(CC) -m32 $(FLAGS) $^ -o $@$(EXT)
|
$(CC) -m32 $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
fuzzer : $(ZSTD_FILES) \
|
fuzzer : CPPFLAGS += -I$(ZSTDDIR)/dictBuilder
|
||||||
datagen.c xxhash.c fuzzer.c
|
fuzzer : $(ZSTD_FILES) $(ZDICT_FILES) datagen.c fuzzer.c
|
||||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
fuzzer32: $(ZSTD_FILES) \
|
fuzzer32 : CPPFLAGS += -I$(ZSTDDIR)/dictBuilder
|
||||||
datagen.c xxhash.c fuzzer.c
|
fuzzer32: $(ZSTD_FILES) $(ZDICT_FILES) datagen.c fuzzer.c
|
||||||
$(CC) -m32 $(FLAGS) $^ -o $@$(EXT)
|
$(CC) -m32 $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
zbufftest : $(ZSTD_FILES) $(ZBUFF_FILES) \
|
zbufftest : $(ZSTD_FILES) $(ZBUFF_FILES) datagen.c zbufftest.c
|
||||||
datagen.c xxhash.c zbufftest.c
|
|
||||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
zbufftest32: $(ZSTD_FILES) $(ZBUFF_FILES) \
|
zbufftest32: $(ZSTD_FILES) $(ZBUFF_FILES) datagen.c zbufftest.c
|
||||||
datagen.c xxhash.c zbufftest.c
|
|
||||||
$(CC) -m32 $(FLAGS) $^ -o $@$(EXT)
|
$(CC) -m32 $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
paramgrill : $(ZSTD_FILES) \
|
paramgrill : $(ZSTD_FILES) datagen.c paramgrill.c
|
||||||
datagen.c xxhash.c paramgrill.c
|
|
||||||
$(CC) $(FLAGS) $^ -lm -o $@$(EXT)
|
$(CC) $(FLAGS) $^ -lm -o $@$(EXT)
|
||||||
|
|
||||||
datagen : datagen.c datagencli.c
|
datagen : datagen.c datagencli.c
|
||||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
|
roundTripCrash : $(ZSTD_FILES) roundTripCrash.c
|
||||||
|
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -f core *.o tmp* result* *.gcda dictionary *.zst \
|
@rm -f core *.o tmp* result* *.gcda dictionary *.zst \
|
||||||
zstd$(EXT) zstd32$(EXT) zstd-compress$(EXT) zstd-decompress$(EXT) \
|
zstd$(EXT) zstd32$(EXT) zstd-compress$(EXT) zstd-decompress$(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) \
|
||||||
datagen$(EXT) paramgrill$(EXT)
|
datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT)
|
||||||
@echo Cleaning completed
|
@echo Cleaning 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))
|
||||||
|
HOST_OS = POSIX
|
||||||
install: zstd
|
install: zstd
|
||||||
@echo Installing binaries
|
@echo Installing binaries
|
||||||
@install -d -m 755 $(DESTDIR)$(BINDIR)/ $(DESTDIR)$(MANDIR)/
|
@install -d -m 755 $(DESTDIR)$(BINDIR)/ $(DESTDIR)$(MANDIR)/
|
||||||
@@ -186,15 +180,42 @@ uninstall:
|
|||||||
[ -f $(DESTDIR)$(MANDIR)/zstd.1 ] && rm -f $(DESTDIR)$(MANDIR)/zstd.1
|
[ -f $(DESTDIR)$(MANDIR)/zstd.1 ] && rm -f $(DESTDIR)$(MANDIR)/zstd.1
|
||||||
@echo zstd programs successfully uninstalled
|
@echo zstd programs successfully uninstalled
|
||||||
|
|
||||||
|
valgrindTest: VALGRIND = valgrind --leak-check=full --error-exitcode=1
|
||||||
|
valgrindTest: zstd datagen fuzzer fullbench zbufftest
|
||||||
|
@echo "\n ---- valgrind tests : memory analyzer ----"
|
||||||
|
$(VALGRIND) ./datagen -g50M > $(VOID)
|
||||||
|
$(VALGRIND) ./zstd ; if [ $$? -eq 0 ] ; then echo "zstd without argument should have failed"; false; fi
|
||||||
|
./datagen -g80 | $(VALGRIND) ./zstd - -c > $(VOID)
|
||||||
|
./datagen -g16KB | $(VALGRIND) ./zstd -vf - -o $(VOID)
|
||||||
|
./datagen -g2930KB | $(VALGRIND) ./zstd -5 -vf - -o tmp
|
||||||
|
$(VALGRIND) ./zstd -vdf tmp -o $(VOID)
|
||||||
|
./datagen -g64MB | $(VALGRIND) ./zstd -vf - -o $(VOID)
|
||||||
|
@rm tmp
|
||||||
|
$(VALGRIND) ./fuzzer -T1mn -t1
|
||||||
|
$(VALGRIND) ./fullbench -i1
|
||||||
|
$(VALGRIND) ./zbufftest -T1mn
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
ifneq (,$(filter MSYS%,$(shell uname)))
|
||||||
|
HOST_OS = MSYS
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------
|
||||||
|
#make tests validated only for MSYS, Linux, OSX, kFreeBSD and Hurd targets
|
||||||
|
#------------------------------------------------------------------------
|
||||||
|
ifneq (,$(filter $(HOST_OS),MSYS POSIX))
|
||||||
|
zstd-playTests: datagen
|
||||||
|
ZSTD=$(ZSTD) ./playTests.sh $(ZSTDRTTEST)
|
||||||
|
|
||||||
test: test-zstd test-fullbench test-fuzzer test-zbuff
|
test: test-zstd test-fullbench test-fuzzer test-zbuff
|
||||||
|
|
||||||
test32: test-zstd32 test-fullbench32 test-fuzzer32 test-zbuff32
|
test32: test-zstd32 test-fullbench32 test-fuzzer32 test-zbuff32
|
||||||
|
|
||||||
test-all: test test32 valgrindTest
|
test-all: test test32 valgrindTest
|
||||||
|
|
||||||
zstd-playTests: datagen
|
|
||||||
ZSTD=$(ZSTD) ./playTests.sh $(ZSTDRTTEST)
|
|
||||||
|
|
||||||
test-zstd: ZSTD = ./zstd
|
test-zstd: ZSTD = ./zstd
|
||||||
test-zstd: zstd zstd-playTests
|
test-zstd: zstd zstd-playTests
|
||||||
|
|
||||||
@@ -223,20 +244,4 @@ test-zbuff: zbufftest
|
|||||||
|
|
||||||
test-zbuff32: zbufftest32
|
test-zbuff32: zbufftest32
|
||||||
./zbufftest32 $(ZBUFFTEST)
|
./zbufftest32 $(ZBUFFTEST)
|
||||||
|
|
||||||
valgrindTest: VALGRIND = valgrind --leak-check=full --error-exitcode=1
|
|
||||||
valgrindTest: zstd datagen fuzzer fullbench zbufftest
|
|
||||||
@echo "\n ---- valgrind tests : memory analyzer ----"
|
|
||||||
$(VALGRIND) ./datagen -g50M > $(VOID)
|
|
||||||
$(VALGRIND) ./zstd ; if [ $$? -eq 0 ] ; then echo "zstd without argument should have failed"; false; fi
|
|
||||||
./datagen -g80 | $(VALGRIND) ./zstd - -c > $(VOID)
|
|
||||||
./datagen -g16KB | $(VALGRIND) ./zstd -vf - -o $(VOID)
|
|
||||||
./datagen -g2930KB | $(VALGRIND) ./zstd -5 -vf - -o tmp
|
|
||||||
$(VALGRIND) ./zstd -vdf tmp -o $(VOID)
|
|
||||||
./datagen -g64MB | $(VALGRIND) ./zstd -vf - -o $(VOID)
|
|
||||||
@rm tmp
|
|
||||||
$(VALGRIND) ./fuzzer -T1mn -t1
|
|
||||||
$(VALGRIND) ./fullbench -i1
|
|
||||||
$(VALGRIND) ./zbufftest -T1mn
|
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|||||||
+30
-53
@@ -26,13 +26,14 @@
|
|||||||
/* *************************************
|
/* *************************************
|
||||||
* Includes
|
* Includes
|
||||||
***************************************/
|
***************************************/
|
||||||
#include "util.h" /* Compiler options, UTIL_GetFileSize, UTIL_HAS_CREATEFILELIST, UTIL_sleep */
|
#include "util.h" /* Compiler options, UTIL_GetFileSize, UTIL_sleep */
|
||||||
#include <stdlib.h> /* malloc, free */
|
#include <stdlib.h> /* malloc, free */
|
||||||
#include <string.h> /* memset */
|
#include <string.h> /* memset */
|
||||||
#include <stdio.h> /* fprintf, fopen, ftello64 */
|
#include <stdio.h> /* fprintf, fopen, ftello64 */
|
||||||
|
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "zstd_static.h"
|
#define ZSTD_STATIC_LINKING_ONLY
|
||||||
|
#include "zstd.h"
|
||||||
#include "datagen.h" /* RDG_genBuffer */
|
#include "datagen.h" /* RDG_genBuffer */
|
||||||
#include "xxhash.h"
|
#include "xxhash.h"
|
||||||
|
|
||||||
@@ -188,7 +189,6 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
|||||||
/* Bench */
|
/* Bench */
|
||||||
{ U64 fastestC = (U64)(-1LL), fastestD = (U64)(-1LL);
|
{ U64 fastestC = (U64)(-1LL), fastestD = (U64)(-1LL);
|
||||||
U64 const crcOrig = XXH64(srcBuffer, srcSize, 0);
|
U64 const crcOrig = XXH64(srcBuffer, srcSize, 0);
|
||||||
U64 crcCheck = 0;
|
|
||||||
UTIL_time_t coolTime;
|
UTIL_time_t coolTime;
|
||||||
U32 testNb;
|
U32 testNb;
|
||||||
size_t cSize = 0;
|
size_t cSize = 0;
|
||||||
@@ -216,24 +216,21 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
|||||||
UTIL_getTime(&clockStart);
|
UTIL_getTime(&clockStart);
|
||||||
|
|
||||||
{ U32 nbLoops = 0;
|
{ U32 nbLoops = 0;
|
||||||
|
ZSTD_CDict* cdict = ZSTD_createCDict(dictBuffer, dictBufferSize, cLevel);
|
||||||
|
if (cdict==NULL) EXM_THROW(1, "ZSTD_createCDict() allocation failure");
|
||||||
do {
|
do {
|
||||||
U32 blockNb;
|
U32 blockNb;
|
||||||
{ ZSTD_parameters params;
|
|
||||||
params.cParams = ZSTD_getCParams(cLevel, blockSize, dictBufferSize);
|
|
||||||
params.fParams.contentSizeFlag = 1;
|
|
||||||
ZSTD_adjustCParams(¶ms.cParams, blockSize, dictBufferSize);
|
|
||||||
{ size_t const initResult = ZSTD_compressBegin_advanced(refCtx, dictBuffer, dictBufferSize, params, blockSize);
|
|
||||||
if (ZSTD_isError(initResult)) break;
|
|
||||||
} }
|
|
||||||
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
|
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
|
||||||
size_t const rSize = ZSTD_compress_usingPreparedCCtx(ctx, refCtx,
|
size_t const rSize = ZSTD_compress_usingCDict(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,
|
||||||
|
cdict);
|
||||||
if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_compress_usingPreparedCCtx() failed : %s", ZSTD_getErrorName(rSize));
|
if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_compress_usingPreparedCCtx() failed : %s", ZSTD_getErrorName(rSize));
|
||||||
blockTable[blockNb].cSize = rSize;
|
blockTable[blockNb].cSize = rSize;
|
||||||
}
|
}
|
||||||
nbLoops++;
|
nbLoops++;
|
||||||
} while (UTIL_clockSpanMicro(clockStart, ticksPerSecond) < clockLoop);
|
} while (UTIL_clockSpanMicro(clockStart, ticksPerSecond) < clockLoop);
|
||||||
|
ZSTD_freeCDict(cdict);
|
||||||
{ U64 const clockSpan = UTIL_clockSpanMicro(clockStart, ticksPerSecond);
|
{ U64 const clockSpan = UTIL_clockSpanMicro(clockStart, ticksPerSecond);
|
||||||
if (clockSpan < fastestC*nbLoops) fastestC = clockSpan / nbLoops;
|
if (clockSpan < fastestC*nbLoops) fastestC = clockSpan / nbLoops;
|
||||||
} }
|
} }
|
||||||
@@ -255,13 +252,15 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
|||||||
UTIL_getTime(&clockStart);
|
UTIL_getTime(&clockStart);
|
||||||
|
|
||||||
{ U32 nbLoops = 0;
|
{ U32 nbLoops = 0;
|
||||||
|
ZSTD_DDict* ddict = ZSTD_createDDict(dictBuffer, dictBufferSize);
|
||||||
|
if (!ddict) EXM_THROW(2, "ZSTD_createDDict() allocation failure");
|
||||||
do {
|
do {
|
||||||
U32 blockNb;
|
U32 blockNb;
|
||||||
ZSTD_decompressBegin_usingDict(refDCtx, dictBuffer, dictBufferSize);
|
|
||||||
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
|
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
|
||||||
size_t const regenSize = ZSTD_decompress_usingPreparedDCtx(dctx, refDCtx,
|
size_t const regenSize = ZSTD_decompress_usingDDict(dctx,
|
||||||
blockTable[blockNb].resPtr, blockTable[blockNb].srcSize,
|
blockTable[blockNb].resPtr, blockTable[blockNb].srcSize,
|
||||||
blockTable[blockNb].cPtr, blockTable[blockNb].cSize);
|
blockTable[blockNb].cPtr, blockTable[blockNb].cSize,
|
||||||
|
ddict);
|
||||||
if (ZSTD_isError(regenSize)) {
|
if (ZSTD_isError(regenSize)) {
|
||||||
DISPLAY("ZSTD_decompress_usingPreparedDCtx() failed on block %u : %s \n",
|
DISPLAY("ZSTD_decompress_usingPreparedDCtx() failed on block %u : %s \n",
|
||||||
blockNb, ZSTD_getErrorName(regenSize));
|
blockNb, ZSTD_getErrorName(regenSize));
|
||||||
@@ -272,6 +271,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
|||||||
}
|
}
|
||||||
nbLoops++;
|
nbLoops++;
|
||||||
} while (UTIL_clockSpanMicro(clockStart, ticksPerSecond) < clockLoop);
|
} while (UTIL_clockSpanMicro(clockStart, ticksPerSecond) < clockLoop);
|
||||||
|
ZSTD_freeDDict(ddict);
|
||||||
{ U64 const clockSpan = UTIL_clockSpanMicro(clockStart, ticksPerSecond);
|
{ U64 const clockSpan = UTIL_clockSpanMicro(clockStart, ticksPerSecond);
|
||||||
if (clockSpan < fastestD*nbLoops) fastestD = clockSpan / nbLoops;
|
if (clockSpan < fastestD*nbLoops) fastestD = clockSpan / nbLoops;
|
||||||
} }
|
} }
|
||||||
@@ -282,7 +282,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
|||||||
(double)srcSize / fastestD );
|
(double)srcSize / fastestD );
|
||||||
|
|
||||||
/* CRC Checking */
|
/* CRC Checking */
|
||||||
{ crcCheck = XXH64(resultBuffer, srcSize, 0);
|
{ U64 const crcCheck = XXH64(resultBuffer, srcSize, 0);
|
||||||
if (crcOrig!=crcCheck) {
|
if (crcOrig!=crcCheck) {
|
||||||
size_t u;
|
size_t u;
|
||||||
DISPLAY("!!! WARNING !!! %14s : Invalid Checksum : %x != %x \n", displayName, (unsigned)crcOrig, (unsigned)crcCheck);
|
DISPLAY("!!! WARNING !!! %14s : Invalid Checksum : %x != %x \n", displayName, (unsigned)crcOrig, (unsigned)crcCheck);
|
||||||
@@ -308,12 +308,10 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
|||||||
#endif
|
#endif
|
||||||
} /* for (testNb = 1; testNb <= (g_nbIterations + !g_nbIterations); testNb++) */
|
} /* for (testNb = 1; testNb <= (g_nbIterations + !g_nbIterations); testNb++) */
|
||||||
|
|
||||||
if (crcOrig == crcCheck) {
|
result->ratio = ratio;
|
||||||
result->ratio = ratio;
|
result->cSize = cSize;
|
||||||
result->cSize = cSize;
|
result->cSpeed = (double)srcSize / fastestC;
|
||||||
result->cSpeed = (double)srcSize / fastestC;
|
result->dSpeed = (double)srcSize / fastestD;
|
||||||
result->dSpeed = (double)srcSize / fastestD;
|
|
||||||
}
|
|
||||||
DISPLAYLEVEL(2, "%2i#\n", cLevel);
|
DISPLAYLEVEL(2, "%2i#\n", cLevel);
|
||||||
} /* Bench */
|
} /* Bench */
|
||||||
|
|
||||||
@@ -402,9 +400,9 @@ static void BMK_loadFiles(void* buffer, size_t bufferSize,
|
|||||||
const char** fileNamesTable, unsigned nbFiles)
|
const char** fileNamesTable, unsigned nbFiles)
|
||||||
{
|
{
|
||||||
size_t pos = 0, totalSize = 0;
|
size_t pos = 0, totalSize = 0;
|
||||||
FILE* f;
|
|
||||||
unsigned n;
|
unsigned n;
|
||||||
for (n=0; n<nbFiles; n++) {
|
for (n=0; n<nbFiles; n++) {
|
||||||
|
FILE* f;
|
||||||
U64 fileSize = UTIL_getFileSize(fileNamesTable[n]);
|
U64 fileSize = UTIL_getFileSize(fileNamesTable[n]);
|
||||||
if (UTIL_isDirectory(fileNamesTable[n])) {
|
if (UTIL_isDirectory(fileNamesTable[n])) {
|
||||||
DISPLAYLEVEL(2, "Ignoring %s directory... \n", fileNamesTable[n]);
|
DISPLAYLEVEL(2, "Ignoring %s directory... \n", fileNamesTable[n]);
|
||||||
@@ -434,9 +432,8 @@ static void BMK_benchFileTable(const char** fileNamesTable, unsigned nbFiles,
|
|||||||
void* dictBuffer = NULL;
|
void* dictBuffer = NULL;
|
||||||
size_t dictBufferSize = 0;
|
size_t dictBufferSize = 0;
|
||||||
size_t* fileSizes = (size_t*)malloc(nbFiles * sizeof(size_t));
|
size_t* fileSizes = (size_t*)malloc(nbFiles * sizeof(size_t));
|
||||||
U64 totalSizeToLoad = UTIL_getTotalFileSize(fileNamesTable, nbFiles);
|
U64 const totalSizeToLoad = UTIL_getTotalFileSize(fileNamesTable, nbFiles);
|
||||||
char mfName[20] = {0};
|
char mfName[20] = {0};
|
||||||
const char* displayName = NULL;
|
|
||||||
|
|
||||||
if (!fileSizes) EXM_THROW(12, "not enough memory for fileSizes");
|
if (!fileSizes) EXM_THROW(12, "not enough memory for fileSizes");
|
||||||
|
|
||||||
@@ -463,13 +460,12 @@ static void BMK_benchFileTable(const char** fileNamesTable, unsigned nbFiles,
|
|||||||
|
|
||||||
/* Bench */
|
/* Bench */
|
||||||
snprintf (mfName, sizeof(mfName), " %u files", nbFiles);
|
snprintf (mfName, sizeof(mfName), " %u files", nbFiles);
|
||||||
if (nbFiles > 1) displayName = mfName;
|
{ const char* displayName = (nbFiles > 1) ? mfName : fileNamesTable[0];
|
||||||
else displayName = fileNamesTable[0];
|
BMK_benchCLevel(srcBuffer, benchedSize,
|
||||||
|
displayName, cLevel, cLevelLast,
|
||||||
BMK_benchCLevel(srcBuffer, benchedSize,
|
fileSizes, nbFiles,
|
||||||
displayName, cLevel, cLevelLast,
|
dictBuffer, dictBufferSize);
|
||||||
fileSizes, nbFiles,
|
}
|
||||||
dictBuffer, dictBufferSize);
|
|
||||||
|
|
||||||
/* clean up */
|
/* clean up */
|
||||||
free(srcBuffer);
|
free(srcBuffer);
|
||||||
@@ -482,7 +478,7 @@ static void BMK_syntheticTest(int cLevel, int cLevelLast, double compressibility
|
|||||||
{
|
{
|
||||||
char name[20] = {0};
|
char name[20] = {0};
|
||||||
size_t benchedSize = 10000000;
|
size_t benchedSize = 10000000;
|
||||||
void* srcBuffer = malloc(benchedSize);
|
void* const srcBuffer = malloc(benchedSize);
|
||||||
|
|
||||||
/* Memory allocation */
|
/* Memory allocation */
|
||||||
if (!srcBuffer) EXM_THROW(21, "not enough memory");
|
if (!srcBuffer) EXM_THROW(21, "not enough memory");
|
||||||
@@ -500,32 +496,13 @@ static void BMK_syntheticTest(int cLevel, int cLevelLast, double compressibility
|
|||||||
|
|
||||||
|
|
||||||
int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles,
|
int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles,
|
||||||
const char* dictFileName, int cLevel, int cLevelLast, int recursive)
|
const char* dictFileName, int cLevel, int cLevelLast)
|
||||||
{
|
{
|
||||||
double const compressibility = (double)g_compressibilityDefault / 100;
|
double const compressibility = (double)g_compressibilityDefault / 100;
|
||||||
|
|
||||||
if (nbFiles == 0)
|
if (nbFiles == 0)
|
||||||
BMK_syntheticTest(cLevel, cLevelLast, compressibility);
|
BMK_syntheticTest(cLevel, cLevelLast, compressibility);
|
||||||
else
|
else
|
||||||
{
|
|
||||||
#ifdef UTIL_HAS_CREATEFILELIST
|
|
||||||
if (recursive) {
|
|
||||||
char* buf;
|
|
||||||
const char** filenameTable;
|
|
||||||
unsigned i;
|
|
||||||
filenameTable = UTIL_createFileList(fileNamesTable, nbFiles, &buf, &nbFiles);
|
|
||||||
if (filenameTable) {
|
|
||||||
for (i=0; i<nbFiles; i++) DISPLAYLEVEL(3, "%d %s\n", i, filenameTable[i]);
|
|
||||||
BMK_benchFileTable(filenameTable, nbFiles, dictFileName, cLevel, cLevelLast);
|
|
||||||
UTIL_freeFileList(filenameTable, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else BMK_benchFileTable(fileNamesTable, nbFiles, dictFileName, cLevel, cLevelLast);
|
|
||||||
#else
|
|
||||||
(void)recursive;
|
|
||||||
BMK_benchFileTable(fileNamesTable, nbFiles, dictFileName, cLevel, cLevelLast);
|
BMK_benchFileTable(fileNamesTable, nbFiles, dictFileName, cLevel, cLevelLast);
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -21,12 +21,13 @@
|
|||||||
You can contact the author at :
|
You can contact the author at :
|
||||||
- ZSTD homepage : http://www.zstd.net/
|
- ZSTD homepage : http://www.zstd.net/
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#ifndef BENCH_H_121279284357
|
||||||
|
#define BENCH_H_121279284357
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
/* Main function */
|
|
||||||
int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles,
|
int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles,
|
||||||
const char* dictFileName, int cLevel, int cLevelLast, int recursive);
|
const char* dictFileName, int cLevel, int cLevelLast);
|
||||||
|
|
||||||
/* Set Parameters */
|
/* Set Parameters */
|
||||||
void BMK_SetNbIterations(unsigned nbLoops);
|
void BMK_SetNbIterations(unsigned nbLoops);
|
||||||
@@ -34,3 +35,4 @@ void BMK_SetBlockSize(size_t blockSize);
|
|||||||
void BMK_setAdditionalParam(int additionalParam);
|
void BMK_setAdditionalParam(int additionalParam);
|
||||||
void BMK_setNotificationLevel(unsigned level);
|
void BMK_setNotificationLevel(unsigned level);
|
||||||
|
|
||||||
|
#endif /* BENCH_H_121279284357 */
|
||||||
|
|||||||
+70
-57
@@ -27,9 +27,9 @@
|
|||||||
* Includes
|
* Includes
|
||||||
**************************************/
|
**************************************/
|
||||||
#include <stdlib.h> /* malloc */
|
#include <stdlib.h> /* malloc */
|
||||||
#include <stdio.h> /* FILE, fwrite */
|
#include <stdio.h> /* FILE, fwrite, fprintf */
|
||||||
#include <string.h> /* memcpy */
|
#include <string.h> /* memcpy */
|
||||||
#include "mem.h"
|
#include "mem.h" /* U32 */
|
||||||
|
|
||||||
|
|
||||||
/*-************************************
|
/*-************************************
|
||||||
@@ -48,22 +48,25 @@
|
|||||||
* Macros
|
* Macros
|
||||||
**************************************/
|
**************************************/
|
||||||
#define KB *(1 <<10)
|
#define KB *(1 <<10)
|
||||||
|
#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
|
||||||
|
|
||||||
|
#define RDG_DEBUG 0
|
||||||
|
#define TRACE(...) if (RDG_DEBUG) fprintf(stderr, __VA_ARGS__ )
|
||||||
|
|
||||||
|
|
||||||
/*-************************************
|
/*-************************************
|
||||||
* Local types
|
* Local constants
|
||||||
**************************************/
|
**************************************/
|
||||||
#define LTLOG 13
|
#define LTLOG 13
|
||||||
#define LTSIZE (1<<LTLOG)
|
#define LTSIZE (1<<LTLOG)
|
||||||
#define LTMASK (LTSIZE-1)
|
#define LTMASK (LTSIZE-1)
|
||||||
typedef BYTE litDistribTable[LTSIZE];
|
|
||||||
|
|
||||||
|
|
||||||
/*-*******************************************************
|
/*-*******************************************************
|
||||||
* Local Functions
|
* Local Functions
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
#define RDG_rotl32(x,r) ((x << r) | (x >> (32 - r)))
|
#define RDG_rotl32(x,r) ((x << r) | (x >> (32 - r)))
|
||||||
static unsigned int RDG_rand(U32* src)
|
static U32 RDG_rand(U32* src)
|
||||||
{
|
{
|
||||||
static const U32 prime1 = 2654435761U;
|
static const U32 prime1 = 2654435761U;
|
||||||
static const U32 prime2 = 2246822519U;
|
static const U32 prime2 = 2246822519U;
|
||||||
@@ -72,126 +75,136 @@ static unsigned int RDG_rand(U32* src)
|
|||||||
rand32 ^= prime2;
|
rand32 ^= prime2;
|
||||||
rand32 = RDG_rotl32(rand32, 13);
|
rand32 = RDG_rotl32(rand32, 13);
|
||||||
*src = rand32;
|
*src = rand32;
|
||||||
return rand32;
|
return rand32 >> 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void RDG_fillLiteralDistrib(litDistribTable lt, double ld)
|
static void RDG_fillLiteralDistrib(BYTE* ldt, double ld)
|
||||||
{
|
{
|
||||||
U32 i = 0;
|
BYTE const firstChar = (ld<=0.0) ? 0 : '(';
|
||||||
|
BYTE const lastChar = (ld<=0.0) ? 255 : '}';
|
||||||
BYTE character = (ld<=0.0) ? 0 : '0';
|
BYTE character = (ld<=0.0) ? 0 : '0';
|
||||||
BYTE const firstChar = (ld<=0.0) ? 0 : '(';
|
U32 u;
|
||||||
BYTE const lastChar = (ld<=0.0) ?255: '}';
|
|
||||||
|
|
||||||
while (i<LTSIZE) {
|
if (ld<=0.0) ld = 0.0;
|
||||||
U32 weight = (U32)((double)(LTSIZE - i) * ld) + 1;
|
//TRACE(" percent:%5.2f%% \n", ld*100.);
|
||||||
U32 end;
|
//TRACE(" start:(%c)[%02X] ", character, character);
|
||||||
if (weight + i > LTSIZE) weight = LTSIZE-i;
|
for (u=0; u<LTSIZE; ) {
|
||||||
end = i + weight;
|
U32 const weight = (U32)((double)(LTSIZE - u) * ld) + 1;
|
||||||
while (i < end) lt[i++] = character;
|
U32 const end = MIN ( u + weight , LTSIZE);
|
||||||
|
while (u < end) ldt[u++] = character; // TRACE(" %u(%c)[%02X] ", u, character, character);
|
||||||
character++;
|
character++;
|
||||||
if (character > lastChar) character = firstChar;
|
if (character > lastChar) character = firstChar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static BYTE RDG_genChar(U32* seed, const litDistribTable lt)
|
static BYTE RDG_genChar(U32* seed, const BYTE* ldt)
|
||||||
{
|
{
|
||||||
U32 const id = RDG_rand(seed) & LTMASK;
|
U32 const id = RDG_rand(seed) & LTMASK;
|
||||||
return (lt[id]);
|
//TRACE(" %u : \n", id);
|
||||||
|
//TRACE(" %4u [%4u] ; val : %4u \n", id, id&255, ldt[id]);
|
||||||
|
return (ldt[id]); /* memory-sanitizer fails here, stating "uninitialized value" when table initialized with 0.0. Checked : table is fully initialized */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define RDG_RAND15BITS ((RDG_rand(seed) >> 3) & 0x7FFF)
|
static U32 RDG_rand15Bits (unsigned* seedPtr)
|
||||||
#define RDG_RANDLENGTH ( ((RDG_rand(seed) >> 7) & 7) ? (RDG_rand(seed) & 15) : (RDG_rand(seed) & 511) + 15)
|
|
||||||
void RDG_genBlock(void* buffer, size_t buffSize, size_t prefixSize, double matchProba, litDistribTable lt, unsigned* seedPtr)
|
|
||||||
{
|
{
|
||||||
BYTE* buffPtr = (BYTE*)buffer;
|
return RDG_rand(seedPtr) & 0x7FFF;
|
||||||
const U32 matchProba32 = (U32)(32768 * matchProba);
|
}
|
||||||
|
|
||||||
|
static U32 RDG_randLength(unsigned* seedPtr)
|
||||||
|
{
|
||||||
|
if (RDG_rand(seedPtr) & 7)
|
||||||
|
return (RDG_rand(seedPtr) & 0xF);
|
||||||
|
return (RDG_rand(seedPtr) & 0x1FF) + 0xF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RDG_genBlock(void* buffer, size_t buffSize, size_t prefixSize, double matchProba, const BYTE* ldt, unsigned* seedPtr)
|
||||||
|
{
|
||||||
|
BYTE* const buffPtr = (BYTE*)buffer;
|
||||||
|
U32 const matchProba32 = (U32)(32768 * matchProba);
|
||||||
size_t pos = prefixSize;
|
size_t pos = prefixSize;
|
||||||
U32* seed = seedPtr;
|
|
||||||
U32 prevOffset = 1;
|
U32 prevOffset = 1;
|
||||||
|
|
||||||
/* special case : sparse content */
|
/* special case : sparse content */
|
||||||
while (matchProba >= 1.0) {
|
while (matchProba >= 1.0) {
|
||||||
size_t size0 = RDG_rand(seed) & 3;
|
size_t size0 = RDG_rand(seedPtr) & 3;
|
||||||
size0 = (size_t)1 << (16 + size0 * 2);
|
size0 = (size_t)1 << (16 + size0 * 2);
|
||||||
size0 += RDG_rand(seed) & (size0-1); /* because size0 is power of 2*/
|
size0 += RDG_rand(seedPtr) & (size0-1); /* because size0 is power of 2*/
|
||||||
if (buffSize < pos + size0) {
|
if (buffSize < pos + size0) {
|
||||||
memset(buffPtr+pos, 0, buffSize-pos);
|
memset(buffPtr+pos, 0, buffSize-pos);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memset(buffPtr+pos, 0, size0);
|
memset(buffPtr+pos, 0, size0);
|
||||||
pos += size0;
|
pos += size0;
|
||||||
buffPtr[pos-1] = RDG_genChar(seed, lt);
|
buffPtr[pos-1] = RDG_genChar(seedPtr, ldt);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
if (pos==0) buffPtr[0] = RDG_genChar(seed, lt), pos=1;
|
if (pos==0) buffPtr[0] = RDG_genChar(seedPtr, ldt), pos=1;
|
||||||
|
|
||||||
/* Generate compressible data */
|
/* Generate compressible data */
|
||||||
while (pos < buffSize) {
|
while (pos < buffSize) {
|
||||||
/* Select : Literal (char) or Match (within 32K) */
|
/* Select : Literal (char) or Match (within 32K) */
|
||||||
if (RDG_RAND15BITS < matchProba32) {
|
if (RDG_rand15Bits(seedPtr) < matchProba32) {
|
||||||
/* Copy (within 32K) */
|
/* Copy (within 32K) */
|
||||||
size_t match;
|
U32 const length = RDG_randLength(seedPtr) + 4;
|
||||||
size_t d;
|
U32 const d = (U32) MIN(pos + length , buffSize);
|
||||||
size_t const length = RDG_RANDLENGTH + 4;
|
U32 const repeatOffset = (RDG_rand(seedPtr) & 15) == 2;
|
||||||
U32 offset = RDG_RAND15BITS + 1;
|
U32 const randOffset = RDG_rand15Bits(seedPtr) + 1;
|
||||||
U32 repeatOffset = (RDG_rand(seed) & 15) == 2;
|
U32 const offset = repeatOffset ? prevOffset : (U32) MIN(randOffset , pos);
|
||||||
if (repeatOffset) offset = prevOffset;
|
size_t match = pos - offset;
|
||||||
if (offset > pos) offset = (U32)pos;
|
//TRACE("pos : %u; offset: %u ; length : %u \n", (U32)pos, offset, length);
|
||||||
prevOffset = offset;
|
|
||||||
match = pos - offset;
|
|
||||||
d = pos + length;
|
|
||||||
if (d > buffSize) d = buffSize;
|
|
||||||
while (pos < d) buffPtr[pos++] = buffPtr[match++]; /* correctly manages overlaps */
|
while (pos < d) buffPtr[pos++] = buffPtr[match++]; /* correctly manages overlaps */
|
||||||
|
prevOffset = offset;
|
||||||
} else {
|
} else {
|
||||||
/* Literal (noise) */
|
/* Literal (noise) */
|
||||||
size_t const length = RDG_RANDLENGTH;
|
U32 const length = RDG_randLength(seedPtr);
|
||||||
size_t d = pos + length;
|
U32 const d = (U32) MIN(pos + length, buffSize);
|
||||||
if (d > buffSize) d = buffSize;
|
while (pos < d) buffPtr[pos++] = RDG_genChar(seedPtr, ldt);
|
||||||
while (pos < d) buffPtr[pos++] = RDG_genChar(seed, lt);
|
|
||||||
} }
|
} }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
litDistribTable lt;
|
BYTE ldt[LTSIZE];
|
||||||
if (litProba==0.0) litProba = matchProba / 4.5;
|
memset(ldt, '0', sizeof(ldt));
|
||||||
RDG_fillLiteralDistrib(lt, litProba);
|
if (litProba<=0.0) litProba = matchProba / 4.5;
|
||||||
RDG_genBlock(buffer, size, 0, matchProba, lt, &seed);
|
//TRACE(" percent:%5.2f%% \n", litProba*100.);
|
||||||
|
RDG_fillLiteralDistrib(ldt, litProba);
|
||||||
|
RDG_genBlock(buffer, size, 0, matchProba, ldt, &seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define RDG_DICTSIZE (32 KB)
|
|
||||||
#define RDG_BLOCKSIZE (128 KB)
|
|
||||||
#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
BYTE* buff = (BYTE*)malloc(RDG_DICTSIZE + RDG_BLOCKSIZE);
|
size_t const stdBlockSize = 128 KB;
|
||||||
|
size_t const stdDictSize = 32 KB;
|
||||||
|
BYTE* const buff = (BYTE*)malloc(stdDictSize + stdBlockSize);
|
||||||
U64 total = 0;
|
U64 total = 0;
|
||||||
litDistribTable ldt;
|
BYTE ldt[LTSIZE];
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
if (buff==NULL) { fprintf(stdout, "not enough memory\n"); exit(1); }
|
if (buff==NULL) { fprintf(stdout, "not enough memory\n"); exit(1); }
|
||||||
if (litProba<=0.0) litProba = matchProba / 4.5;
|
if (litProba<=0.0) litProba = matchProba / 4.5;
|
||||||
|
memset(ldt, '0', sizeof(ldt));
|
||||||
RDG_fillLiteralDistrib(ldt, litProba);
|
RDG_fillLiteralDistrib(ldt, litProba);
|
||||||
SET_BINARY_MODE(stdout);
|
SET_BINARY_MODE(stdout);
|
||||||
|
|
||||||
/* Generate initial dict */
|
/* Generate initial dict */
|
||||||
RDG_genBlock(buff, RDG_DICTSIZE, 0, matchProba, ldt, &seed);
|
RDG_genBlock(buff, stdDictSize, 0, matchProba, ldt, &seed);
|
||||||
|
|
||||||
/* Generate compressible data */
|
/* Generate compressible data */
|
||||||
while (total < size) {
|
while (total < size) {
|
||||||
size_t const genBlockSize = (size_t) (MIN (RDG_BLOCKSIZE, size-total));
|
size_t const genBlockSize = (size_t) (MIN (stdBlockSize, size-total));
|
||||||
RDG_genBlock(buff, RDG_DICTSIZE+RDG_BLOCKSIZE, RDG_DICTSIZE, matchProba, ldt, &seed);
|
RDG_genBlock(buff, stdDictSize+stdBlockSize, stdDictSize, matchProba, ldt, &seed);
|
||||||
total += genBlockSize;
|
total += genBlockSize;
|
||||||
{ size_t const unused = fwrite(buff, 1, genBlockSize, stdout); (void)unused; }
|
{ size_t const unused = fwrite(buff, 1, genBlockSize, stdout); (void)unused; }
|
||||||
/* update dict */
|
/* update dict */
|
||||||
memcpy(buff, buff + RDG_BLOCKSIZE, RDG_DICTSIZE);
|
memcpy(buff, buff + stdBlockSize, stdDictSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
|
|||||||
@@ -27,8 +27,8 @@
|
|||||||
/*-************************************
|
/*-************************************
|
||||||
* Includes
|
* Includes
|
||||||
**************************************/
|
**************************************/
|
||||||
|
#include "util.h" /* Compiler options */
|
||||||
#include <stdio.h> /* fprintf, stderr */
|
#include <stdio.h> /* fprintf, stderr */
|
||||||
#include "mem.h"
|
|
||||||
#include "datagen.h" /* RDG_generate */
|
#include "datagen.h" /* RDG_generate */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+39
-39
@@ -101,27 +101,30 @@ const char* DiB_getErrorName(size_t errorCode) { return ERR_getErrorName(errorCo
|
|||||||
/* ********************************************************
|
/* ********************************************************
|
||||||
* File related operations
|
* File related operations
|
||||||
**********************************************************/
|
**********************************************************/
|
||||||
static void DiB_loadFiles(void* buffer, size_t bufferSize,
|
/** DiB_loadFiles() :
|
||||||
size_t* fileSizes,
|
* @return : nb of files effectively loaded into `buffer` */
|
||||||
const char** fileNamesTable, unsigned nbFiles)
|
static unsigned DiB_loadFiles(void* buffer, size_t bufferSize,
|
||||||
|
size_t* fileSizes,
|
||||||
|
const char** fileNamesTable, unsigned nbFiles)
|
||||||
{
|
{
|
||||||
char* buff = (char*)buffer;
|
char* const buff = (char*)buffer;
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
unsigned n;
|
unsigned n;
|
||||||
|
|
||||||
for (n=0; n<nbFiles; n++) {
|
for (n=0; n<nbFiles; n++) {
|
||||||
size_t readSize;
|
unsigned long long const fs64 = UTIL_getFileSize(fileNamesTable[n]);
|
||||||
unsigned long long fileSize = UTIL_getFileSize(fileNamesTable[n]);
|
size_t const fileSize = (size_t)(fs64 > bufferSize-pos ? 0 : fs64);
|
||||||
FILE* f = fopen(fileNamesTable[n], "rb");
|
FILE* const f = fopen(fileNamesTable[n], "rb");
|
||||||
if (f==NULL) EXM_THROW(10, "impossible to open file %s", fileNamesTable[n]);
|
if (f==NULL) EXM_THROW(10, "impossible to open file %s", fileNamesTable[n]);
|
||||||
DISPLAYUPDATE(2, "Loading %s... \r", fileNamesTable[n]);
|
DISPLAYUPDATE(2, "Loading %s... \r", fileNamesTable[n]);
|
||||||
if (fileSize > bufferSize-pos) fileSize = 0; /* stop there, not enough memory to load all files */
|
{ size_t const readSize = fread(buff+pos, 1, fileSize, f);
|
||||||
readSize = fread(buff+pos, 1, (size_t)fileSize, f);
|
if (readSize != fileSize) EXM_THROW(11, "could not read %s", fileNamesTable[n]);
|
||||||
if (readSize != (size_t)fileSize) EXM_THROW(11, "could not read %s", fileNamesTable[n]);
|
pos += readSize; }
|
||||||
pos += readSize;
|
fileSizes[n] = fileSize;
|
||||||
fileSizes[n] = (size_t)fileSize;
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
if (fileSize == 0) break; /* stop there, not enough memory to load all files */
|
||||||
}
|
}
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -130,7 +133,7 @@ static void DiB_loadFiles(void* buffer, size_t bufferSize,
|
|||||||
**********************************************************/
|
**********************************************************/
|
||||||
static size_t DiB_findMaxMem(unsigned long long requiredMem)
|
static size_t DiB_findMaxMem(unsigned long long requiredMem)
|
||||||
{
|
{
|
||||||
size_t step = 8 MB;
|
size_t const step = 8 MB;
|
||||||
void* testmem = NULL;
|
void* testmem = NULL;
|
||||||
|
|
||||||
requiredMem = (((requiredMem >> 23) + 1) << 23);
|
requiredMem = (((requiredMem >> 23) + 1) << 23);
|
||||||
@@ -162,7 +165,7 @@ static void DiB_fillNoise(void* buffer, size_t length)
|
|||||||
static void DiB_saveDict(const char* dictFileName,
|
static void DiB_saveDict(const char* dictFileName,
|
||||||
const void* buff, size_t buffSize)
|
const void* buff, size_t buffSize)
|
||||||
{
|
{
|
||||||
FILE* f = fopen(dictFileName, "wb");
|
FILE* const f = fopen(dictFileName, "wb");
|
||||||
if (f==NULL) EXM_THROW(3, "cannot open %s ", dictFileName);
|
if (f==NULL) EXM_THROW(3, "cannot open %s ", dictFileName);
|
||||||
|
|
||||||
{ size_t const n = fwrite(buff, 1, buffSize, f);
|
{ size_t const n = fwrite(buff, 1, buffSize, f);
|
||||||
@@ -185,47 +188,44 @@ size_t ZDICT_trainFromBuffer_unsafe(void* dictBuffer, size_t dictBufferCapacity,
|
|||||||
ZDICT_params_t parameters);
|
ZDICT_params_t parameters);
|
||||||
|
|
||||||
|
|
||||||
|
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||||
int DiB_trainFromFiles(const char* dictFileName, unsigned maxDictSize,
|
int DiB_trainFromFiles(const char* dictFileName, unsigned maxDictSize,
|
||||||
const char** fileNamesTable, unsigned nbFiles,
|
const char** fileNamesTable, unsigned nbFiles,
|
||||||
ZDICT_params_t params)
|
ZDICT_params_t params)
|
||||||
{
|
{
|
||||||
void* srcBuffer;
|
void* const dictBuffer = malloc(maxDictSize);
|
||||||
size_t benchedSize;
|
size_t* const fileSizes = (size_t*)malloc(nbFiles * sizeof(size_t));
|
||||||
size_t* fileSizes = (size_t*)malloc(nbFiles * sizeof(size_t));
|
unsigned long long const totalSizeToLoad = UTIL_getTotalFileSize(fileNamesTable, nbFiles);
|
||||||
unsigned long long totalSizeToLoad = UTIL_getTotalFileSize(fileNamesTable, nbFiles);
|
size_t const maxMem = DiB_findMaxMem(totalSizeToLoad * MEMMULT) / MEMMULT;
|
||||||
void* dictBuffer = malloc(maxDictSize);
|
size_t const benchedSize = MIN (maxMem, (size_t)totalSizeToLoad);
|
||||||
size_t dictSize;
|
void* const srcBuffer = malloc(benchedSize+NOISELENGTH);
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
|
/* Checks */
|
||||||
|
if ((!fileSizes) || (!srcBuffer) || (!dictBuffer)) EXM_THROW(12, "not enough memory for DiB_trainFiles"); /* should not happen */
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
g_displayLevel = params.notificationLevel;
|
g_displayLevel = params.notificationLevel;
|
||||||
benchedSize = DiB_findMaxMem(totalSizeToLoad * MEMMULT) / MEMMULT;
|
|
||||||
if ((unsigned long long)benchedSize > totalSizeToLoad) benchedSize = (size_t)totalSizeToLoad;
|
|
||||||
if (benchedSize < totalSizeToLoad)
|
if (benchedSize < totalSizeToLoad)
|
||||||
DISPLAYLEVEL(1, "Not enough memory; training on %u MB only...\n", (unsigned)(benchedSize >> 20));
|
DISPLAYLEVEL(1, "Not enough memory; training on %u MB only...\n", (unsigned)(benchedSize >> 20));
|
||||||
|
|
||||||
/* Memory allocation & restrictions */
|
|
||||||
srcBuffer = malloc(benchedSize+NOISELENGTH); /* + noise */
|
|
||||||
if ((!fileSizes) || (!srcBuffer) || (!dictBuffer)) EXM_THROW(12, "not enough memory for DiB_trainFiles"); /* should not happen */
|
|
||||||
|
|
||||||
/* Load input buffer */
|
/* Load input buffer */
|
||||||
DiB_loadFiles(srcBuffer, benchedSize, fileSizes, fileNamesTable, nbFiles);
|
nbFiles = DiB_loadFiles(srcBuffer, benchedSize, fileSizes, fileNamesTable, nbFiles);
|
||||||
DiB_fillNoise((char*)srcBuffer + benchedSize, NOISELENGTH); /* guard band, for end of buffer condition */
|
DiB_fillNoise((char*)srcBuffer + benchedSize, NOISELENGTH); /* guard band, for end of buffer condition */
|
||||||
|
|
||||||
/* call buffer version */
|
{ size_t const dictSize = ZDICT_trainFromBuffer_unsafe(dictBuffer, maxDictSize,
|
||||||
dictSize = ZDICT_trainFromBuffer_unsafe(dictBuffer, maxDictSize,
|
srcBuffer, fileSizes, nbFiles,
|
||||||
srcBuffer, fileSizes, nbFiles,
|
params);
|
||||||
params);
|
if (ZDICT_isError(dictSize)) {
|
||||||
if (ZDICT_isError(dictSize)) {
|
DISPLAYLEVEL(1, "dictionary training failed : %s \n", ZDICT_getErrorName(dictSize)); /* should not happen */
|
||||||
DISPLAYLEVEL(1, "dictionary training failed : %s \n", ZDICT_getErrorName(dictSize)); /* should not happen */
|
result = 1;
|
||||||
result = 1;
|
goto _cleanup;
|
||||||
goto _cleanup;
|
}
|
||||||
|
/* save dict */
|
||||||
|
DISPLAYLEVEL(2, "Save dictionary of size %u into file %s \n", (U32)dictSize, dictFileName);
|
||||||
|
DiB_saveDict(dictFileName, dictBuffer, dictSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save dict */
|
|
||||||
DISPLAYLEVEL(2, "Save dictionary of size %u into file %s \n", (U32)dictSize, dictFileName);
|
|
||||||
DiB_saveDict(dictFileName, dictBuffer, dictSize);
|
|
||||||
|
|
||||||
/* clean up */
|
/* clean up */
|
||||||
_cleanup:
|
_cleanup:
|
||||||
free(srcBuffer);
|
free(srcBuffer);
|
||||||
|
|||||||
+2
-1
@@ -32,7 +32,8 @@
|
|||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Dependencies
|
* Dependencies
|
||||||
***************************************/
|
***************************************/
|
||||||
#include "../lib/dictBuilder/zdict_static.h" /* ZDICT_params_t */
|
#define ZDICT_STATIC_LINKING_ONLY
|
||||||
|
#include "zdict.h" /* ZDICT_params_t */
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
|
|||||||
+176
-50
@@ -56,8 +56,11 @@
|
|||||||
|
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include "zstd_static.h" /* ZSTD_magicNumber, ZSTD_frameHeaderSize_max */
|
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_magicNumber, ZSTD_frameHeaderSize_max */
|
||||||
#include "zbuff_static.h"
|
#include "zstd.h"
|
||||||
|
#include "zstd_internal.h" /* MIN, KB, MB */
|
||||||
|
#define ZBUFF_STATIC_LINKING_ONLY
|
||||||
|
#include "zbuff.h"
|
||||||
|
|
||||||
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
||||||
# include "zstd_legacy.h" /* ZSTD_isLegacy */
|
# include "zstd_legacy.h" /* ZSTD_isLegacy */
|
||||||
@@ -71,7 +74,7 @@
|
|||||||
#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 */
|
||||||
# define SET_BINARY_MODE(file) { int unused = _setmode(_fileno(file), _O_BINARY); (void)unused; }
|
# define SET_BINARY_MODE(file) { if (_setmode(_fileno(file), _O_BINARY) == -1) perror("Cannot set _O_BINARY"); }
|
||||||
#else
|
#else
|
||||||
# include <unistd.h> /* isatty */
|
# include <unistd.h> /* isatty */
|
||||||
# define SET_BINARY_MODE(file)
|
# define SET_BINARY_MODE(file)
|
||||||
@@ -96,7 +99,7 @@
|
|||||||
|
|
||||||
#define CACHELINE 64
|
#define CACHELINE 64
|
||||||
|
|
||||||
#define MAX_DICT_SIZE (1 MB) /* protection against large input (attack scenario) ; can be changed */
|
#define MAX_DICT_SIZE (8 MB) /* protection against large input (attack scenario) */
|
||||||
|
|
||||||
#define FNSPACE 30
|
#define FNSPACE 30
|
||||||
|
|
||||||
@@ -130,6 +133,14 @@ static U32 g_overwrite = 0;
|
|||||||
void FIO_overwriteMode(void) { g_overwrite=1; }
|
void FIO_overwriteMode(void) { g_overwrite=1; }
|
||||||
static U32 g_maxWLog = 23;
|
static U32 g_maxWLog = 23;
|
||||||
void FIO_setMaxWLog(unsigned maxWLog) { g_maxWLog = maxWLog; }
|
void FIO_setMaxWLog(unsigned maxWLog) { g_maxWLog = maxWLog; }
|
||||||
|
static U32 g_sparseFileSupport = 1; /* 0 : no sparse allowed; 1: auto (file yes, stdout no); 2: force sparse */
|
||||||
|
void FIO_setSparseWrite(unsigned sparse) { g_sparseFileSupport=sparse; }
|
||||||
|
static U32 g_dictIDFlag = 1;
|
||||||
|
void FIO_setDictIDFlag(unsigned dictIDFlag) { g_dictIDFlag = dictIDFlag; }
|
||||||
|
static U32 g_checksumFlag = 0;
|
||||||
|
void FIO_setChecksumFlag(unsigned checksumFlag) { g_checksumFlag = checksumFlag; }
|
||||||
|
static U32 g_removeSrcFile = 0;
|
||||||
|
void FIO_setRemoveSrcFile(unsigned flag) { g_removeSrcFile = (flag>0); }
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
@@ -178,8 +189,12 @@ static FILE* FIO_openDstFile(const char* dstFileName)
|
|||||||
DISPLAYLEVEL(4,"Using stdout for output\n");
|
DISPLAYLEVEL(4,"Using stdout for output\n");
|
||||||
f = stdout;
|
f = stdout;
|
||||||
SET_BINARY_MODE(stdout);
|
SET_BINARY_MODE(stdout);
|
||||||
|
if (g_sparseFileSupport==1) {
|
||||||
|
g_sparseFileSupport = 0;
|
||||||
|
DISPLAYLEVEL(4, "Sparse File Support is automatically disabled on stdout ; try --sparse \n");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!g_overwrite) { /* Check if destination file already exists */
|
if (!g_overwrite && strcmp (dstFileName, nulmark)) { /* Check if destination file already exists */
|
||||||
f = fopen( dstFileName, "rb" );
|
f = fopen( dstFileName, "rb" );
|
||||||
if (f != 0) { /* dest file exists, prompt for overwrite authorization */
|
if (f != 0) { /* dest file exists, prompt for overwrite authorization */
|
||||||
fclose(f);
|
fclose(f);
|
||||||
@@ -189,8 +204,7 @@ static FILE* FIO_openDstFile(const char* dstFileName)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
DISPLAY("zstd: %s already exists; do you wish to overwrite (y/N) ? ", dstFileName);
|
DISPLAY("zstd: %s already exists; do you wish to overwrite (y/N) ? ", dstFileName);
|
||||||
{
|
{ int ch = getchar();
|
||||||
int ch = getchar();
|
|
||||||
if ((ch!='Y') && (ch!='y')) {
|
if ((ch!='Y') && (ch!='y')) {
|
||||||
DISPLAY(" not overwritten \n");
|
DISPLAY(" not overwritten \n");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -206,12 +220,12 @@ static FILE* FIO_openDstFile(const char* dstFileName)
|
|||||||
/*! FIO_loadFile() :
|
/*! FIO_loadFile() :
|
||||||
* creates a buffer, pointed by `*bufferPtr`,
|
* creates a buffer, pointed by `*bufferPtr`,
|
||||||
* loads `filename` content into it,
|
* loads `filename` content into it,
|
||||||
* up to MAX_DICT_SIZE bytes
|
* up to MAX_DICT_SIZE bytes.
|
||||||
|
* @return : loaded size
|
||||||
*/
|
*/
|
||||||
static size_t FIO_loadFile(void** bufferPtr, const char* fileName)
|
static size_t FIO_loadFile(void** bufferPtr, const char* fileName)
|
||||||
{
|
{
|
||||||
FILE* fileHandle;
|
FILE* fileHandle;
|
||||||
size_t readSize;
|
|
||||||
U64 fileSize;
|
U64 fileSize;
|
||||||
|
|
||||||
*bufferPtr = NULL;
|
*bufferPtr = NULL;
|
||||||
@@ -231,8 +245,8 @@ static size_t FIO_loadFile(void** bufferPtr, const char* fileName)
|
|||||||
}
|
}
|
||||||
*bufferPtr = (BYTE*)malloc((size_t)fileSize);
|
*bufferPtr = (BYTE*)malloc((size_t)fileSize);
|
||||||
if (*bufferPtr==NULL) EXM_THROW(34, "Allocation error : not enough memory for dictBuffer");
|
if (*bufferPtr==NULL) EXM_THROW(34, "Allocation error : not enough memory for dictBuffer");
|
||||||
readSize = fread(*bufferPtr, 1, (size_t)fileSize, fileHandle);
|
{ size_t const readSize = fread(*bufferPtr, 1, (size_t)fileSize, fileHandle);
|
||||||
if (readSize!=fileSize) EXM_THROW(35, "Error reading dictionary file %s", fileName);
|
if (readSize!=fileSize) EXM_THROW(35, "Error reading dictionary file %s", fileName); }
|
||||||
fclose(fileHandle);
|
fclose(fileHandle);
|
||||||
return (size_t)fileSize;
|
return (size_t)fileSize;
|
||||||
}
|
}
|
||||||
@@ -302,12 +316,18 @@ static int FIO_compressFilename_internal(cRess_t ress,
|
|||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
{ ZSTD_parameters params;
|
{ ZSTD_parameters params;
|
||||||
|
memset(¶ms, 0, sizeof(params));
|
||||||
params.cParams = ZSTD_getCParams(cLevel, fileSize, ress.dictBufferSize);
|
params.cParams = ZSTD_getCParams(cLevel, fileSize, ress.dictBufferSize);
|
||||||
params.fParams.contentSizeFlag = 1;
|
params.fParams.contentSizeFlag = 1;
|
||||||
if (g_maxWLog) if (params.cParams.windowLog > g_maxWLog) params.cParams.windowLog = g_maxWLog;
|
params.fParams.checksumFlag = g_checksumFlag;
|
||||||
{ size_t const errorCode = ZBUFF_compressInit_advanced(ress.ctx, ress.dictBuffer, ress.dictBufferSize, params, fileSize);
|
params.fParams.noDictIDFlag = !g_dictIDFlag;
|
||||||
if (ZBUFF_isError(errorCode)) EXM_THROW(21, "Error initializing compression : %s", ZBUFF_getErrorName(errorCode)); }
|
if ((g_maxWLog) && (params.cParams.windowLog > g_maxWLog)) {
|
||||||
}
|
params.cParams.windowLog = g_maxWLog;
|
||||||
|
params.cParams = ZSTD_adjustCParams(params.cParams, fileSize, ress.dictBufferSize);
|
||||||
|
}
|
||||||
|
{ size_t const errorCode = ZBUFF_compressInit_advanced(ress.ctx, ress.dictBuffer, ress.dictBufferSize, params, fileSize);
|
||||||
|
if (ZBUFF_isError(errorCode)) EXM_THROW(21, "Error initializing compression : %s", ZBUFF_getErrorName(errorCode));
|
||||||
|
} }
|
||||||
|
|
||||||
/* Main compression loop */
|
/* Main compression loop */
|
||||||
readsize = 0;
|
readsize = 0;
|
||||||
@@ -347,8 +367,9 @@ static int FIO_compressFilename_internal(cRess_t ress,
|
|||||||
|
|
||||||
/* Status */
|
/* Status */
|
||||||
DISPLAYLEVEL(2, "\r%79s\r", "");
|
DISPLAYLEVEL(2, "\r%79s\r", "");
|
||||||
DISPLAYLEVEL(2,"Compressed %llu bytes into %llu bytes ==> %.2f%%\n",
|
DISPLAYLEVEL(2,"%-20.20s :%6.2f%% (%6llu =>%6llu bytes, %s) \n", srcFileName,
|
||||||
(unsigned long long)readsize, (unsigned long long) compressedfilesize, (double)compressedfilesize/readsize*100);
|
(double)compressedfilesize/readsize*100, (unsigned long long)readsize, (unsigned long long) compressedfilesize,
|
||||||
|
dstFileName);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -366,36 +387,38 @@ static int FIO_compressFilename_srcFile(cRess_t ress,
|
|||||||
int result;
|
int result;
|
||||||
|
|
||||||
/* File check */
|
/* File check */
|
||||||
|
if (UTIL_isDirectory(srcFileName)) {
|
||||||
|
DISPLAYLEVEL(1, "zstd: %s is a directory -- ignored \n", srcFileName);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
ress.srcFile = FIO_openSrcFile(srcFileName);
|
ress.srcFile = FIO_openSrcFile(srcFileName);
|
||||||
if (!ress.srcFile) return 1; /* srcFile could not be opened */
|
if (!ress.srcFile) return 1; /* srcFile could not be opened */
|
||||||
|
|
||||||
result = FIO_compressFilename_internal(ress, dstFileName, srcFileName, cLevel);
|
result = FIO_compressFilename_internal(ress, dstFileName, srcFileName, cLevel);
|
||||||
|
|
||||||
fclose(ress.srcFile);
|
fclose(ress.srcFile);
|
||||||
|
if ((g_removeSrcFile) && (!result)) remove(srcFileName);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! FIO_compressFilename_extRess() :
|
/*! FIO_compressFilename_dstFile() :
|
||||||
* @return : 0 : compression completed correctly,
|
* @return : 0 : compression completed correctly,
|
||||||
* 1 : missing or pb opening srcFileName
|
* 1 : pb
|
||||||
*/
|
*/
|
||||||
static int FIO_compressFilename_extRess(cRess_t ress,
|
static int FIO_compressFilename_dstFile(cRess_t ress,
|
||||||
const char* dstFileName, const char* srcFileName,
|
const char* dstFileName, const char* srcFileName,
|
||||||
int cLevel)
|
int cLevel)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
ress.srcFile = FIO_openSrcFile(srcFileName);
|
|
||||||
if (ress.srcFile==0) return 1;
|
|
||||||
ress.dstFile = FIO_openDstFile(dstFileName);
|
ress.dstFile = FIO_openDstFile(dstFileName);
|
||||||
if (ress.dstFile==0) { fclose(ress.srcFile); return 1; }
|
if (ress.dstFile==0) { fclose(ress.srcFile); return 1; }
|
||||||
|
|
||||||
result = FIO_compressFilename_internal(ress, dstFileName, srcFileName, cLevel);
|
result = FIO_compressFilename_srcFile(ress, dstFileName, srcFileName, cLevel);
|
||||||
if (result!=0) remove(dstFileName); /* remove operation artefact */
|
|
||||||
|
|
||||||
fclose(ress.srcFile); /* no pb to expect : only reading */
|
|
||||||
if (fclose(ress.dstFile)) EXM_THROW(28, "Write error : cannot properly close %s", dstFileName);
|
if (fclose(ress.dstFile)) EXM_THROW(28, "Write error : cannot properly close %s", dstFileName);
|
||||||
|
if (result!=0) remove(dstFileName); /* remove operation artefact */
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,19 +426,13 @@ static int FIO_compressFilename_extRess(cRess_t ress,
|
|||||||
int FIO_compressFilename(const char* dstFileName, const char* srcFileName,
|
int FIO_compressFilename(const char* dstFileName, const char* srcFileName,
|
||||||
const char* dictFileName, int compressionLevel)
|
const char* dictFileName, int compressionLevel)
|
||||||
{
|
{
|
||||||
clock_t start;
|
clock_t const start = clock();
|
||||||
cRess_t ress;
|
|
||||||
int issueWithSrcFile = 0;
|
|
||||||
|
|
||||||
/* Init */
|
|
||||||
start = clock();
|
|
||||||
ress = FIO_createCResources(dictFileName);
|
|
||||||
|
|
||||||
issueWithSrcFile += FIO_compressFilename_extRess(ress, dstFileName, srcFileName, compressionLevel);
|
|
||||||
|
|
||||||
|
cRess_t const ress = FIO_createCResources(dictFileName);
|
||||||
|
int const issueWithSrcFile = FIO_compressFilename_dstFile(ress, dstFileName, srcFileName, compressionLevel);
|
||||||
FIO_freeCResources(ress);
|
FIO_freeCResources(ress);
|
||||||
|
|
||||||
{ double seconds = (double)(clock() - start) / CLOCKS_PER_SEC;
|
{ double const seconds = (double)(clock() - start) / CLOCKS_PER_SEC;
|
||||||
DISPLAYLEVEL(4, "Completed in %.2f sec \n", seconds);
|
DISPLAYLEVEL(4, "Completed in %.2f sec \n", seconds);
|
||||||
}
|
}
|
||||||
return issueWithSrcFile;
|
return issueWithSrcFile;
|
||||||
@@ -439,6 +456,7 @@ int FIO_compressMultipleFilenames(const char** inFileNamesTable, unsigned nbFile
|
|||||||
if (!strcmp(suffix, stdoutmark)) {
|
if (!strcmp(suffix, stdoutmark)) {
|
||||||
unsigned u;
|
unsigned u;
|
||||||
ress.dstFile = stdout;
|
ress.dstFile = stdout;
|
||||||
|
SET_BINARY_MODE(stdout);
|
||||||
for (u=0; u<nbFiles; u++)
|
for (u=0; u<nbFiles; u++)
|
||||||
missed_files += FIO_compressFilename_srcFile(ress, stdoutmark,
|
missed_files += FIO_compressFilename_srcFile(ress, stdoutmark,
|
||||||
inFileNamesTable[u], compressionLevel);
|
inFileNamesTable[u], compressionLevel);
|
||||||
@@ -450,7 +468,7 @@ int FIO_compressMultipleFilenames(const char** inFileNamesTable, unsigned nbFile
|
|||||||
if (dfnSize <= ifnSize+suffixSize+1) { free(dstFileName); dfnSize = ifnSize + 20; dstFileName = (char*)malloc(dfnSize); }
|
if (dfnSize <= ifnSize+suffixSize+1) { free(dstFileName); dfnSize = ifnSize + 20; dstFileName = (char*)malloc(dfnSize); }
|
||||||
strcpy(dstFileName, inFileNamesTable[u]);
|
strcpy(dstFileName, inFileNamesTable[u]);
|
||||||
strcat(dstFileName, suffix);
|
strcat(dstFileName, suffix);
|
||||||
missed_files += FIO_compressFilename_extRess(ress, dstFileName,
|
missed_files += FIO_compressFilename_dstFile(ress, dstFileName,
|
||||||
inFileNamesTable[u], compressionLevel);
|
inFileNamesTable[u], compressionLevel);
|
||||||
} }
|
} }
|
||||||
|
|
||||||
@@ -512,6 +530,81 @@ static void FIO_freeDResources(dRess_t ress)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** FIO_fwriteSparse() :
|
||||||
|
* @return : storedSkips, to be provided to next call to FIO_fwriteSparse() of LZ4IO_fwriteSparseEnd() */
|
||||||
|
static unsigned FIO_fwriteSparse(FILE* file, const void* buffer, size_t bufferSize, unsigned storedSkips)
|
||||||
|
{
|
||||||
|
const size_t* const bufferT = (const size_t*)buffer; /* Buffer is supposed malloc'ed, hence aligned on size_t */
|
||||||
|
size_t bufferSizeT = bufferSize / sizeof(size_t);
|
||||||
|
const size_t* const bufferTEnd = bufferT + bufferSizeT;
|
||||||
|
const size_t* ptrT = bufferT;
|
||||||
|
static const size_t segmentSizeT = (32 KB) / sizeof(size_t); /* 0-test re-attempted every 32 KB */
|
||||||
|
|
||||||
|
if (!g_sparseFileSupport) { /* normal write */
|
||||||
|
size_t const sizeCheck = fwrite(buffer, 1, bufferSize, file);
|
||||||
|
if (sizeCheck != bufferSize) EXM_THROW(70, "Write error : cannot write decoded block");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* avoid int overflow */
|
||||||
|
if (storedSkips > 1 GB) {
|
||||||
|
int const seekResult = fseek(file, 1 GB, SEEK_CUR);
|
||||||
|
if (seekResult != 0) EXM_THROW(71, "1 GB skip error (sparse file support)");
|
||||||
|
storedSkips -= 1 GB;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ptrT < bufferTEnd) {
|
||||||
|
size_t seg0SizeT = segmentSizeT;
|
||||||
|
size_t nb0T;
|
||||||
|
|
||||||
|
/* count leading zeros */
|
||||||
|
if (seg0SizeT > bufferSizeT) seg0SizeT = bufferSizeT;
|
||||||
|
bufferSizeT -= seg0SizeT;
|
||||||
|
for (nb0T=0; (nb0T < seg0SizeT) && (ptrT[nb0T] == 0); nb0T++) ;
|
||||||
|
storedSkips += (unsigned)(nb0T * sizeof(size_t));
|
||||||
|
|
||||||
|
if (nb0T != seg0SizeT) { /* not all 0s */
|
||||||
|
int const seekResult = fseek(file, storedSkips, SEEK_CUR);
|
||||||
|
if (seekResult) EXM_THROW(72, "Sparse skip error ; try --no-sparse");
|
||||||
|
storedSkips = 0;
|
||||||
|
seg0SizeT -= nb0T;
|
||||||
|
ptrT += nb0T;
|
||||||
|
{ size_t const sizeCheck = fwrite(ptrT, sizeof(size_t), seg0SizeT, file);
|
||||||
|
if (sizeCheck != seg0SizeT) EXM_THROW(73, "Write error : cannot write decoded block");
|
||||||
|
} }
|
||||||
|
ptrT += seg0SizeT;
|
||||||
|
}
|
||||||
|
|
||||||
|
{ static size_t const maskT = sizeof(size_t)-1;
|
||||||
|
if (bufferSize & maskT) { /* size not multiple of sizeof(size_t) : implies end of block */
|
||||||
|
const char* const restStart = (const char*)bufferTEnd;
|
||||||
|
const char* restPtr = restStart;
|
||||||
|
size_t restSize = bufferSize & maskT;
|
||||||
|
const char* const restEnd = restStart + restSize;
|
||||||
|
for ( ; (restPtr < restEnd) && (*restPtr == 0); restPtr++) ;
|
||||||
|
storedSkips += (unsigned) (restPtr - restStart);
|
||||||
|
if (restPtr != restEnd) {
|
||||||
|
int seekResult = fseek(file, storedSkips, SEEK_CUR);
|
||||||
|
if (seekResult) EXM_THROW(74, "Sparse skip error ; try --no-sparse");
|
||||||
|
storedSkips = 0;
|
||||||
|
{ size_t const sizeCheck = fwrite(restPtr, 1, restEnd - restPtr, file);
|
||||||
|
if (sizeCheck != (size_t)(restEnd - restPtr)) EXM_THROW(75, "Write error : cannot write decoded end of block");
|
||||||
|
} } } }
|
||||||
|
|
||||||
|
return storedSkips;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIO_fwriteSparseEnd(FILE* file, unsigned storedSkips)
|
||||||
|
{
|
||||||
|
if (storedSkips-->0) { /* implies g_sparseFileSupport>0 */
|
||||||
|
int const seekResult = fseek(file, storedSkips, SEEK_CUR);
|
||||||
|
if (seekResult != 0) EXM_THROW(69, "Final skip error (sparse file)\n");
|
||||||
|
{ const char lastZeroByte[1] = { 0 };
|
||||||
|
size_t const sizeCheck = fwrite(lastZeroByte, 1, 1, file);
|
||||||
|
if (sizeCheck != 1) EXM_THROW(69, "Write error : cannot write last zero\n");
|
||||||
|
} }
|
||||||
|
}
|
||||||
|
|
||||||
/** FIO_decompressFrame() :
|
/** FIO_decompressFrame() :
|
||||||
@return : size of decoded frame
|
@return : size of decoded frame
|
||||||
*/
|
*/
|
||||||
@@ -520,26 +613,25 @@ unsigned long long FIO_decompressFrame(dRess_t ress,
|
|||||||
{
|
{
|
||||||
U64 frameSize = 0;
|
U64 frameSize = 0;
|
||||||
size_t readSize;
|
size_t readSize;
|
||||||
|
U32 storedSkips = 0;
|
||||||
|
|
||||||
ZBUFF_decompressInitDictionary(ress.dctx, ress.dictBuffer, ress.dictBufferSize);
|
ZBUFF_decompressInitDictionary(ress.dctx, ress.dictBuffer, ress.dictBufferSize);
|
||||||
|
|
||||||
/* Header loading (optional, saves one loop) */
|
/* Header loading (optional, saves one loop) */
|
||||||
{ size_t const toLoad = ZSTD_frameHeaderSize_min - alreadyLoaded; /* assumption : ZSTD_frameHeaderSize_min >= alreadyLoaded */
|
{ size_t const toLoad = 9 - alreadyLoaded; /* assumption : 9 >= alreadyLoaded */
|
||||||
size_t const loadedSize = fread(((char*)ress.srcBuffer) + alreadyLoaded, 1, toLoad, finput);
|
size_t const loadedSize = fread(((char*)ress.srcBuffer) + alreadyLoaded, 1, toLoad, finput);
|
||||||
readSize = alreadyLoaded + loadedSize;
|
readSize = alreadyLoaded + loadedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main decompression Loop */
|
/* Main decompression Loop */
|
||||||
while (1) {
|
while (1) {
|
||||||
/* Decode */
|
|
||||||
size_t inSize=readSize, decodedSize=ress.dstBufferSize;
|
size_t inSize=readSize, decodedSize=ress.dstBufferSize;
|
||||||
size_t const toRead = ZBUFF_decompressContinue(ress.dctx, ress.dstBuffer, &decodedSize, ress.srcBuffer, &inSize);
|
size_t const toRead = ZBUFF_decompressContinue(ress.dctx, ress.dstBuffer, &decodedSize, ress.srcBuffer, &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;
|
||||||
|
|
||||||
/* Write block */
|
/* Write block */
|
||||||
{ size_t const sizeCheck = fwrite(ress.dstBuffer, 1, decodedSize, foutput);
|
storedSkips = FIO_fwriteSparse(foutput, ress.dstBuffer, decodedSize, storedSkips);
|
||||||
if (sizeCheck != decodedSize) EXM_THROW(37, "Write error : unable to write data block into destination"); }
|
|
||||||
frameSize += decodedSize;
|
frameSize += decodedSize;
|
||||||
DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)(frameSize>>20) );
|
DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)(frameSize>>20) );
|
||||||
|
|
||||||
@@ -553,10 +645,34 @@ unsigned long long FIO_decompressFrame(dRess_t ress,
|
|||||||
EXM_THROW(35, "Read error");
|
EXM_THROW(35, "Read error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FIO_fwriteSparseEnd(foutput, storedSkips);
|
||||||
|
|
||||||
return frameSize;
|
return frameSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** FIO_passThrough() : just copy input into output, for compatibility with gzip -df mode
|
||||||
|
@return : 0 (no error) */
|
||||||
|
static unsigned FIO_passThrough(FILE* foutput, FILE* finput, void* buffer, size_t bufferSize)
|
||||||
|
{
|
||||||
|
size_t const blockSize = MIN (64 KB, bufferSize);
|
||||||
|
size_t readFromInput = 1;
|
||||||
|
unsigned storedSkips = 0;
|
||||||
|
|
||||||
|
/* assumption : first 4 bytes already loaded (magic number detection), and stored within buffer */
|
||||||
|
{ size_t const sizeCheck = fwrite(buffer, 1, 4, foutput);
|
||||||
|
if (sizeCheck != 4) EXM_THROW(50, "Pass-through write error"); }
|
||||||
|
|
||||||
|
while (readFromInput) {
|
||||||
|
readFromInput = fread(buffer, 1, blockSize, finput);
|
||||||
|
storedSkips = FIO_fwriteSparse(foutput, buffer, readFromInput, storedSkips);
|
||||||
|
}
|
||||||
|
|
||||||
|
FIO_fwriteSparseEnd(foutput, storedSkips);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** FIO_decompressSrcFile() :
|
/** FIO_decompressSrcFile() :
|
||||||
Decompression `srcFileName` into `ress.dstFile`
|
Decompression `srcFileName` into `ress.dstFile`
|
||||||
@return : 0 : OK
|
@return : 0 : OK
|
||||||
@@ -566,7 +682,13 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName)
|
|||||||
{
|
{
|
||||||
unsigned long long filesize = 0;
|
unsigned long long filesize = 0;
|
||||||
FILE* const dstFile = ress.dstFile;
|
FILE* const dstFile = ress.dstFile;
|
||||||
FILE* const srcFile = FIO_openSrcFile(srcFileName);
|
FILE* srcFile;
|
||||||
|
|
||||||
|
if (UTIL_isDirectory(srcFileName)) {
|
||||||
|
DISPLAYLEVEL(1, "zstd: %s is a directory -- ignored \n", srcFileName);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
srcFile = FIO_openSrcFile(srcFileName);
|
||||||
if (srcFile==0) return 1;
|
if (srcFile==0) return 1;
|
||||||
|
|
||||||
/* for each frame */
|
/* for each frame */
|
||||||
@@ -583,19 +705,23 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (magic != ZSTD_MAGICNUMBER) {
|
if (((magic & 0xFFFFFFF0U) != ZSTD_MAGIC_SKIPPABLE_START) && (magic != ZSTD_MAGICNUMBER)) {
|
||||||
DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName);
|
if (g_overwrite) /* -df : pass-through mode */
|
||||||
return 1;
|
return FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize);
|
||||||
} }
|
else {
|
||||||
|
DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName);
|
||||||
|
return 1;
|
||||||
|
} } }
|
||||||
filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead);
|
filesize += FIO_decompressFrame(ress, dstFile, srcFile, toRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Final Status */
|
/* Final Status */
|
||||||
DISPLAYLEVEL(2, "\r%79s\r", "");
|
DISPLAYLEVEL(2, "\r%79s\r", "");
|
||||||
DISPLAYLEVEL(2, "Successfully decoded %llu bytes \n", filesize);
|
DISPLAYLEVEL(2, "%-20.20s: %llu bytes \n", srcFileName, filesize);
|
||||||
|
|
||||||
/* Close */
|
/* Close */
|
||||||
fclose(srcFile);
|
fclose(srcFile);
|
||||||
|
if (g_removeSrcFile) remove(srcFileName);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,7 +731,7 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName)
|
|||||||
@return : 0 : OK
|
@return : 0 : OK
|
||||||
1 : operation aborted (src not available, dst already taken, etc.)
|
1 : operation aborted (src not available, dst already taken, etc.)
|
||||||
*/
|
*/
|
||||||
static int FIO_decompressFile_extRess(dRess_t ress,
|
static int FIO_decompressDstFile(dRess_t ress,
|
||||||
const char* dstFileName, const char* srcFileName)
|
const char* dstFileName, const char* srcFileName)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
@@ -613,9 +739,9 @@ static int FIO_decompressFile_extRess(dRess_t ress,
|
|||||||
if (ress.dstFile==0) return 1;
|
if (ress.dstFile==0) return 1;
|
||||||
|
|
||||||
result = FIO_decompressSrcFile(ress, srcFileName);
|
result = FIO_decompressSrcFile(ress, srcFileName);
|
||||||
if (result != 0) remove(dstFileName);
|
|
||||||
|
|
||||||
if (fclose(ress.dstFile)) EXM_THROW(38, "Write error : cannot properly close %s", dstFileName);
|
if (fclose(ress.dstFile)) EXM_THROW(38, "Write error : cannot properly close %s", dstFileName);
|
||||||
|
if (result != 0) remove(dstFileName);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,7 +752,7 @@ int FIO_decompressFilename(const char* dstFileName, const char* srcFileName,
|
|||||||
int missingFiles = 0;
|
int missingFiles = 0;
|
||||||
dRess_t ress = FIO_createDResources(dictFileName);
|
dRess_t ress = FIO_createDResources(dictFileName);
|
||||||
|
|
||||||
missingFiles += FIO_decompressFile_extRess(ress, dstFileName, srcFileName);
|
missingFiles += FIO_decompressDstFile(ress, dstFileName, srcFileName);
|
||||||
|
|
||||||
FIO_freeDResources(ress);
|
FIO_freeDResources(ress);
|
||||||
return missingFiles;
|
return missingFiles;
|
||||||
@@ -673,7 +799,7 @@ int FIO_decompressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles
|
|||||||
memcpy(dstFileName, srcFileName, sfnSize - suffixSize);
|
memcpy(dstFileName, srcFileName, sfnSize - suffixSize);
|
||||||
dstFileName[sfnSize-suffixSize] = '\0';
|
dstFileName[sfnSize-suffixSize] = '\0';
|
||||||
|
|
||||||
missingFiles += FIO_decompressFile_extRess(ress, dstFileName, srcFileName);
|
missingFiles += FIO_decompressDstFile(ress, dstFileName, srcFileName);
|
||||||
}
|
}
|
||||||
free(dstFileName);
|
free(dstFileName);
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -46,7 +46,11 @@ extern "C" {
|
|||||||
***************************************/
|
***************************************/
|
||||||
void FIO_overwriteMode(void);
|
void FIO_overwriteMode(void);
|
||||||
void FIO_setNotificationLevel(unsigned level);
|
void FIO_setNotificationLevel(unsigned level);
|
||||||
void FIO_setMaxWLog(unsigned maxWLog); /**< if `maxWLog` == 0, no max enforced */
|
void FIO_setMaxWLog(unsigned maxWLog); /**< if `maxWLog` == 0, no max enforced */
|
||||||
|
void FIO_setSparseWrite(unsigned sparse); /**< 0: no sparse; 1: disable on stdout; 2: always enabled */
|
||||||
|
void FIO_setDictIDFlag(unsigned dictIDFlag);
|
||||||
|
void FIO_setChecksumFlag(unsigned checksumFlag);
|
||||||
|
void FIO_setRemoveSrcFile(unsigned flag);
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
|
|||||||
@@ -28,12 +28,13 @@
|
|||||||
#include "util.h" /* Compiler options, UTIL_GetFileSize */
|
#include "util.h" /* Compiler options, UTIL_GetFileSize */
|
||||||
#include <stdlib.h> /* malloc */
|
#include <stdlib.h> /* malloc */
|
||||||
#include <stdio.h> /* fprintf, fopen, ftello64 */
|
#include <stdio.h> /* fprintf, fopen, ftello64 */
|
||||||
#include <string.h> /* strcmp */
|
|
||||||
#include <time.h> /* clock_t, clock, CLOCKS_PER_SEC */
|
#include <time.h> /* clock_t, clock, CLOCKS_PER_SEC */
|
||||||
|
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "zstd_static.h"
|
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressBegin, ZSTD_compressContinue, etc. */
|
||||||
#include "fse_static.h"
|
#include "zstd.h" /* ZSTD_VERSION_STRING */
|
||||||
|
#define FSE_STATIC_LINKING_ONLY /* FSE_DTABLE_SIZE_U32 */
|
||||||
|
#include "fse.h"
|
||||||
#include "zbuff.h"
|
#include "zbuff.h"
|
||||||
#include "datagen.h"
|
#include "datagen.h"
|
||||||
|
|
||||||
@@ -42,11 +43,8 @@
|
|||||||
* Constants
|
* Constants
|
||||||
**************************************/
|
**************************************/
|
||||||
#define PROGRAM_DESCRIPTION "Zstandard speed analyzer"
|
#define PROGRAM_DESCRIPTION "Zstandard speed analyzer"
|
||||||
#ifndef ZSTD_VERSION
|
|
||||||
# define ZSTD_VERSION ""
|
|
||||||
#endif
|
|
||||||
#define AUTHOR "Yann Collet"
|
#define AUTHOR "Yann Collet"
|
||||||
#define WELCOME_MESSAGE "*** %s %s %i-bits, by %s (%s) ***\n", PROGRAM_DESCRIPTION, ZSTD_VERSION, (int)(sizeof(void*)*8), AUTHOR, __DATE__
|
#define WELCOME_MESSAGE "*** %s %s %i-bits, by %s (%s) ***\n", PROGRAM_DESCRIPTION, ZSTD_VERSION_STRING, (int)(sizeof(void*)*8), AUTHOR, __DATE__
|
||||||
|
|
||||||
|
|
||||||
#define KB *(1<<10)
|
#define KB *(1<<10)
|
||||||
@@ -547,4 +545,3 @@ int main(int argc, const char** argv)
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+258
-211
@@ -28,7 +28,7 @@
|
|||||||
#ifdef _MSC_VER /* Visual Studio */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
# define _CRT_SECURE_NO_WARNINGS /* fgets */
|
# define _CRT_SECURE_NO_WARNINGS /* fgets */
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# pragma warning(disable : 4146) /* disable: C4146: minus unsigned expression */
|
# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -40,24 +40,22 @@
|
|||||||
#include <sys/timeb.h> /* timeb */
|
#include <sys/timeb.h> /* timeb */
|
||||||
#include <string.h> /* strcmp */
|
#include <string.h> /* strcmp */
|
||||||
#include <time.h> /* clock_t */
|
#include <time.h> /* clock_t */
|
||||||
#include "zstd_static.h"
|
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressContinue */
|
||||||
|
#include "zstd.h" /* ZSTD_VERSION_STRING, ZSTD_getErrorCode */
|
||||||
|
#include "zdict.h" /* ZDICT_trainFromBuffer */
|
||||||
#include "datagen.h" /* RDG_genBuffer */
|
#include "datagen.h" /* RDG_genBuffer */
|
||||||
#include "xxhash.h" /* XXH64 */
|
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
#define XXH_STATIC_LINKING_ONLY
|
||||||
|
#include "xxhash.h" /* XXH64 */
|
||||||
|
|
||||||
|
|
||||||
/*-************************************
|
/*-************************************
|
||||||
* Constants
|
* Constants
|
||||||
**************************************/
|
**************************************/
|
||||||
#ifndef ZSTD_VERSION
|
|
||||||
# define ZSTD_VERSION ""
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define KB *(1U<<10)
|
#define KB *(1U<<10)
|
||||||
#define MB *(1U<<20)
|
#define MB *(1U<<20)
|
||||||
#define GB *(1U<<30)
|
#define GB *(1U<<30)
|
||||||
|
|
||||||
static const size_t COMPRESSIBLE_NOISE_LENGTH = 10 MB; /* capital, used to be a macro */
|
|
||||||
static const U32 FUZ_compressibility_default = 50;
|
static const U32 FUZ_compressibility_default = 50;
|
||||||
static const U32 nbTestsDefault = 30000;
|
static const U32 nbTestsDefault = 30000;
|
||||||
|
|
||||||
@@ -81,7 +79,6 @@ static clock_t g_displayClock = 0;
|
|||||||
* Fuzzer functions
|
* Fuzzer functions
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
|
||||||
|
|
||||||
static clock_t FUZ_clockSpan(clock_t cStart)
|
static clock_t FUZ_clockSpan(clock_t cStart)
|
||||||
{
|
{
|
||||||
@@ -89,8 +86,8 @@ static clock_t FUZ_clockSpan(clock_t cStart)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# define FUZ_rotl32(x,r) ((x << r) | (x >> (32 - r)))
|
#define FUZ_rotl32(x,r) ((x << r) | (x >> (32 - r)))
|
||||||
unsigned int FUZ_rand(unsigned int* src)
|
static unsigned FUZ_rand(unsigned* src)
|
||||||
{
|
{
|
||||||
static const U32 prime1 = 2654435761U;
|
static const U32 prime1 = 2654435761U;
|
||||||
static const U32 prime2 = 2246822519U;
|
static const U32 prime2 = 2246822519U;
|
||||||
@@ -107,142 +104,131 @@ static unsigned FUZ_highbit32(U32 v32)
|
|||||||
{
|
{
|
||||||
unsigned nbBits = 0;
|
unsigned nbBits = 0;
|
||||||
if (v32==0) return 0;
|
if (v32==0) return 0;
|
||||||
while (v32) {
|
while (v32) v32 >>= 1, nbBits++;
|
||||||
v32 >>= 1;
|
|
||||||
nbBits ++;
|
|
||||||
}
|
|
||||||
return nbBits;
|
return nbBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define CHECKTEST(var, fn) size_t const var = fn; if (ZSTD_isError(var)) goto _output_error
|
||||||
|
#define CHECK(fn) { CHECKTEST(err, fn); }
|
||||||
|
#define CHECKPLUS(var, fn, more) { CHECKTEST(var, fn); more; }
|
||||||
static int basicUnitTests(U32 seed, double compressibility)
|
static int basicUnitTests(U32 seed, double compressibility)
|
||||||
{
|
{
|
||||||
|
size_t const CNBuffSize = 5 MB;
|
||||||
|
void* const CNBuffer = malloc(CNBuffSize);
|
||||||
|
void* const compressedBuffer = malloc(ZSTD_compressBound(CNBuffSize));
|
||||||
|
void* const decodedBuffer = malloc(CNBuffSize);
|
||||||
int testResult = 0;
|
int testResult = 0;
|
||||||
void* CNBuffer;
|
|
||||||
void* compressedBuffer;
|
|
||||||
void* decodedBuffer;
|
|
||||||
U32 randState = seed;
|
|
||||||
size_t result, cSize;
|
|
||||||
U32 testNb=0;
|
U32 testNb=0;
|
||||||
|
size_t cSize;
|
||||||
|
|
||||||
/* Create compressible test buffer */
|
/* Create compressible noise */
|
||||||
CNBuffer = malloc(COMPRESSIBLE_NOISE_LENGTH);
|
|
||||||
compressedBuffer = malloc(ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH));
|
|
||||||
decodedBuffer = malloc(COMPRESSIBLE_NOISE_LENGTH);
|
|
||||||
if (!CNBuffer || !compressedBuffer || !decodedBuffer) {
|
if (!CNBuffer || !compressedBuffer || !decodedBuffer) {
|
||||||
DISPLAY("Not enough memory, aborting\n");
|
DISPLAY("Not enough memory, aborting\n");
|
||||||
testResult = 1;
|
testResult = 1;
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
RDG_genBuffer(CNBuffer, COMPRESSIBLE_NOISE_LENGTH, compressibility, 0., randState);
|
RDG_genBuffer(CNBuffer, CNBuffSize, compressibility, 0., seed);
|
||||||
|
|
||||||
/* Basic tests */
|
/* Basic tests */
|
||||||
DISPLAYLEVEL(4, "test%3i : compress %u bytes : ", testNb++, (U32)COMPRESSIBLE_NOISE_LENGTH);
|
DISPLAYLEVEL(4, "test%3i : compress %u bytes : ", testNb++, (U32)CNBuffSize);
|
||||||
result = ZSTD_compress(compressedBuffer, ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH), CNBuffer, COMPRESSIBLE_NOISE_LENGTH, 1);
|
CHECKPLUS(r, ZSTD_compress(compressedBuffer, ZSTD_compressBound(CNBuffSize),
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
CNBuffer, CNBuffSize, 1),
|
||||||
cSize = result;
|
cSize=r );
|
||||||
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/COMPRESSIBLE_NOISE_LENGTH*100);
|
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100);
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : decompress %u bytes : ", testNb++, (U32)COMPRESSIBLE_NOISE_LENGTH);
|
DISPLAYLEVEL(4, "test%3i : decompress %u bytes : ", testNb++, (U32)CNBuffSize);
|
||||||
result = ZSTD_decompress(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, compressedBuffer, cSize);
|
CHECKPLUS( r , ZSTD_decompress(decodedBuffer, CNBuffSize, compressedBuffer, cSize),
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
if (r != CNBuffSize) goto _output_error);
|
||||||
if (result != COMPRESSIBLE_NOISE_LENGTH) goto _output_error;
|
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
{ size_t i;
|
DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++);
|
||||||
DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++);
|
{ size_t u;
|
||||||
for (i=0; i<COMPRESSIBLE_NOISE_LENGTH; i++) {
|
for (u=0; u<CNBuffSize; u++) {
|
||||||
if (((BYTE*)decodedBuffer)[i] != ((BYTE*)CNBuffer)[i]) goto _output_error;;
|
if (((BYTE*)decodedBuffer)[u] != ((BYTE*)CNBuffer)[u]) goto _output_error;;
|
||||||
}
|
} }
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
}
|
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : decompress with 1 missing byte : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : decompress with 1 missing byte : ", testNb++);
|
||||||
result = ZSTD_decompress(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, compressedBuffer, cSize-1);
|
{ size_t const r = ZSTD_decompress(decodedBuffer, CNBuffSize, compressedBuffer, cSize-1);
|
||||||
if (!ZSTD_isError(result)) goto _output_error;
|
if (!ZSTD_isError(r)) goto _output_error;
|
||||||
if (result != (size_t)-ZSTD_error_srcSize_wrong) goto _output_error;
|
if (ZSTD_getErrorCode((size_t)r) != ZSTD_error_srcSize_wrong) goto _output_error; }
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : decompress with 1 too much byte : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : decompress with 1 too much byte : ", testNb++);
|
||||||
result = ZSTD_decompress(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, compressedBuffer, cSize+1);
|
{ size_t const r = ZSTD_decompress(decodedBuffer, CNBuffSize, compressedBuffer, cSize+1);
|
||||||
if (!ZSTD_isError(result)) goto _output_error;
|
if (!ZSTD_isError(r)) goto _output_error;
|
||||||
if (result != (size_t)-ZSTD_error_srcSize_wrong) goto _output_error;
|
if (ZSTD_getErrorCode(r) != ZSTD_error_srcSize_wrong) goto _output_error; }
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
/* Dictionary and CCtx Duplication tests */
|
/* Dictionary and CCtx Duplication tests */
|
||||||
{ ZSTD_CCtx* ctxOrig = ZSTD_createCCtx();
|
{ ZSTD_CCtx* const ctxOrig = ZSTD_createCCtx();
|
||||||
ZSTD_CCtx* ctxDuplicated = ZSTD_createCCtx();
|
ZSTD_CCtx* const ctxDuplicated = ZSTD_createCCtx();
|
||||||
ZSTD_DCtx* dctx = ZSTD_createDCtx();
|
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
|
||||||
size_t const dictSize = 500;
|
static const size_t dictSize = 551;
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : copy context too soon : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : copy context too soon : ", testNb++);
|
||||||
{ size_t const copyResult = ZSTD_copyCCtx(ctxDuplicated, ctxOrig);
|
{ size_t const copyResult = ZSTD_copyCCtx(ctxDuplicated, ctxOrig);
|
||||||
if (!ZSTD_isError(copyResult)) goto _output_error; } /* error should be detected */
|
if (!ZSTD_isError(copyResult)) goto _output_error; } /* error must be detected */
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : load dictionary into context : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : load dictionary into context : ", testNb++);
|
||||||
{ size_t const initResult = ZSTD_compressBegin_usingDict(ctxOrig, CNBuffer, dictSize, 2);
|
CHECK( ZSTD_compressBegin_usingDict(ctxOrig, CNBuffer, dictSize, 2) );
|
||||||
if (ZSTD_isError(initResult)) goto _output_error; }
|
CHECK( ZSTD_copyCCtx(ctxDuplicated, ctxOrig) );
|
||||||
{ size_t const copyResult = ZSTD_copyCCtx(ctxDuplicated, ctxOrig);
|
|
||||||
if (ZSTD_isError(copyResult)) goto _output_error; }
|
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : compress with dictionary : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : compress with flat dictionary : ", testNb++);
|
||||||
cSize = 0;
|
cSize = 0;
|
||||||
result = ZSTD_compressContinue(ctxOrig, compressedBuffer, ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH), (const char*)CNBuffer + dictSize, COMPRESSIBLE_NOISE_LENGTH - dictSize);
|
CHECKPLUS(r, ZSTD_compressContinue(ctxOrig, compressedBuffer, ZSTD_compressBound(CNBuffSize),
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
(const char*)CNBuffer + dictSize, CNBuffSize - dictSize),
|
||||||
cSize += result;
|
cSize += r);
|
||||||
result = ZSTD_compressEnd(ctxOrig, (char*)compressedBuffer+cSize, ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH)-cSize);
|
CHECKPLUS(r, ZSTD_compressEnd(ctxOrig, (char*)compressedBuffer+cSize, ZSTD_compressBound(CNBuffSize)-cSize),
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
cSize += r);
|
||||||
cSize += result;
|
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100);
|
||||||
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/COMPRESSIBLE_NOISE_LENGTH*100);
|
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : frame built with dictionary should be decompressible : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : frame built with flat dictionary should be decompressible : ", testNb++);
|
||||||
result = ZSTD_decompress_usingDict(dctx,
|
CHECKPLUS(r, ZSTD_decompress_usingDict(dctx,
|
||||||
decodedBuffer, COMPRESSIBLE_NOISE_LENGTH,
|
decodedBuffer, CNBuffSize,
|
||||||
compressedBuffer, cSize,
|
compressedBuffer, cSize,
|
||||||
CNBuffer, dictSize);
|
CNBuffer, dictSize),
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
if (r != CNBuffSize - dictSize) goto _output_error);
|
||||||
if (result != COMPRESSIBLE_NOISE_LENGTH - dictSize) goto _output_error;
|
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : compress with duplicated context : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : compress with duplicated context : ", testNb++);
|
||||||
{ size_t const cSizeOrig = cSize;
|
{ size_t const cSizeOrig = cSize;
|
||||||
cSize = 0;
|
cSize = 0;
|
||||||
result = ZSTD_compressContinue(ctxDuplicated, compressedBuffer, ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH), (const char*)CNBuffer + dictSize, COMPRESSIBLE_NOISE_LENGTH - dictSize);
|
CHECKPLUS(r, ZSTD_compressContinue(ctxDuplicated, compressedBuffer, ZSTD_compressBound(CNBuffSize),
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
(const char*)CNBuffer + dictSize, CNBuffSize - dictSize),
|
||||||
cSize += result;
|
cSize += r);
|
||||||
result = ZSTD_compressEnd(ctxDuplicated, (char*)compressedBuffer+cSize, ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH)-cSize);
|
CHECKPLUS(r, ZSTD_compressEnd(ctxDuplicated, (char*)compressedBuffer+cSize, ZSTD_compressBound(CNBuffSize)-cSize),
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
cSize += r);
|
||||||
cSize += result;
|
if (cSize != cSizeOrig) goto _output_error; /* should be identical ==> have same size */
|
||||||
if (cSize != cSizeOrig) goto _output_error; /* should be identical == have same size */
|
|
||||||
}
|
}
|
||||||
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/COMPRESSIBLE_NOISE_LENGTH*100);
|
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100);
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : frame built with duplicated context should be decompressible : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : frame built with duplicated context should be decompressible : ", testNb++);
|
||||||
result = ZSTD_decompress_usingDict(dctx,
|
CHECKPLUS(r, ZSTD_decompress_usingDict(dctx,
|
||||||
decodedBuffer, COMPRESSIBLE_NOISE_LENGTH,
|
decodedBuffer, CNBuffSize,
|
||||||
compressedBuffer, cSize,
|
compressedBuffer, cSize,
|
||||||
CNBuffer, dictSize);
|
CNBuffer, dictSize),
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
if (r != CNBuffSize - dictSize) goto _output_error);
|
||||||
if (result != COMPRESSIBLE_NOISE_LENGTH - dictSize) goto _output_error;
|
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : check content size on duplicated context : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : check content size on duplicated context : ", testNb++);
|
||||||
{ size_t const testSize = COMPRESSIBLE_NOISE_LENGTH / 3;
|
{ size_t const testSize = CNBuffSize / 3;
|
||||||
{ ZSTD_parameters p;
|
{ ZSTD_compressionParameters const cPar = ZSTD_getCParams(2, testSize, dictSize);
|
||||||
p.cParams = ZSTD_getCParams(2, testSize, dictSize);
|
ZSTD_frameParameters const fPar = { 1 , 0 , 0 };
|
||||||
p.fParams.contentSizeFlag = 1;
|
ZSTD_parameters p;
|
||||||
{ size_t const initResult = ZSTD_compressBegin_advanced(ctxOrig, CNBuffer, dictSize, p, testSize-1);
|
p.cParams = cPar; p.fParams = fPar;
|
||||||
if (ZSTD_isError(initResult)) goto _output_error;
|
CHECK( ZSTD_compressBegin_advanced(ctxOrig, CNBuffer, dictSize, p, testSize-1) );
|
||||||
} }
|
}
|
||||||
{ size_t const copyResult = ZSTD_copyCCtx(ctxDuplicated, ctxOrig);
|
CHECK( ZSTD_copyCCtx(ctxDuplicated, ctxOrig) );
|
||||||
if (ZSTD_isError(copyResult)) goto _output_error; }
|
|
||||||
cSize = ZSTD_compressContinue(ctxDuplicated, compressedBuffer, ZSTD_compressBound(testSize), (const char*)CNBuffer + dictSize, COMPRESSIBLE_NOISE_LENGTH - dictSize);
|
CHECKPLUS(r, ZSTD_compressContinue(ctxDuplicated, compressedBuffer, ZSTD_compressBound(testSize),
|
||||||
if (ZSTD_isError(cSize)) goto _output_error;
|
(const char*)CNBuffer + dictSize, CNBuffSize - dictSize),
|
||||||
|
cSize = r);
|
||||||
{ ZSTD_frameParams fp;
|
{ ZSTD_frameParams fp;
|
||||||
size_t const gfpResult = ZSTD_getFrameParams(&fp, compressedBuffer, cSize);
|
if (ZSTD_getFrameParams(&fp, compressedBuffer, cSize)) goto _output_error;
|
||||||
if (gfpResult!=0) goto _output_error;
|
|
||||||
if ((fp.frameContentSize != testSize) && (fp.frameContentSize != 0)) goto _output_error;
|
if ((fp.frameContentSize != testSize) && (fp.frameContentSize != 0)) goto _output_error;
|
||||||
} }
|
} }
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
@@ -252,55 +238,113 @@ static int basicUnitTests(U32 seed, double compressibility)
|
|||||||
ZSTD_freeDCtx(dctx);
|
ZSTD_freeDCtx(dctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Dictionary and dictBuilder tests */
|
||||||
|
{ ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
||||||
|
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
|
||||||
|
size_t dictSize = 16 KB;
|
||||||
|
void* dictBuffer = malloc(dictSize);
|
||||||
|
size_t const totalSampleSize = 1 MB;
|
||||||
|
size_t const sampleUnitSize = 8 KB;
|
||||||
|
U32 const nbSamples = (U32)(totalSampleSize / sampleUnitSize);
|
||||||
|
size_t* const samplesSizes = (size_t*) malloc(nbSamples * sizeof(size_t));
|
||||||
|
|
||||||
|
if (dictBuffer==NULL || samplesSizes==NULL) {
|
||||||
|
free(dictBuffer);
|
||||||
|
free(samplesSizes);
|
||||||
|
goto _output_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
DISPLAYLEVEL(4, "test%3i : dictBuilder : ", testNb++);
|
||||||
|
{ U32 u; for (u=0; u<nbSamples; u++) samplesSizes[u] = sampleUnitSize; }
|
||||||
|
dictSize = ZDICT_trainFromBuffer(dictBuffer, dictSize,
|
||||||
|
CNBuffer, samplesSizes, nbSamples);
|
||||||
|
if (ZDICT_isError(dictSize)) goto _output_error;
|
||||||
|
DISPLAYLEVEL(4, "OK, created dictionary of size %u \n", (U32)dictSize);
|
||||||
|
|
||||||
|
DISPLAYLEVEL(4, "test%3i : compress with dictionary : ", testNb++);
|
||||||
|
cSize = ZSTD_compress_usingDict(cctx, compressedBuffer, ZSTD_compressBound(CNBuffSize),
|
||||||
|
CNBuffer, CNBuffSize,
|
||||||
|
dictBuffer, dictSize, 4);
|
||||||
|
if (ZSTD_isError(cSize)) goto _output_error;
|
||||||
|
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100);
|
||||||
|
|
||||||
|
DISPLAYLEVEL(4, "test%3i : frame built with dictionary should be decompressible : ", testNb++);
|
||||||
|
CHECKPLUS(r, ZSTD_decompress_usingDict(dctx,
|
||||||
|
decodedBuffer, CNBuffSize,
|
||||||
|
compressedBuffer, cSize,
|
||||||
|
dictBuffer, dictSize),
|
||||||
|
if (r != CNBuffSize) goto _output_error);
|
||||||
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
|
DISPLAYLEVEL(4, "test%3i : compress without dictID : ", testNb++);
|
||||||
|
{ ZSTD_frameParameters const fParams = { 0 /*contentSize*/, 0 /*checksum*/, 1 /*NoDictID*/ };
|
||||||
|
ZSTD_compressionParameters const cParams = ZSTD_getCParams(3, CNBuffSize, dictSize);
|
||||||
|
ZSTD_parameters p;
|
||||||
|
p.cParams = cParams; p.fParams = fParams;
|
||||||
|
cSize = ZSTD_compress_advanced(cctx, compressedBuffer, ZSTD_compressBound(CNBuffSize),
|
||||||
|
CNBuffer, CNBuffSize,
|
||||||
|
dictBuffer, dictSize, p);
|
||||||
|
if (ZSTD_isError(cSize)) goto _output_error;
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100);
|
||||||
|
|
||||||
|
DISPLAYLEVEL(4, "test%3i : frame built without dictID should be decompressible : ", testNb++);
|
||||||
|
CHECKPLUS(r, ZSTD_decompress_usingDict(dctx,
|
||||||
|
decodedBuffer, CNBuffSize,
|
||||||
|
compressedBuffer, cSize,
|
||||||
|
dictBuffer, dictSize),
|
||||||
|
if (r != CNBuffSize) goto _output_error);
|
||||||
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
|
ZSTD_freeCCtx(cctx);
|
||||||
|
ZSTD_freeDCtx(dctx);
|
||||||
|
free(dictBuffer);
|
||||||
|
free(samplesSizes);
|
||||||
|
}
|
||||||
|
|
||||||
/* Decompression defense tests */
|
/* Decompression defense tests */
|
||||||
DISPLAYLEVEL(4, "test%3i : Check input length for magic number : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : Check input length for magic number : ", testNb++);
|
||||||
result = ZSTD_decompress(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, CNBuffer, 3);
|
{ size_t const r = ZSTD_decompress(decodedBuffer, CNBuffSize, CNBuffer, 3);
|
||||||
if (!ZSTD_isError(result)) goto _output_error;
|
if (!ZSTD_isError(r)) goto _output_error;
|
||||||
if (result != (size_t)-ZSTD_error_srcSize_wrong) goto _output_error;
|
if (r != (size_t)-ZSTD_error_srcSize_wrong) goto _output_error; }
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : Check magic Number : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : Check magic Number : ", testNb++);
|
||||||
((char*)(CNBuffer))[0] = 1;
|
((char*)(CNBuffer))[0] = 1;
|
||||||
result = ZSTD_decompress(decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, CNBuffer, 4);
|
{ size_t const r = ZSTD_decompress(decodedBuffer, CNBuffSize, CNBuffer, 4);
|
||||||
if (!ZSTD_isError(result)) goto _output_error;
|
if (!ZSTD_isError(r)) goto _output_error; }
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
/* block API tests */
|
/* block API tests */
|
||||||
{ ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
{ ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
||||||
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
|
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
|
||||||
const size_t blockSize = 100 KB;
|
static const size_t blockSize = 100 KB;
|
||||||
const size_t dictSize = 16 KB;
|
static const size_t dictSize = 16 KB;
|
||||||
|
|
||||||
/* basic block compression */
|
/* basic block compression */
|
||||||
DISPLAYLEVEL(4, "test%3i : Block compression test : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : Block compression test : ", testNb++);
|
||||||
result = ZSTD_compressBegin(cctx, 5);
|
CHECK( ZSTD_compressBegin(cctx, 5) );
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
|
||||||
cSize = ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), CNBuffer, blockSize);
|
cSize = ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), CNBuffer, blockSize);
|
||||||
if (ZSTD_isError(cSize)) goto _output_error;
|
if (ZSTD_isError(cSize)) goto _output_error;
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : Block decompression test : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : Block decompression test : ", testNb++);
|
||||||
result = ZSTD_decompressBegin(dctx);
|
CHECK( ZSTD_decompressBegin(dctx) );
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
{ CHECKTEST(r, ZSTD_decompressBlock(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize) );
|
||||||
result = ZSTD_decompressBlock(dctx, decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, compressedBuffer, cSize);
|
if (r != blockSize) goto _output_error; }
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
|
||||||
if (result != blockSize) goto _output_error;
|
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
/* dictionary block compression */
|
/* dictionary block compression */
|
||||||
DISPLAYLEVEL(4, "test%3i : Dictionary Block compression test : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : Dictionary Block compression test : ", testNb++);
|
||||||
result = ZSTD_compressBegin_usingDict(cctx, CNBuffer, dictSize, 5);
|
CHECK( ZSTD_compressBegin_usingDict(cctx, CNBuffer, dictSize, 5) );
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
|
||||||
cSize = ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize, blockSize);
|
cSize = ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize, blockSize);
|
||||||
if (ZSTD_isError(cSize)) goto _output_error;
|
if (ZSTD_isError(cSize)) goto _output_error;
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : Dictionary Block decompression test : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : Dictionary Block decompression test : ", testNb++);
|
||||||
result = ZSTD_decompressBegin_usingDict(dctx, CNBuffer, dictSize);
|
CHECK( ZSTD_decompressBegin_usingDict(dctx, CNBuffer, dictSize) );
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
{ CHECKTEST( r, ZSTD_decompressBlock(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize) );
|
||||||
result = ZSTD_decompressBlock(dctx, decodedBuffer, COMPRESSIBLE_NOISE_LENGTH, compressedBuffer, cSize);
|
if (r != blockSize) goto _output_error; }
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
|
||||||
if (result != blockSize) goto _output_error;
|
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
ZSTD_freeCCtx(cctx);
|
ZSTD_freeCCtx(cctx);
|
||||||
@@ -310,32 +354,29 @@ static int basicUnitTests(U32 seed, double compressibility)
|
|||||||
/* long rle test */
|
/* long rle test */
|
||||||
{ size_t sampleSize = 0;
|
{ size_t sampleSize = 0;
|
||||||
DISPLAYLEVEL(4, "test%3i : Long RLE test : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : Long RLE test : ", testNb++);
|
||||||
RDG_genBuffer(CNBuffer, sampleSize, compressibility, 0., randState);
|
RDG_genBuffer(CNBuffer, sampleSize, compressibility, 0., seed+1);
|
||||||
memset((char*)CNBuffer+sampleSize, 'B', 256 KB - 1);
|
memset((char*)CNBuffer+sampleSize, 'B', 256 KB - 1);
|
||||||
sampleSize += 256 KB - 1;
|
sampleSize += 256 KB - 1;
|
||||||
RDG_genBuffer((char*)CNBuffer+sampleSize, 96 KB, compressibility, 0., randState);
|
RDG_genBuffer((char*)CNBuffer+sampleSize, 96 KB, compressibility, 0., seed+2);
|
||||||
sampleSize += 96 KB;
|
sampleSize += 96 KB;
|
||||||
cSize = ZSTD_compress(compressedBuffer, ZSTD_compressBound(sampleSize), CNBuffer, sampleSize, 1);
|
cSize = ZSTD_compress(compressedBuffer, ZSTD_compressBound(sampleSize), CNBuffer, sampleSize, 1);
|
||||||
if (ZSTD_isError(cSize)) goto _output_error;
|
if (ZSTD_isError(cSize)) goto _output_error;
|
||||||
result = ZSTD_decompress(decodedBuffer, sampleSize, compressedBuffer, cSize);
|
{ CHECKTEST(regenSize, ZSTD_decompress(decodedBuffer, sampleSize, compressedBuffer, cSize));
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
if (regenSize!=sampleSize) goto _output_error; }
|
||||||
if (result!=sampleSize) goto _output_error;
|
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All zeroes test (#137 verif) */
|
/* All zeroes test (test bug #137) */
|
||||||
#define ZEROESLENGTH 100
|
#define ZEROESLENGTH 100
|
||||||
DISPLAYLEVEL(4, "test%3i : compress %u zeroes : ", testNb++, ZEROESLENGTH);
|
DISPLAYLEVEL(4, "test%3i : compress %u zeroes : ", testNb++, ZEROESLENGTH);
|
||||||
memset(CNBuffer, 0, ZEROESLENGTH);
|
memset(CNBuffer, 0, ZEROESLENGTH);
|
||||||
result = ZSTD_compress(compressedBuffer, ZSTD_compressBound(ZEROESLENGTH), CNBuffer, ZEROESLENGTH, 1);
|
{ CHECKTEST(r, ZSTD_compress(compressedBuffer, ZSTD_compressBound(ZEROESLENGTH), CNBuffer, ZEROESLENGTH, 1) );
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
cSize = r; }
|
||||||
cSize = result;
|
|
||||||
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/ZEROESLENGTH*100);
|
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/ZEROESLENGTH*100);
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : decompress %u zeroes : ", testNb++, ZEROESLENGTH);
|
DISPLAYLEVEL(4, "test%3i : decompress %u zeroes : ", testNb++, ZEROESLENGTH);
|
||||||
result = ZSTD_decompress(decodedBuffer, ZEROESLENGTH, compressedBuffer, cSize);
|
{ CHECKTEST(r, ZSTD_decompress(decodedBuffer, ZEROESLENGTH, compressedBuffer, cSize) );
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
if (r != ZEROESLENGTH) goto _output_error; }
|
||||||
if (result != ZEROESLENGTH) goto _output_error;
|
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
/* nbSeq limit test */
|
/* nbSeq limit test */
|
||||||
@@ -355,23 +396,21 @@ static int basicUnitTests(U32 seed, double compressibility)
|
|||||||
}}
|
}}
|
||||||
|
|
||||||
/* randomly fills CNBuffer with prepared 3-bytes sequences */
|
/* randomly fills CNBuffer with prepared 3-bytes sequences */
|
||||||
{ int i; for (i=0; i < _3BYTESTESTLENGTH; ) { /* note : CNBuffer size > _3BYTESTESTLENGTH+3 */
|
{ int i; for (i=0; i < _3BYTESTESTLENGTH; i += 3) { /* note : CNBuffer size > _3BYTESTESTLENGTH+3 */
|
||||||
U32 id = FUZ_rand(&rSeed) & NB3BYTESSEQMASK;
|
U32 const id = FUZ_rand(&rSeed) & NB3BYTESSEQMASK;
|
||||||
((BYTE*)CNBuffer)[i+0] = _3BytesSeqs[id][0];
|
((BYTE*)CNBuffer)[i+0] = _3BytesSeqs[id][0];
|
||||||
((BYTE*)CNBuffer)[i+1] = _3BytesSeqs[id][1];
|
((BYTE*)CNBuffer)[i+1] = _3BytesSeqs[id][1];
|
||||||
((BYTE*)CNBuffer)[i+2] = _3BytesSeqs[id][2];
|
((BYTE*)CNBuffer)[i+2] = _3BytesSeqs[id][2];
|
||||||
i += 3;
|
|
||||||
} }}
|
} }}
|
||||||
DISPLAYLEVEL(4, "test%3i : compress lots 3-bytes sequences : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : compress lots 3-bytes sequences : ", testNb++);
|
||||||
result = ZSTD_compress(compressedBuffer, ZSTD_compressBound(_3BYTESTESTLENGTH), CNBuffer, _3BYTESTESTLENGTH, 19);
|
{ CHECKTEST(r, ZSTD_compress(compressedBuffer, ZSTD_compressBound(_3BYTESTESTLENGTH),
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
CNBuffer, _3BYTESTESTLENGTH, 19) );
|
||||||
cSize = result;
|
cSize = r; }
|
||||||
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/_3BYTESTESTLENGTH*100);
|
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/_3BYTESTESTLENGTH*100);
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : decompress lots 3-bytes sequence : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : decompress lots 3-bytes sequence : ", testNb++);
|
||||||
result = ZSTD_decompress(decodedBuffer, _3BYTESTESTLENGTH, compressedBuffer, cSize);
|
{ CHECKTEST(r, ZSTD_decompress(decodedBuffer, _3BYTESTESTLENGTH, compressedBuffer, cSize) );
|
||||||
if (ZSTD_isError(result)) goto _output_error;
|
if (r != _3BYTESTESTLENGTH) goto _output_error; }
|
||||||
if (result != _3BYTESTESTLENGTH) goto _output_error;
|
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
_end:
|
_end:
|
||||||
@@ -391,11 +430,11 @@ static size_t findDiff(const void* buf1, const void* buf2, size_t max)
|
|||||||
{
|
{
|
||||||
const BYTE* b1 = (const BYTE*)buf1;
|
const BYTE* b1 = (const BYTE*)buf1;
|
||||||
const BYTE* b2 = (const BYTE*)buf2;
|
const BYTE* b2 = (const BYTE*)buf2;
|
||||||
size_t i;
|
size_t u;
|
||||||
for (i=0; i<max; i++) {
|
for (u=0; u<max; u++) {
|
||||||
if (b1[i] != b2[i]) break;
|
if (b1[u] != b2[u]) break;
|
||||||
}
|
}
|
||||||
return i;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -411,6 +450,7 @@ static size_t FUZ_randomLength(U32* seed, U32 maxLog)
|
|||||||
return FUZ_rLogLength(seed, logLength);
|
return FUZ_rLogLength(seed, logLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef CHECK
|
||||||
#define CHECK(cond, ...) if (cond) { DISPLAY("Error => "); DISPLAY(__VA_ARGS__); \
|
#define CHECK(cond, ...) if (cond) { DISPLAY("Error => "); DISPLAY(__VA_ARGS__); \
|
||||||
DISPLAY(" (seed %u, test nb %u) \n", seed, testNb); goto _output_error; }
|
DISPLAY(" (seed %u, test nb %u) \n", seed, testNb); goto _output_error; }
|
||||||
|
|
||||||
@@ -418,35 +458,29 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
|
|||||||
{
|
{
|
||||||
static const U32 maxSrcLog = 23;
|
static const U32 maxSrcLog = 23;
|
||||||
static const U32 maxSampleLog = 22;
|
static const U32 maxSampleLog = 22;
|
||||||
|
size_t const srcBufferSize = (size_t)1<<maxSrcLog;
|
||||||
|
size_t const dstBufferSize = (size_t)1<<maxSampleLog;
|
||||||
|
size_t const cBufferSize = ZSTD_compressBound(dstBufferSize);
|
||||||
BYTE* cNoiseBuffer[5];
|
BYTE* cNoiseBuffer[5];
|
||||||
BYTE* srcBuffer;
|
BYTE* srcBuffer; /* jumping pointer */
|
||||||
BYTE* cBuffer;
|
BYTE* const cBuffer = (BYTE*) malloc (cBufferSize);
|
||||||
BYTE* dstBuffer;
|
BYTE* const dstBuffer = (BYTE*) malloc (dstBufferSize);
|
||||||
BYTE* mirrorBuffer;
|
BYTE* const mirrorBuffer = (BYTE*) malloc (dstBufferSize);
|
||||||
size_t srcBufferSize = (size_t)1<<maxSrcLog;
|
ZSTD_CCtx* const refCtx = ZSTD_createCCtx();
|
||||||
size_t dstBufferSize = (size_t)1<<maxSampleLog;
|
ZSTD_CCtx* const ctx = ZSTD_createCCtx();
|
||||||
size_t cBufferSize = ZSTD_compressBound(dstBufferSize);
|
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
|
||||||
U32 result = 0;
|
U32 result = 0;
|
||||||
U32 testNb = 0;
|
U32 testNb = 0;
|
||||||
U32 coreSeed = seed, lseed = 0;
|
U32 coreSeed = seed, lseed = 0;
|
||||||
ZSTD_CCtx* refCtx;
|
clock_t const startClock = clock();
|
||||||
ZSTD_CCtx* ctx;
|
|
||||||
ZSTD_DCtx* dctx;
|
|
||||||
clock_t startClock = clock();
|
|
||||||
clock_t const maxClockSpan = maxDurationS * CLOCKS_PER_SEC;
|
clock_t const maxClockSpan = maxDurationS * CLOCKS_PER_SEC;
|
||||||
|
|
||||||
/* allocation */
|
/* allocation */
|
||||||
refCtx = 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);
|
|
||||||
mirrorBuffer = (BYTE*)malloc (dstBufferSize);
|
|
||||||
cBuffer = (BYTE*)malloc (cBufferSize);
|
|
||||||
CHECK (!cNoiseBuffer[0] || !cNoiseBuffer[1] || !cNoiseBuffer[2] || !cNoiseBuffer[3] || !cNoiseBuffer[4]
|
CHECK (!cNoiseBuffer[0] || !cNoiseBuffer[1] || !cNoiseBuffer[2] || !cNoiseBuffer[3] || !cNoiseBuffer[4]
|
||||||
|| !dstBuffer || !mirrorBuffer || !cBuffer || !refCtx || !ctx || !dctx,
|
|| !dstBuffer || !mirrorBuffer || !cBuffer || !refCtx || !ctx || !dctx,
|
||||||
"Not enough memory, fuzzer tests cancelled");
|
"Not enough memory, fuzzer tests cancelled");
|
||||||
@@ -464,10 +498,9 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
|
|||||||
|
|
||||||
/* main test loop */
|
/* main test loop */
|
||||||
for ( ; (testNb <= nbTests) || (FUZ_clockSpan(startClock) < maxClockSpan); testNb++ ) {
|
for ( ; (testNb <= nbTests) || (FUZ_clockSpan(startClock) < maxClockSpan); testNb++ ) {
|
||||||
size_t sampleSize, sampleStart, maxTestSize, totalTestSize;
|
size_t sampleSize, maxTestSize, totalTestSize;
|
||||||
size_t cSize, dSize, totalCSize, totalGenSize;
|
size_t cSize, totalCSize, totalGenSize;
|
||||||
U32 sampleSizeLog, nbChunks, n;
|
XXH64_state_t xxhState;
|
||||||
XXH64_CREATESTATE_STATIC(xxh64);
|
|
||||||
U64 crcOrig;
|
U64 crcOrig;
|
||||||
BYTE* sampleBuffer;
|
BYTE* sampleBuffer;
|
||||||
const BYTE* dict;
|
const BYTE* dict;
|
||||||
@@ -496,18 +529,17 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* select src segment */
|
/* select src segment */
|
||||||
sampleSizeLog = FUZ_rand(&lseed) % maxSampleLog;
|
sampleSize = FUZ_randomLength(&lseed, maxSampleLog);
|
||||||
sampleSize = FUZ_rLogLength(&lseed, sampleSizeLog);
|
|
||||||
sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);
|
|
||||||
|
|
||||||
/* create sample buffer (to catch read error with valgrind & sanitizers) */
|
/* create sample buffer (to catch read error with valgrind & sanitizers) */
|
||||||
sampleBuffer = (BYTE*)malloc(sampleSize);
|
sampleBuffer = (BYTE*)malloc(sampleSize);
|
||||||
CHECK (sampleBuffer==NULL, "not enough memory for sample buffer");
|
CHECK(sampleBuffer==NULL, "not enough memory for sample buffer");
|
||||||
memcpy(sampleBuffer, srcBuffer + sampleStart, sampleSize);
|
{ size_t const sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);
|
||||||
|
memcpy(sampleBuffer, srcBuffer + sampleStart, sampleSize); }
|
||||||
crcOrig = XXH64(sampleBuffer, sampleSize, 0);
|
crcOrig = XXH64(sampleBuffer, sampleSize, 0);
|
||||||
|
|
||||||
/* compression tests */
|
/* compression tests */
|
||||||
{ int const cLevel = (FUZ_rand(&lseed) % (ZSTD_maxCLevel() - (sampleSizeLog/3))) + 1;
|
{ unsigned const cLevel = (FUZ_rand(&lseed) % (ZSTD_maxCLevel() - (FUZ_highbit32((U32)sampleSize)/3))) + 1;
|
||||||
cSize = ZSTD_compressCCtx(ctx, cBuffer, cBufferSize, sampleBuffer, sampleSize, cLevel);
|
cSize = ZSTD_compressCCtx(ctx, cBuffer, cBufferSize, sampleBuffer, sampleSize, cLevel);
|
||||||
CHECK(ZSTD_isError(cSize), "ZSTD_compressCCtx failed");
|
CHECK(ZSTD_isError(cSize), "ZSTD_compressCCtx failed");
|
||||||
|
|
||||||
@@ -521,9 +553,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
|
|||||||
CHECK(!ZSTD_isError(errorCode), "ZSTD_compressCCtx should have failed ! (buffer too small : %u < %u)", (U32)tooSmallSize, (U32)cSize); }
|
CHECK(!ZSTD_isError(errorCode), "ZSTD_compressCCtx should have failed ! (buffer too small : %u < %u)", (U32)tooSmallSize, (U32)cSize); }
|
||||||
{ U32 endCheck; memcpy(&endCheck, dstBuffer+tooSmallSize, 4);
|
{ U32 endCheck; memcpy(&endCheck, dstBuffer+tooSmallSize, 4);
|
||||||
CHECK(endCheck != endMark, "ZSTD_compressCCtx : dst buffer overflow"); }
|
CHECK(endCheck != endMark, "ZSTD_compressCCtx : dst buffer overflow"); }
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* frame header decompression test */
|
/* frame header decompression test */
|
||||||
{ ZSTD_frameParams dParams;
|
{ ZSTD_frameParams dParams;
|
||||||
@@ -534,7 +564,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
|
|||||||
|
|
||||||
/* successful decompression test */
|
/* successful decompression test */
|
||||||
{ size_t const margin = (FUZ_rand(&lseed) & 1) ? 0 : (FUZ_rand(&lseed) & 31) + 1;
|
{ size_t const margin = (FUZ_rand(&lseed) & 1) ? 0 : (FUZ_rand(&lseed) & 31) + 1;
|
||||||
dSize = ZSTD_decompress(dstBuffer, sampleSize + margin, cBuffer, cSize);
|
size_t const dSize = ZSTD_decompress(dstBuffer, sampleSize + margin, cBuffer, cSize);
|
||||||
CHECK(dSize != sampleSize, "ZSTD_decompress failed (%s) (srcSize : %u ; cSize : %u)", ZSTD_getErrorName(dSize), (U32)sampleSize, (U32)cSize);
|
CHECK(dSize != sampleSize, "ZSTD_decompress failed (%s) (srcSize : %u ; cSize : %u)", ZSTD_getErrorName(dSize), (U32)sampleSize, (U32)cSize);
|
||||||
{ U64 const crcDest = XXH64(dstBuffer, sampleSize, 0);
|
{ U64 const crcDest = XXH64(dstBuffer, sampleSize, 0);
|
||||||
CHECK(crcOrig != crcDest, "decompression result corrupted (pos %u / %u)", (U32)findDiff(sampleBuffer, dstBuffer, sampleSize), (U32)sampleSize);
|
CHECK(crcOrig != crcDest, "decompression result corrupted (pos %u / %u)", (U32)findDiff(sampleBuffer, dstBuffer, sampleSize), (U32)sampleSize);
|
||||||
@@ -545,7 +575,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
|
|||||||
/* truncated src decompression test */
|
/* truncated src decompression test */
|
||||||
{ size_t const missing = (FUZ_rand(&lseed) % (cSize-2)) + 1; /* no problem, as cSize > 4 (frameHeaderSizer) */
|
{ size_t const missing = (FUZ_rand(&lseed) % (cSize-2)) + 1; /* no problem, as cSize > 4 (frameHeaderSizer) */
|
||||||
size_t const tooSmallSize = cSize - missing;
|
size_t const tooSmallSize = cSize - missing;
|
||||||
void* cBufferTooSmall = malloc(tooSmallSize); /* valgrind will catch overflows */
|
void* cBufferTooSmall = malloc(tooSmallSize); /* valgrind will catch read overflows */
|
||||||
CHECK(cBufferTooSmall == NULL, "not enough memory !");
|
CHECK(cBufferTooSmall == NULL, "not enough memory !");
|
||||||
memcpy(cBufferTooSmall, cBuffer, tooSmallSize);
|
memcpy(cBufferTooSmall, cBuffer, tooSmallSize);
|
||||||
{ size_t const errorCode = ZSTD_decompress(dstBuffer, dstBufferSize, cBufferTooSmall, tooSmallSize);
|
{ size_t const errorCode = ZSTD_decompress(dstBuffer, dstBufferSize, cBufferTooSmall, tooSmallSize);
|
||||||
@@ -578,13 +608,12 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
|
|||||||
}
|
}
|
||||||
if (pos <= cSize) break;
|
if (pos <= cSize) break;
|
||||||
/* add noise */
|
/* add noise */
|
||||||
{ U32 nbBits = FUZ_rand(&lseed) % maxNbBits;
|
{ U32 const nbBitsCodes = FUZ_rand(&lseed) % maxNbBits;
|
||||||
size_t mask, noiseStart, noiseLength;
|
U32 const nbBits = nbBitsCodes ? nbBitsCodes-1 : 0;
|
||||||
if (nbBits>0) nbBits--;
|
size_t const mask = (1<<nbBits) - 1;
|
||||||
mask = (1<<nbBits) - 1;
|
size_t const rNoiseLength = (FUZ_rand(&lseed) & mask) + 1;
|
||||||
noiseLength = (FUZ_rand(&lseed) & mask) + 1;
|
size_t const noiseLength = MIN(rNoiseLength, cSize-pos);
|
||||||
if ( pos+noiseLength > cSize ) noiseLength = cSize-pos;
|
size_t const noiseStart = FUZ_rand(&lseed) % (srcBufferSize - noiseLength);
|
||||||
noiseStart = FUZ_rand(&lseed) % (srcBufferSize - noiseLength);
|
|
||||||
memcpy(cBuffer + pos, srcBuffer + noiseStart, noiseLength);
|
memcpy(cBuffer + pos, srcBuffer + noiseStart, noiseLength);
|
||||||
pos += noiseLength;
|
pos += noiseLength;
|
||||||
} } }
|
} } }
|
||||||
@@ -608,44 +637,55 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
|
|||||||
maxTestSize = FUZ_rLogLength(&lseed, testLog);
|
maxTestSize = FUZ_rLogLength(&lseed, testLog);
|
||||||
if (maxTestSize >= dstBufferSize) maxTestSize = dstBufferSize-1;
|
if (maxTestSize >= dstBufferSize) maxTestSize = dstBufferSize-1;
|
||||||
|
|
||||||
sampleSize = FUZ_randomLength(&lseed, maxSampleLog);
|
dictSize = FUZ_randomLength(&lseed, maxSampleLog); /* needed also for decompression */
|
||||||
sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);
|
dict = srcBuffer + (FUZ_rand(&lseed) % (srcBufferSize - dictSize));
|
||||||
dict = srcBuffer + sampleStart;
|
|
||||||
dictSize = sampleSize;
|
|
||||||
|
|
||||||
{ size_t const errorCode = ZSTD_compressBegin_usingDict(refCtx, dict, dictSize, cLevel);
|
if (FUZ_rand(&lseed) & 0xF) {
|
||||||
CHECK (ZSTD_isError(errorCode), "ZSTD_compressBegin_usingDict error : %s", ZSTD_getErrorName(errorCode)); }
|
size_t const errorCode = ZSTD_compressBegin_usingDict(refCtx, dict, dictSize, cLevel);
|
||||||
|
CHECK (ZSTD_isError(errorCode), "ZSTD_compressBegin_usingDict error : %s", ZSTD_getErrorName(errorCode));
|
||||||
|
} else {
|
||||||
|
ZSTD_compressionParameters const cPar = ZSTD_getCParams(cLevel, 0, dictSize);
|
||||||
|
ZSTD_frameParameters const fpar = { FUZ_rand(&lseed)&1 /* contentSizeFlag */,
|
||||||
|
!(FUZ_rand(&lseed)&3) /* contentChecksumFlag*/,
|
||||||
|
0 /*NodictID*/ }; /* note : since dictionary is fake, dictIDflag has no impact */
|
||||||
|
ZSTD_parameters p;
|
||||||
|
size_t errorCode;
|
||||||
|
p.cParams = cPar; p.fParams = fpar;
|
||||||
|
errorCode = ZSTD_compressBegin_advanced(refCtx, dict, dictSize, p, 0);
|
||||||
|
CHECK (ZSTD_isError(errorCode), "ZSTD_compressBegin_advanced error : %s", ZSTD_getErrorName(errorCode));
|
||||||
|
}
|
||||||
{ size_t const errorCode = ZSTD_copyCCtx(ctx, refCtx);
|
{ size_t const errorCode = ZSTD_copyCCtx(ctx, refCtx);
|
||||||
CHECK (ZSTD_isError(errorCode), "ZSTD_copyCCtx error : %s", ZSTD_getErrorName(errorCode)); }
|
CHECK (ZSTD_isError(errorCode), "ZSTD_copyCCtx error : %s", ZSTD_getErrorName(errorCode)); }
|
||||||
}
|
}
|
||||||
XXH64_reset(xxh64, 0);
|
XXH64_reset(&xxhState, 0);
|
||||||
nbChunks = (FUZ_rand(&lseed) & 127) + 2;
|
{ U32 const nbChunks = (FUZ_rand(&lseed) & 127) + 2;
|
||||||
for (totalTestSize=0, cSize=0, n=0 ; n<nbChunks ; n++) {
|
U32 n;
|
||||||
sampleSizeLog = FUZ_rand(&lseed) % maxSampleLog;
|
for (totalTestSize=0, cSize=0, n=0 ; n<nbChunks ; n++) {
|
||||||
sampleSize = (size_t)1 << sampleSizeLog;
|
size_t const segmentSize = FUZ_randomLength(&lseed, maxSampleLog);
|
||||||
sampleSize += FUZ_rand(&lseed) & (sampleSize-1);
|
size_t const segmentStart = FUZ_rand(&lseed) % (srcBufferSize - segmentSize);
|
||||||
sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);
|
|
||||||
|
|
||||||
if (cBufferSize-cSize < ZSTD_compressBound(sampleSize)) break; /* avoid invalid dstBufferTooSmall */
|
if (cBufferSize-cSize < ZSTD_compressBound(segmentSize)) break; /* avoid invalid dstBufferTooSmall */
|
||||||
if (totalTestSize+sampleSize > maxTestSize) break;
|
if (totalTestSize+segmentSize > maxTestSize) break;
|
||||||
|
|
||||||
|
{ size_t const compressResult = ZSTD_compressContinue(ctx, cBuffer+cSize, cBufferSize-cSize, srcBuffer+segmentStart, segmentSize);
|
||||||
|
CHECK (ZSTD_isError(compressResult), "multi-segments compression error : %s", ZSTD_getErrorName(compressResult));
|
||||||
|
cSize += compressResult;
|
||||||
|
}
|
||||||
|
XXH64_update(&xxhState, srcBuffer+segmentStart, segmentSize);
|
||||||
|
memcpy(mirrorBuffer + totalTestSize, srcBuffer+segmentStart, segmentSize);
|
||||||
|
totalTestSize += segmentSize;
|
||||||
|
} }
|
||||||
|
|
||||||
{ size_t const compressResult = ZSTD_compressContinue(ctx, cBuffer+cSize, cBufferSize-cSize, srcBuffer+sampleStart, sampleSize);
|
|
||||||
CHECK (ZSTD_isError(compressResult), "multi-segments compression error : %s", ZSTD_getErrorName(compressResult));
|
|
||||||
cSize += compressResult;
|
|
||||||
}
|
|
||||||
XXH64_update(xxh64, srcBuffer+sampleStart, sampleSize);
|
|
||||||
memcpy(mirrorBuffer + totalTestSize, srcBuffer+sampleStart, sampleSize);
|
|
||||||
totalTestSize += sampleSize;
|
|
||||||
}
|
|
||||||
{ size_t const flushResult = ZSTD_compressEnd(ctx, cBuffer+cSize, cBufferSize-cSize);
|
{ size_t const flushResult = ZSTD_compressEnd(ctx, cBuffer+cSize, cBufferSize-cSize);
|
||||||
CHECK (ZSTD_isError(flushResult), "multi-segments epilogue error : %s", ZSTD_getErrorName(flushResult));
|
CHECK (ZSTD_isError(flushResult), "multi-segments epilogue error : %s", ZSTD_getErrorName(flushResult));
|
||||||
cSize += flushResult;
|
cSize += flushResult;
|
||||||
}
|
}
|
||||||
crcOrig = XXH64_digest(xxh64);
|
crcOrig = XXH64_digest(&xxhState);
|
||||||
|
|
||||||
/* streaming decompression test */
|
/* streaming decompression test */
|
||||||
|
if (dictSize<8) dictSize=0, dict=NULL; /* disable dictionary */
|
||||||
{ size_t const errorCode = ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
|
{ size_t const errorCode = ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
|
||||||
CHECK (ZSTD_isError(errorCode), "cannot init DCtx : %s", ZSTD_getErrorName(errorCode)); }
|
CHECK (ZSTD_isError(errorCode), "ZSTD_decompressBegin_usingDict error : %s", ZSTD_getErrorName(errorCode)); }
|
||||||
totalCSize = 0;
|
totalCSize = 0;
|
||||||
totalGenSize = 0;
|
totalGenSize = 0;
|
||||||
while (totalCSize < cSize) {
|
while (totalCSize < cSize) {
|
||||||
@@ -656,12 +696,12 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
|
|||||||
totalCSize += inSize;
|
totalCSize += inSize;
|
||||||
}
|
}
|
||||||
CHECK (ZSTD_nextSrcSizeToDecompress(dctx) != 0, "frame not fully decoded");
|
CHECK (ZSTD_nextSrcSizeToDecompress(dctx) != 0, "frame not fully decoded");
|
||||||
CHECK (totalGenSize != totalTestSize, "decompressed data : wrong size")
|
CHECK (totalGenSize != totalTestSize, "streaming decompressed data : wrong size")
|
||||||
CHECK (totalCSize != cSize, "compressed data should be fully read")
|
CHECK (totalCSize != cSize, "compressed data should be fully read")
|
||||||
{ U64 const crcDest = XXH64(dstBuffer, totalTestSize, 0);
|
{ U64 const crcDest = XXH64(dstBuffer, totalTestSize, 0);
|
||||||
if (crcDest!=crcOrig) {
|
if (crcDest!=crcOrig) {
|
||||||
size_t const errorPos = findDiff(mirrorBuffer, dstBuffer, totalTestSize);
|
size_t const errorPos = findDiff(mirrorBuffer, dstBuffer, totalTestSize);
|
||||||
CHECK (crcDest!=crcOrig, "streaming decompressed data corrupted : byte %u / %u (%02X!=%02X)",
|
CHECK (1, "streaming decompressed data corrupted : byte %u / %u (%02X!=%02X)",
|
||||||
(U32)errorPos, (U32)totalTestSize, dstBuffer[errorPos], mirrorBuffer[errorPos]);
|
(U32)errorPos, (U32)totalTestSize, dstBuffer[errorPos], mirrorBuffer[errorPos]);
|
||||||
} }
|
} }
|
||||||
} /* for ( ; (testNb <= nbTests) */
|
} /* for ( ; (testNb <= nbTests) */
|
||||||
@@ -805,12 +845,19 @@ int main(int argc, const char** argv)
|
|||||||
} } } } /* for (argNb=1; argNb<argc; argNb++) */
|
} } } } /* for (argNb=1; argNb<argc; argNb++) */
|
||||||
|
|
||||||
/* Get Seed */
|
/* Get Seed */
|
||||||
DISPLAY("Starting zstd tester (%i-bits, %s)\n", (int)(sizeof(size_t)*8), ZSTD_VERSION);
|
DISPLAY("Starting zstd tester (%i-bits, %s)\n", (int)(sizeof(size_t)*8), ZSTD_VERSION_STRING);
|
||||||
|
|
||||||
|
if (!seedset) {
|
||||||
|
time_t const t = time(NULL);
|
||||||
|
U32 const h = XXH32(&t, sizeof(t), 1);
|
||||||
|
seed = h % 10000;
|
||||||
|
}
|
||||||
|
|
||||||
if (!seedset) seed = (U32)(clock() % 10000);
|
|
||||||
DISPLAY("Seed = %u\n", seed);
|
DISPLAY("Seed = %u\n", seed);
|
||||||
if (proba!=FUZ_compressibility_default) DISPLAY("Compressibility : %u%%\n", proba);
|
if (proba!=FUZ_compressibility_default) DISPLAY("Compressibility : %u%%\n", proba);
|
||||||
|
|
||||||
|
if (nbTests < testNb) nbTests = testNb;
|
||||||
|
|
||||||
if (testNb==0)
|
if (testNb==0)
|
||||||
result = basicUnitTests(0, ((double)proba) / 100); /* constant seed for predictability */
|
result = basicUnitTests(0, ((double)proba) / 100); /* constant seed for predictability */
|
||||||
if (!result)
|
if (!result)
|
||||||
|
|||||||
+100
-17
@@ -473,35 +473,118 @@ unsigned long long FIOv05_decompressFrame(dRessv05_t ress,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===== v0.6.x =====*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void* srcBuffer;
|
||||||
|
size_t srcBufferSize;
|
||||||
|
void* dstBuffer;
|
||||||
|
size_t dstBufferSize;
|
||||||
|
const void* dictBuffer;
|
||||||
|
size_t dictBufferSize;
|
||||||
|
ZBUFFv06_DCtx* dctx;
|
||||||
|
} dRessv06_t;
|
||||||
|
|
||||||
|
static dRessv06_t FIOv06_createDResources(void)
|
||||||
|
{
|
||||||
|
dRessv06_t ress;
|
||||||
|
|
||||||
|
/* init */
|
||||||
|
ress.dctx = ZBUFFv06_createDCtx();
|
||||||
|
if (ress.dctx==NULL) EXM_THROW(60, "Can't create ZBUFF decompression context");
|
||||||
|
ress.dictBuffer = NULL; ress.dictBufferSize=0;
|
||||||
|
|
||||||
|
/* Allocate Memory */
|
||||||
|
ress.srcBufferSize = ZBUFFv06_recommendedDInSize();
|
||||||
|
ress.srcBuffer = malloc(ress.srcBufferSize);
|
||||||
|
ress.dstBufferSize = ZBUFFv06_recommendedDOutSize();
|
||||||
|
ress.dstBuffer = malloc(ress.dstBufferSize);
|
||||||
|
if (!ress.srcBuffer || !ress.dstBuffer) EXM_THROW(61, "Allocation error : not enough memory");
|
||||||
|
|
||||||
|
return ress;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIOv06_freeDResources(dRessv06_t ress)
|
||||||
|
{
|
||||||
|
size_t const errorCode = ZBUFFv06_freeDCtx(ress.dctx);
|
||||||
|
if (ZBUFFv06_isError(errorCode)) EXM_THROW(69, "Error : can't free ZBUFF context resource : %s", ZBUFFv06_getErrorName(errorCode));
|
||||||
|
free(ress.srcBuffer);
|
||||||
|
free(ress.dstBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long long FIOv06_decompressFrame(dRessv06_t ress,
|
||||||
|
FILE* foutput, FILE* finput)
|
||||||
|
{
|
||||||
|
U64 frameSize = 0;
|
||||||
|
size_t readSize = 4;
|
||||||
|
|
||||||
|
MEM_writeLE32(ress.srcBuffer, ZSTDv06_MAGICNUMBER);
|
||||||
|
ZBUFFv06_decompressInitDictionary(ress.dctx, ress.dictBuffer, ress.dictBufferSize);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
/* Decode */
|
||||||
|
size_t inSize=readSize, decodedSize=ress.dstBufferSize;
|
||||||
|
size_t toRead = ZBUFFv06_decompressContinue(ress.dctx, ress.dstBuffer, &decodedSize, ress.srcBuffer, &inSize);
|
||||||
|
if (ZBUFFv06_isError(toRead)) EXM_THROW(36, "Decoding error : %s", ZBUFFv06_getErrorName(toRead));
|
||||||
|
readSize -= inSize;
|
||||||
|
|
||||||
|
/* Write block */
|
||||||
|
{ size_t const sizeCheck = fwrite(ress.dstBuffer, 1, decodedSize, foutput);
|
||||||
|
if (sizeCheck != decodedSize) EXM_THROW(37, "Write error : unable to write data block to destination file"); }
|
||||||
|
frameSize += decodedSize;
|
||||||
|
DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)(frameSize>>20) );
|
||||||
|
|
||||||
|
if (toRead == 0) break;
|
||||||
|
if (readSize) EXM_THROW(38, "Decoding error : should consume entire input");
|
||||||
|
|
||||||
|
/* Fill input buffer */
|
||||||
|
if (toRead > ress.srcBufferSize) EXM_THROW(34, "too large block");
|
||||||
|
readSize = fread(ress.srcBuffer, 1, toRead, finput);
|
||||||
|
if (readSize != toRead) EXM_THROW(35, "Read error");
|
||||||
|
}
|
||||||
|
|
||||||
|
return frameSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*===== General legacy dispatcher =====*/
|
/*===== General legacy dispatcher =====*/
|
||||||
|
|
||||||
unsigned long long FIO_decompressLegacyFrame(FILE* foutput, FILE* finput,
|
unsigned long long FIO_decompressLegacyFrame(FILE* foutput, FILE* finput,
|
||||||
const void* dictBuffer, size_t dictSize,
|
const void* dictBuffer, size_t dictSize,
|
||||||
U32 magicNumberLE)
|
U32 magicNumberLE)
|
||||||
{
|
{
|
||||||
switch(magicNumberLE)
|
switch(magicNumberLE)
|
||||||
{
|
{
|
||||||
case ZSTDv01_magicNumberLE :
|
case ZSTDv01_magicNumberLE :
|
||||||
return FIOv01_decompressFrame(foutput, finput);
|
return FIOv01_decompressFrame(foutput, finput);
|
||||||
case ZSTDv02_magicNumber :
|
case ZSTDv02_magicNumber :
|
||||||
return FIOv02_decompressFrame(foutput, finput);
|
return FIOv02_decompressFrame(foutput, finput);
|
||||||
case ZSTDv03_magicNumber :
|
case ZSTDv03_magicNumber :
|
||||||
return FIOv03_decompressFrame(foutput, finput);
|
return FIOv03_decompressFrame(foutput, finput);
|
||||||
case ZSTDv04_magicNumber :
|
case ZSTDv04_magicNumber :
|
||||||
{ dRessv04_t r = FIOv04_createDResources();
|
{ dRessv04_t r = FIOv04_createDResources();
|
||||||
unsigned long long const s = FIOv04_decompressFrame(r, foutput, finput);
|
unsigned long long const s = FIOv04_decompressFrame(r, foutput, finput);
|
||||||
FIOv04_freeDResources(r);
|
FIOv04_freeDResources(r);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
case ZSTDv05_MAGICNUMBER :
|
case ZSTDv05_MAGICNUMBER :
|
||||||
{ dRessv05_t r = FIOv05_createDResources();
|
{ dRessv05_t r = FIOv05_createDResources();
|
||||||
r.dictBuffer = dictBuffer;
|
r.dictBuffer = dictBuffer;
|
||||||
r.dictBufferSize = dictSize;
|
r.dictBufferSize = dictSize;
|
||||||
{ unsigned long long const s = FIOv05_decompressFrame(r, foutput, finput);
|
{ unsigned long long const s = FIOv05_decompressFrame(r, foutput, finput);
|
||||||
FIOv05_freeDResources(r);
|
FIOv05_freeDResources(r);
|
||||||
return s;
|
return s;
|
||||||
} }
|
} }
|
||||||
default :
|
case ZSTDv06_MAGICNUMBER :
|
||||||
return ERROR(prefix_unknown);
|
{ dRessv06_t r = FIOv06_createDResources();
|
||||||
}
|
r.dictBuffer = dictBuffer;
|
||||||
|
r.dictBufferSize = dictSize;
|
||||||
|
{ unsigned long long const s = FIOv06_decompressFrame(r, foutput, finput);
|
||||||
|
FIOv06_freeDResources(r);
|
||||||
|
return s;
|
||||||
|
} }
|
||||||
|
default :
|
||||||
|
return ERROR(prefix_unknown);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-22
@@ -48,7 +48,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "zstd_static.h"
|
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_parameters */
|
||||||
|
#include "zstd.h"
|
||||||
#include "datagen.h"
|
#include "datagen.h"
|
||||||
#include "xxhash.h"
|
#include "xxhash.h"
|
||||||
|
|
||||||
@@ -57,11 +58,8 @@
|
|||||||
* Constants
|
* Constants
|
||||||
**************************************/
|
**************************************/
|
||||||
#define PROGRAM_DESCRIPTION "ZSTD parameters tester"
|
#define PROGRAM_DESCRIPTION "ZSTD parameters tester"
|
||||||
#ifndef ZSTD_VERSION
|
|
||||||
# define ZSTD_VERSION ""
|
|
||||||
#endif
|
|
||||||
#define AUTHOR "Yann Collet"
|
#define AUTHOR "Yann Collet"
|
||||||
#define WELCOME_MESSAGE "*** %s %s %i-bits, by %s (%s) ***\n", PROGRAM_DESCRIPTION, ZSTD_VERSION, (int)(sizeof(void*)*8), AUTHOR, __DATE__
|
#define WELCOME_MESSAGE "*** %s %s %i-bits, by %s (%s) ***\n", PROGRAM_DESCRIPTION, ZSTD_VERSION_STRING, (int)(sizeof(void*)*8), AUTHOR, __DATE__
|
||||||
|
|
||||||
|
|
||||||
#define KB *(1<<10)
|
#define KB *(1<<10)
|
||||||
@@ -603,22 +601,22 @@ static void playAround(FILE* f, winnerInfo_t* winners,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void potentialRandomParams(ZSTD_compressionParameters* p, U32 inverseChance)
|
static ZSTD_compressionParameters randomParams(void)
|
||||||
{
|
{
|
||||||
U32 chance = (FUZ_rand(&g_rand) % (inverseChance+1));
|
ZSTD_compressionParameters p;
|
||||||
U32 validated = 0;
|
U32 validated = 0;
|
||||||
if (!chance)
|
|
||||||
while (!validated) {
|
while (!validated) {
|
||||||
/* totally random entry */
|
/* totally random entry */
|
||||||
p->chainLog = FUZ_rand(&g_rand) % (ZSTD_CHAINLOG_MAX+1 - ZSTD_CHAINLOG_MIN) + ZSTD_CHAINLOG_MIN;
|
p.chainLog = FUZ_rand(&g_rand) % (ZSTD_CHAINLOG_MAX+1 - ZSTD_CHAINLOG_MIN) + ZSTD_CHAINLOG_MIN;
|
||||||
p->hashLog = FUZ_rand(&g_rand) % (ZSTD_HASHLOG_MAX+1 - ZSTD_HASHLOG_MIN) + ZSTD_HASHLOG_MIN;
|
p.hashLog = FUZ_rand(&g_rand) % (ZSTD_HASHLOG_MAX+1 - ZSTD_HASHLOG_MIN) + ZSTD_HASHLOG_MIN;
|
||||||
p->searchLog = FUZ_rand(&g_rand) % (ZSTD_SEARCHLOG_MAX+1 - ZSTD_SEARCHLOG_MIN) + ZSTD_SEARCHLOG_MIN;
|
p.searchLog = FUZ_rand(&g_rand) % (ZSTD_SEARCHLOG_MAX+1 - ZSTD_SEARCHLOG_MIN) + ZSTD_SEARCHLOG_MIN;
|
||||||
p->windowLog = FUZ_rand(&g_rand) % (ZSTD_WINDOWLOG_MAX+1 - ZSTD_WINDOWLOG_MIN) + ZSTD_WINDOWLOG_MIN;
|
p.windowLog = FUZ_rand(&g_rand) % (ZSTD_WINDOWLOG_MAX+1 - ZSTD_WINDOWLOG_MIN) + ZSTD_WINDOWLOG_MIN;
|
||||||
p->searchLength=FUZ_rand(&g_rand) % (ZSTD_SEARCHLENGTH_MAX+1 - ZSTD_SEARCHLENGTH_MIN) + ZSTD_SEARCHLENGTH_MIN;
|
p.searchLength=FUZ_rand(&g_rand) % (ZSTD_SEARCHLENGTH_MAX+1 - ZSTD_SEARCHLENGTH_MIN) + ZSTD_SEARCHLENGTH_MIN;
|
||||||
p->targetLength=FUZ_rand(&g_rand) % (ZSTD_TARGETLENGTH_MAX+1 - ZSTD_TARGETLENGTH_MIN) + ZSTD_TARGETLENGTH_MIN;
|
p.targetLength=FUZ_rand(&g_rand) % (ZSTD_TARGETLENGTH_MAX+1 - ZSTD_TARGETLENGTH_MIN) + ZSTD_TARGETLENGTH_MIN;
|
||||||
p->strategy = (ZSTD_strategy) (FUZ_rand(&g_rand) % (ZSTD_btopt +1));
|
p.strategy = (ZSTD_strategy) (FUZ_rand(&g_rand) % (ZSTD_btopt +1));
|
||||||
validated = !ZSTD_isError(ZSTD_checkCParams(*p));
|
validated = !ZSTD_isError(ZSTD_checkCParams(p));
|
||||||
}
|
}
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BMK_selectRandomStart(
|
static void BMK_selectRandomStart(
|
||||||
@@ -626,12 +624,10 @@ static void BMK_selectRandomStart(
|
|||||||
const void* srcBuffer, size_t srcSize,
|
const void* srcBuffer, size_t srcSize,
|
||||||
ZSTD_CCtx* ctx)
|
ZSTD_CCtx* ctx)
|
||||||
{
|
{
|
||||||
U32 id = (FUZ_rand(&g_rand) % (ZSTD_maxCLevel()+1));
|
U32 const id = (FUZ_rand(&g_rand) % (ZSTD_maxCLevel()+1));
|
||||||
if ((id==0) || (winners[id].params.windowLog==0)) {
|
if ((id==0) || (winners[id].params.windowLog==0)) {
|
||||||
/* totally random entry */
|
/* totally random entry */
|
||||||
ZSTD_compressionParameters p;
|
ZSTD_compressionParameters const p = ZSTD_adjustCParams(randomParams(), srcSize, 0);
|
||||||
potentialRandomParams(&p, 1);
|
|
||||||
ZSTD_adjustCParams(&p, srcSize, 0);
|
|
||||||
playAround(f, winners, p, srcBuffer, srcSize, ctx);
|
playAround(f, winners, p, srcBuffer, srcSize, ctx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -652,7 +648,7 @@ static void BMK_benchMem(void* srcBuffer, size_t srcSize)
|
|||||||
|
|
||||||
if (g_singleRun) {
|
if (g_singleRun) {
|
||||||
BMK_result_t testResult;
|
BMK_result_t testResult;
|
||||||
ZSTD_adjustCParams(&g_params, srcSize, 0);
|
g_params = ZSTD_adjustCParams(g_params, srcSize, 0);
|
||||||
BMK_benchParam(&testResult, srcBuffer, srcSize, ctx, g_params);
|
BMK_benchParam(&testResult, srcBuffer, srcSize, ctx, g_params);
|
||||||
DISPLAY("\n");
|
DISPLAY("\n");
|
||||||
return;
|
return;
|
||||||
@@ -864,7 +860,7 @@ int optimizeForSize(char* inFileName)
|
|||||||
do {
|
do {
|
||||||
params = winner.params;
|
params = winner.params;
|
||||||
paramVariation(¶ms);
|
paramVariation(¶ms);
|
||||||
potentialRandomParams(¶ms, 16);
|
if ((FUZ_rand(&g_rand) & 15) == 1) params = randomParams();
|
||||||
|
|
||||||
/* exclude faster if already played set of params */
|
/* exclude faster if already played set of params */
|
||||||
if (FUZ_rand(&g_rand) & ((1 << NB_TESTS_PLAYED(params))-1)) continue;
|
if (FUZ_rand(&g_rand) & ((1 << NB_TESTS_PLAYED(params))-1)) continue;
|
||||||
|
|||||||
+134
-49
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
die() {
|
die() {
|
||||||
echo "$@" 1>&2
|
$ECHO "$@" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14,47 +14,77 @@ roundTripTest() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f tmp1 tmp2
|
rm -f tmp1 tmp2
|
||||||
echo "roundTripTest: ./datagen $1 $p | $ZSTD -v$c | $ZSTD -d"
|
$ECHO "roundTripTest: ./datagen $1 $p | $ZSTD -v$c | $ZSTD -d"
|
||||||
./datagen $1 $p | md5sum > tmp1
|
./datagen $1 $p | $MD5SUM > tmp1
|
||||||
./datagen $1 $p | $ZSTD -vq$c | $ZSTD -d | md5sum > tmp2
|
./datagen $1 $p | $ZSTD -vq$c | $ZSTD -d | $MD5SUM > tmp2
|
||||||
diff -q tmp1 tmp2
|
diff -q tmp1 tmp2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isWindows=false
|
||||||
|
ECHO="echo"
|
||||||
|
case "$OS" in
|
||||||
|
Windows*)
|
||||||
|
isWindows=true
|
||||||
|
ECHO="echo -e"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
MD5SUM="md5sum"
|
||||||
|
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||||
|
MD5SUM="md5 -r"
|
||||||
|
fi
|
||||||
|
|
||||||
|
$ECHO "\nStarting playTests.sh isWindows=$isWindows TRAVIS_OS_NAME=$TRAVIS_OS_NAME"
|
||||||
|
|
||||||
[ -n "$ZSTD" ] || die "ZSTD variable must be defined!"
|
[ -n "$ZSTD" ] || die "ZSTD variable must be defined!"
|
||||||
|
|
||||||
|
file $ZSTD
|
||||||
|
$ECHO "\n**** simple tests **** "
|
||||||
|
|
||||||
echo "\n**** simple tests **** "
|
|
||||||
./datagen > tmp
|
./datagen > tmp
|
||||||
$ZSTD -f tmp # trivial compression case, creates tmp.zst
|
$ZSTD -f tmp # trivial compression case, creates tmp.zst
|
||||||
$ZSTD -df tmp.zst # trivial decompression case (overwrites tmp)
|
$ZSTD -df tmp.zst # trivial decompression case (overwrites tmp)
|
||||||
echo "test : too large compression level (must fail)"
|
$ECHO "test : too large compression level (must fail)"
|
||||||
$ZSTD -99 tmp && die "too large compression level undetected"
|
$ZSTD -99 tmp && die "too large compression level undetected"
|
||||||
echo "test : compress to stdout"
|
$ECHO "test : compress to stdout"
|
||||||
$ZSTD tmp -c > tmpCompressed
|
$ZSTD tmp -c > tmpCompressed
|
||||||
$ZSTD tmp --stdout > tmpCompressed # long command format
|
$ZSTD tmp --stdout > tmpCompressed # long command format
|
||||||
echo "test : null-length file roundtrip"
|
$ECHO "test : null-length file roundtrip"
|
||||||
echo -n '' | $ZSTD - --stdout | $ZSTD -d --stdout
|
$ECHO -n '' | $ZSTD - --stdout | $ZSTD -d --stdout
|
||||||
echo "test : decompress file with wrong suffix (must fail)"
|
$ECHO "test : decompress file with wrong suffix (must fail)"
|
||||||
$ZSTD -d tmpCompressed && die "wrong suffix error not detected!"
|
$ZSTD -d tmpCompressed && die "wrong suffix error not detected!"
|
||||||
$ZSTD -d tmpCompressed -c > tmpResult # decompression using stdout
|
$ZSTD -d tmpCompressed -c > tmpResult # decompression using stdout
|
||||||
$ZSTD --decompress tmpCompressed -c > tmpResult
|
$ZSTD --decompress tmpCompressed -c > tmpResult
|
||||||
$ZSTD --decompress tmpCompressed --stdout > tmpResult
|
$ZSTD --decompress tmpCompressed --stdout > tmpResult
|
||||||
$ZSTD -d < tmp.zst > /dev/null # combine decompression, stdin & stdout
|
if [ "$isWindows" = false ] ; then
|
||||||
$ZSTD -d - < tmp.zst > /dev/null
|
$ZSTD -d < tmp.zst > /dev/null # combine decompression, stdin & stdout
|
||||||
|
$ZSTD -d - < tmp.zst > /dev/null
|
||||||
|
fi
|
||||||
$ZSTD -dc < tmp.zst > /dev/null
|
$ZSTD -dc < tmp.zst > /dev/null
|
||||||
$ZSTD -dc - < tmp.zst > /dev/null
|
$ZSTD -dc - < tmp.zst > /dev/null
|
||||||
$ZSTD -q tmp && die "overwrite check failed!"
|
$ZSTD -q tmp && die "overwrite check failed!"
|
||||||
$ZSTD -q -f tmp
|
$ZSTD -q -f tmp
|
||||||
$ZSTD -q --force tmp
|
$ZSTD -q --force tmp
|
||||||
$ZSTD -df tmp && die "should have refused : wrong extension"
|
$ZSTD -df tmp && die "should have refused : wrong extension"
|
||||||
cp tmp tmp2.zst
|
$ECHO "test : file removal"
|
||||||
$ZSTD -df tmp2.zst && die "should have failed : wrong format"
|
$ZSTD -f --rm tmp
|
||||||
rm tmp2.zst
|
ls tmp && die "tmp should no longer be present"
|
||||||
|
$ZSTD -f -d --rm tmp.zst
|
||||||
|
ls tmp.zst && die "tmp.zst should no longer be present"
|
||||||
|
rm tmp
|
||||||
|
$ZSTD -f tmp && die "tmp not present : should have failed"
|
||||||
|
ls tmp.zst && die "tmp.zst should not be created"
|
||||||
|
|
||||||
echo "\n**** frame concatenation **** "
|
|
||||||
|
|
||||||
echo "hello " > hello.tmp
|
$ECHO "\n**** Pass-Through mode **** "
|
||||||
echo "world!" > world.tmp
|
$ECHO "Hello world !" | $ZSTD -df
|
||||||
|
$ECHO "Hello world !" | $ZSTD -dcf
|
||||||
|
|
||||||
|
|
||||||
|
$ECHO "\n**** frame concatenation **** "
|
||||||
|
|
||||||
|
$ECHO "hello " > hello.tmp
|
||||||
|
$ECHO "world!" > world.tmp
|
||||||
cat hello.tmp world.tmp > helloworld.tmp
|
cat hello.tmp world.tmp > helloworld.tmp
|
||||||
$ZSTD -c hello.tmp > hello.zstd
|
$ZSTD -c hello.tmp > hello.zstd
|
||||||
$ZSTD -c world.tmp > world.zstd
|
$ZSTD -c world.tmp > world.zstd
|
||||||
@@ -63,62 +93,118 @@ $ZSTD -dc helloworld.zstd > result.tmp
|
|||||||
cat result.tmp
|
cat result.tmp
|
||||||
sdiff helloworld.tmp result.tmp
|
sdiff helloworld.tmp result.tmp
|
||||||
rm ./*.tmp ./*.zstd
|
rm ./*.tmp ./*.zstd
|
||||||
|
$ECHO "frame concatenation tests completed"
|
||||||
echo frame concatenation test completed
|
|
||||||
|
|
||||||
|
|
||||||
echo "\n**** flush write error test **** "
|
if [ "$isWindows" = false ] ; then
|
||||||
|
$ECHO "\n**** flush write error test **** "
|
||||||
|
|
||||||
echo "echo foo | $ZSTD > /dev/full"
|
$ECHO "$ECHO foo | $ZSTD > /dev/full"
|
||||||
echo foo | $ZSTD > /dev/full && die "write error not detected!"
|
$ECHO foo | $ZSTD > /dev/full && die "write error not detected!"
|
||||||
echo "echo foo | $ZSTD | $ZSTD -d > /dev/full"
|
$ECHO "$ECHO foo | $ZSTD | $ZSTD -d > /dev/full"
|
||||||
echo foo | $ZSTD | $ZSTD -d > /dev/full && die "write error not detected!"
|
$ECHO foo | $ZSTD | $ZSTD -d > /dev/full && die "write error not detected!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
echo "\n**** dictionary tests **** "
|
$ECHO "\n**** test sparse file support **** "
|
||||||
|
|
||||||
./datagen > tmpDict
|
./datagen -g5M -P100 > tmpSparse
|
||||||
./datagen -g1M | md5sum > tmp1
|
$ZSTD tmpSparse -c | $ZSTD -dv -o tmpSparseRegen
|
||||||
./datagen -g1M | $ZSTD -D tmpDict | $ZSTD -D tmpDict -dvq | md5sum > tmp2
|
diff -s tmpSparse tmpSparseRegen
|
||||||
diff -q tmp1 tmp2
|
$ZSTD tmpSparse -c | $ZSTD -dv --sparse -c > tmpOutSparse
|
||||||
$ZSTD --train *.c *.h -o tmpDict
|
diff -s tmpSparse tmpOutSparse
|
||||||
$ZSTD xxhash.c -D tmpDict -of tmp
|
$ZSTD tmpSparse -c | $ZSTD -dv --no-sparse -c > tmpOutNoSparse
|
||||||
$ZSTD -d tmp -D tmpDict -of result
|
diff -s tmpSparse tmpOutNoSparse
|
||||||
diff xxhash.c result
|
ls -ls tmpSparse*
|
||||||
|
./datagen -s1 -g1200007 -P100 | $ZSTD | $ZSTD -dv --sparse -c > tmpSparseOdd # Odd size file (to not finish on an exact nb of blocks)
|
||||||
|
./datagen -s1 -g1200007 -P100 | diff -s - tmpSparseOdd
|
||||||
|
ls -ls tmpSparseOdd
|
||||||
|
$ECHO "\n Sparse Compatibility with Console :"
|
||||||
|
$ECHO "Hello World 1 !" | $ZSTD | $ZSTD -d -c
|
||||||
|
$ECHO "Hello World 2 !" | $ZSTD | $ZSTD -d | cat
|
||||||
|
$ECHO "\n Sparse Compatibility with Append :"
|
||||||
|
./datagen -P100 -g1M > tmpSparse1M
|
||||||
|
cat tmpSparse1M tmpSparse1M > tmpSparse2M
|
||||||
|
$ZSTD -v -f tmpSparse1M -o tmpSparseCompressed
|
||||||
|
$ZSTD -d -v -f tmpSparseCompressed -o tmpSparseRegenerated
|
||||||
|
$ZSTD -d -v -f tmpSparseCompressed -c >> tmpSparseRegenerated
|
||||||
|
ls -ls tmpSparse*
|
||||||
|
diff tmpSparse2M tmpSparseRegenerated
|
||||||
|
rm tmpSparse*
|
||||||
|
|
||||||
|
|
||||||
echo "\n**** multiple files tests **** "
|
$ECHO "\n**** multiple files tests **** "
|
||||||
|
|
||||||
./datagen -s1 > tmp1 2> /dev/null
|
./datagen -s1 > tmp1 2> /dev/null
|
||||||
./datagen -s2 -g100K > tmp2 2> /dev/null
|
./datagen -s2 -g100K > tmp2 2> /dev/null
|
||||||
./datagen -s3 -g1M > tmp3 2> /dev/null
|
./datagen -s3 -g1M > tmp3 2> /dev/null
|
||||||
$ZSTD -f tmp*
|
$ZSTD -f tmp*
|
||||||
echo "compress tmp* : "
|
$ECHO "compress tmp* : "
|
||||||
ls -ls tmp*
|
ls -ls tmp*
|
||||||
rm tmp1 tmp2 tmp3
|
rm tmp1 tmp2 tmp3
|
||||||
echo "decompress tmp* : "
|
$ECHO "decompress tmp* : "
|
||||||
$ZSTD -df *.zst
|
$ZSTD -df *.zst
|
||||||
ls -ls tmp*
|
ls -ls tmp*
|
||||||
echo "compress tmp* into stdout > tmpall : "
|
$ECHO "compress tmp* into stdout > tmpall : "
|
||||||
$ZSTD -c tmp1 tmp2 tmp3 > tmpall
|
$ZSTD -c tmp1 tmp2 tmp3 > tmpall
|
||||||
ls -ls tmp*
|
ls -ls tmp*
|
||||||
echo "decompress tmpall* into stdout > tmpdec : "
|
$ECHO "decompress tmpall* into stdout > tmpdec : "
|
||||||
cp tmpall tmpall2
|
cp tmpall tmpall2
|
||||||
$ZSTD -dc tmpall* > tmpdec
|
$ZSTD -dc tmpall* > tmpdec
|
||||||
ls -ls tmp*
|
ls -ls tmp*
|
||||||
echo "compress multiple files including a missing one (notHere) : "
|
$ECHO "compress multiple files including a missing one (notHere) : "
|
||||||
$ZSTD -f tmp1 notHere tmp2 && die "missing file not detected!"
|
$ZSTD -f tmp1 notHere tmp2 && die "missing file not detected!"
|
||||||
|
|
||||||
echo "\n**** integrity tests **** "
|
|
||||||
echo "test one file (tmp1.zst) "
|
$ECHO "\n**** dictionary tests **** "
|
||||||
|
|
||||||
|
./datagen > tmpDict
|
||||||
|
./datagen -g1M | $MD5SUM > tmp1
|
||||||
|
./datagen -g1M | $ZSTD -D tmpDict | $ZSTD -D tmpDict -dvq | $MD5SUM > tmp2
|
||||||
|
diff -q tmp1 tmp2
|
||||||
|
$ECHO "- Create first dictionary"
|
||||||
|
$ZSTD --train *.c -o tmpDict
|
||||||
|
cp zstdcli.c tmp
|
||||||
|
$ZSTD -f tmp -D tmpDict
|
||||||
|
$ZSTD -d tmp.zst -D tmpDict -of result
|
||||||
|
diff zstdcli.c result
|
||||||
|
$ECHO "- Create second (different) dictionary"
|
||||||
|
$ZSTD --train *.c *.h -o tmpDictC
|
||||||
|
$ZSTD -d tmp.zst -D tmpDictC -of result && die "wrong dictionary not detected!"
|
||||||
|
$ECHO "- Create dictionary with short dictID"
|
||||||
|
$ZSTD --train *.c --dictID 1 -o tmpDict1
|
||||||
|
cmp tmpDict tmpDict1 && die "dictionaries should have different ID !"
|
||||||
|
$ECHO "- Compress without dictID"
|
||||||
|
$ZSTD -f tmp -D tmpDict1 --no-dictID
|
||||||
|
$ZSTD -d tmp.zst -D tmpDict -of result
|
||||||
|
diff zstdcli.c result
|
||||||
|
$ECHO "- Compress multiple files with dictionary"
|
||||||
|
rm -rf dirTestDict
|
||||||
|
mkdir dirTestDict
|
||||||
|
cp *.c dirTestDict
|
||||||
|
cp *.h dirTestDict
|
||||||
|
cat dirTestDict/* | $MD5SUM > tmph1 # note : we expect same file order to generate same hash
|
||||||
|
$ZSTD -f dirTestDict/* -D tmpDictC
|
||||||
|
$ZSTD -d dirTestDict/*.zst -D tmpDictC -c | $MD5SUM > tmph2
|
||||||
|
diff -q tmph1 tmph2
|
||||||
|
rm -rf dirTestDict
|
||||||
|
rm tmp*
|
||||||
|
|
||||||
|
|
||||||
|
$ECHO "\n**** integrity tests **** "
|
||||||
|
|
||||||
|
$ECHO "test one file (tmp1.zst) "
|
||||||
|
./datagen > tmp1
|
||||||
|
$ZSTD tmp1
|
||||||
$ZSTD -t tmp1.zst
|
$ZSTD -t tmp1.zst
|
||||||
$ZSTD --test tmp1.zst
|
$ZSTD --test tmp1.zst
|
||||||
echo "test multiple files (*.zst) "
|
$ECHO "test multiple files (*.zst) "
|
||||||
$ZSTD -t *.zst
|
$ZSTD -t *.zst
|
||||||
echo "test good and bad files (*) "
|
$ECHO "test good and bad files (*) "
|
||||||
$ZSTD -t * && die "bad files not detected !"
|
$ZSTD -t * && die "bad files not detected !"
|
||||||
|
|
||||||
echo "\n**** zstd round-trip tests **** "
|
|
||||||
|
$ECHO "\n**** zstd round-trip tests **** "
|
||||||
|
|
||||||
roundTripTest
|
roundTripTest
|
||||||
roundTripTest -g15K # TableID==3
|
roundTripTest -g15K # TableID==3
|
||||||
@@ -132,7 +218,7 @@ roundTripTest -g512K 19 # btopt
|
|||||||
rm tmp*
|
rm tmp*
|
||||||
|
|
||||||
if [ "$1" != "--test-large-data" ]; then
|
if [ "$1" != "--test-large-data" ]; then
|
||||||
echo "Skipping large data tests"
|
$ECHO "Skipping large data tests"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -165,4 +251,3 @@ roundTripTest -g99000000 -P99 20
|
|||||||
roundTripTest -g6000000000 -P99 1
|
roundTripTest -g6000000000 -P99 1
|
||||||
|
|
||||||
rm tmp*
|
rm tmp*
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
roundTripCrash
|
||||||
|
Copyright (C) Yann Collet 2013-2016
|
||||||
|
|
||||||
|
GPL v2 License
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
You can contact the author at :
|
||||||
|
- zstd homepage : http://www.zstd.net
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
This program takes a file in input,
|
||||||
|
performs a zstd round-trip test (compression - decompress)
|
||||||
|
compares the result with original
|
||||||
|
and generates a crash (double free) on corruption detection.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*===========================================
|
||||||
|
* Dependencies
|
||||||
|
*==========================================*/
|
||||||
|
#include <stddef.h> /* size_t */
|
||||||
|
#include <stdlib.h> /* malloc, free, exit */
|
||||||
|
#include <stdio.h> /* fprintf */
|
||||||
|
#include <sys/types.h> /* stat */
|
||||||
|
#include <sys/stat.h> /* stat */
|
||||||
|
#include "zstd.h"
|
||||||
|
|
||||||
|
/** roundTripTest() :
|
||||||
|
* Compresses `srcBuff` into `compressedBuff`,
|
||||||
|
* then decompresses `compressedBuff` into `resultBuff`.
|
||||||
|
* Compression level used is derived from first content byte.
|
||||||
|
* @return : result of decompression, which should be == `srcSize`
|
||||||
|
* or an error code if either compression or decompression fails.
|
||||||
|
* Note : `compressedBuffCapacity` should be `>= ZSTD_compressBound(srcSize)`
|
||||||
|
* for compression to be guaranteed to work */
|
||||||
|
static size_t roundTripTest(void* resultBuff, size_t resultBuffCapacity,
|
||||||
|
void* compressedBuff, size_t compressedBuffCapacity,
|
||||||
|
const void* srcBuff, size_t srcBuffSize)
|
||||||
|
{
|
||||||
|
static const int maxClevel = 19;
|
||||||
|
int const cLevel = (!srcBuffSize) ? 1 : (*(const unsigned char*)srcBuff) % maxClevel;
|
||||||
|
size_t const cSize = ZSTD_compress(compressedBuff, compressedBuffCapacity, srcBuff, srcBuffSize, cLevel);
|
||||||
|
if (ZSTD_isError(cSize)) {
|
||||||
|
fprintf(stderr, "Compression error : %s \n", ZSTD_getErrorName(cSize));
|
||||||
|
return cSize;
|
||||||
|
}
|
||||||
|
return ZSTD_decompress(resultBuff, resultBuffCapacity, compressedBuff, cSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t checkBuffers(const void* buff1, const void* buff2, size_t buffSize)
|
||||||
|
{
|
||||||
|
const char* ip1 = (const char*)buff1;
|
||||||
|
const char* ip2 = (const char*)buff2;
|
||||||
|
size_t pos;
|
||||||
|
|
||||||
|
for (pos=0; pos<buffSize; pos++)
|
||||||
|
if (ip1[pos]!=ip2[pos])
|
||||||
|
break;
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void roundTripCheck(const void* srcBuff, size_t srcBuffSize)
|
||||||
|
{
|
||||||
|
size_t const cBuffSize = ZSTD_compressBound(srcBuffSize);
|
||||||
|
void* cBuff = malloc(cBuffSize);
|
||||||
|
void* rBuff = malloc(cBuffSize);
|
||||||
|
#define CRASH { free(cBuff); free(cBuff); } /* double free, to crash program */
|
||||||
|
|
||||||
|
if (!cBuff || !rBuff) {
|
||||||
|
fprintf(stderr, "not enough memory ! \n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ size_t const result = roundTripTest(rBuff, cBuffSize, cBuff, cBuffSize, srcBuff, srcBuffSize);
|
||||||
|
if (ZSTD_isError(result)) {
|
||||||
|
fprintf(stderr, "roundTripTest error : %s \n", ZSTD_getErrorName(result));
|
||||||
|
CRASH;
|
||||||
|
}
|
||||||
|
if (result != srcBuffSize) {
|
||||||
|
fprintf(stderr, "Incorrect regenerated size : %u != %u\n", (unsigned)result, (unsigned)srcBuffSize);
|
||||||
|
CRASH;
|
||||||
|
}
|
||||||
|
if (checkBuffers(srcBuff, rBuff, srcBuffSize) != srcBuffSize) {
|
||||||
|
fprintf(stderr, "Silent decoding corruption !!!");
|
||||||
|
CRASH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(cBuff);
|
||||||
|
free(rBuff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t getFileSize(const char* infilename)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
struct _stat64 statbuf;
|
||||||
|
r = _stat64(infilename, &statbuf);
|
||||||
|
if (r || !(statbuf.st_mode & S_IFREG)) return 0; /* No good... */
|
||||||
|
#else
|
||||||
|
struct stat statbuf;
|
||||||
|
r = stat(infilename, &statbuf);
|
||||||
|
if (r || !S_ISREG(statbuf.st_mode)) return 0; /* No good... */
|
||||||
|
#endif
|
||||||
|
return (size_t)statbuf.st_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int isDirectory(const char* infilename)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
struct _stat64 statbuf;
|
||||||
|
r = _stat64(infilename, &statbuf);
|
||||||
|
if (!r && (statbuf.st_mode & _S_IFDIR)) return 1;
|
||||||
|
#else
|
||||||
|
struct stat statbuf;
|
||||||
|
r = stat(infilename, &statbuf);
|
||||||
|
if (!r && S_ISDIR(statbuf.st_mode)) return 1;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** loadFile() :
|
||||||
|
* requirement : `buffer` size >= `fileSize` */
|
||||||
|
static void loadFile(void* buffer, const char* fileName, size_t fileSize)
|
||||||
|
{
|
||||||
|
FILE* const f = fopen(fileName, "rb");
|
||||||
|
if (isDirectory(fileName)) {
|
||||||
|
fprintf(stderr, "Ignoring %s directory \n", fileName);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
if (f==NULL) {
|
||||||
|
fprintf(stderr, "Impossible to open %s \n", fileName);
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
{ size_t const readSize = fread(buffer, 1, fileSize, f);
|
||||||
|
if (readSize != fileSize) {
|
||||||
|
fprintf(stderr, "Error reading %s \n", fileName);
|
||||||
|
exit(5);
|
||||||
|
} }
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void fileCheck(const char* fileName)
|
||||||
|
{
|
||||||
|
size_t const fileSize = getFileSize(fileName);
|
||||||
|
void* buffer = malloc(fileSize);
|
||||||
|
if (!buffer) {
|
||||||
|
fprintf(stderr, "not enough memory \n");
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
loadFile(buffer, fileName, fileSize);
|
||||||
|
roundTripCheck(buffer, fileSize);
|
||||||
|
free (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argCount, const char** argv) {
|
||||||
|
if (argCount < 2) {
|
||||||
|
fprintf(stderr, "Error : no argument : need input file \n");
|
||||||
|
exit(9);
|
||||||
|
}
|
||||||
|
fileCheck(argv[1]);
|
||||||
|
fprintf(stderr, "no pb detected\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+7
-5
@@ -37,7 +37,6 @@ extern "C" {
|
|||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
#if _MSC_VER <= 1800 /* (1800 = Visual Studio 2013) */
|
#if _MSC_VER <= 1800 /* (1800 = Visual Studio 2013) */
|
||||||
#define snprintf sprintf_s /* snprintf unsupported by Visual <= 2013 */
|
#define snprintf sprintf_s /* snprintf unsupported by Visual <= 2013 */
|
||||||
//#define snprintf _snprintf
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -91,11 +90,15 @@ extern "C" {
|
|||||||
# define SET_HIGH_PRIORITY SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)
|
# define SET_HIGH_PRIORITY SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)
|
||||||
# define UTIL_sleep(s) Sleep(1000*s)
|
# define UTIL_sleep(s) Sleep(1000*s)
|
||||||
# define UTIL_sleepMilli(milli) Sleep(milli)
|
# define UTIL_sleepMilli(milli) Sleep(milli)
|
||||||
#elif (defined(__unix__) || defined(__unix) || defined(__midipix__) || (defined(__APPLE__) && defined(__MACH__)))
|
#elif (defined(__unix__) || defined(__unix) || defined(__VMS) || defined(__midipix__) || (defined(__APPLE__) && defined(__MACH__)))
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
# include <sys/resource.h> /* setpriority */
|
# include <sys/resource.h> /* setpriority */
|
||||||
# include <time.h> /* clock_t, nanosleep, clock, CLOCKS_PER_SEC */
|
# include <time.h> /* clock_t, nanosleep, clock, CLOCKS_PER_SEC */
|
||||||
# define SET_HIGH_PRIORITY setpriority(PRIO_PROCESS, 0, -20)
|
# if defined(PRIO_PROCESS)
|
||||||
|
# define SET_HIGH_PRIORITY setpriority(PRIO_PROCESS, 0, -20)
|
||||||
|
# else
|
||||||
|
# define SET_HIGH_PRIORITY /* disabled */
|
||||||
|
# endif
|
||||||
# define UTIL_sleep(s) sleep(s)
|
# define UTIL_sleep(s) sleep(s)
|
||||||
# if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L)
|
# if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L)
|
||||||
# define UTIL_sleepMilli(milli) { struct timespec t; t.tv_sec=0; t.tv_nsec=milli*1000000ULL; nanosleep(&t, NULL); }
|
# define UTIL_sleepMilli(milli) { struct timespec t; t.tv_sec=0; t.tv_nsec=milli*1000000ULL; nanosleep(&t, NULL); }
|
||||||
@@ -342,8 +345,7 @@ UTIL_STATIC const char** UTIL_createFileList(const char **inputNames, unsigned i
|
|||||||
bufend = buf + LIST_SIZE_INCREASE;
|
bufend = buf + LIST_SIZE_INCREASE;
|
||||||
|
|
||||||
for (i=0, pos=0, nbFiles=0; i<inputNamesNb; i++) {
|
for (i=0, pos=0, nbFiles=0; i<inputNamesNb; i++) {
|
||||||
if (UTIL_doesFileExists(inputNames[i])) {
|
if (!UTIL_isDirectory(inputNames[i])) {
|
||||||
// printf ("UTIL_doesFileExists=[%s]\n", inputNames[i]);
|
|
||||||
size_t len = strlen(inputNames[i]);
|
size_t len = strlen(inputNames[i]);
|
||||||
if (buf + pos + len >= bufend) {
|
if (buf + pos + len >= bufend) {
|
||||||
ptrdiff_t newListSize = (bufend - buf) + LIST_SIZE_INCREASE;
|
ptrdiff_t newListSize = (bufend - buf) + LIST_SIZE_INCREASE;
|
||||||
|
|||||||
+116
-73
@@ -35,24 +35,23 @@
|
|||||||
/*-************************************
|
/*-************************************
|
||||||
* Includes
|
* Includes
|
||||||
**************************************/
|
**************************************/
|
||||||
#include <stdlib.h> /* free */
|
#include <stdlib.h> /* free */
|
||||||
#include <stdio.h> /* fgets, sscanf */
|
#include <stdio.h> /* fgets, sscanf */
|
||||||
#include <sys/timeb.h> /* timeb */
|
#include <sys/timeb.h> /* timeb */
|
||||||
#include <string.h> /* strcmp */
|
#include <string.h> /* strcmp */
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "zbuff.h"
|
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_maxCLevel */
|
||||||
#include "zstd_static.h" /* ZSTD_compressBound(), ZSTD_maxCLevel() */
|
#include "zstd.h" /* ZSTD_compressBound */
|
||||||
#include "datagen.h" /* RDG_genBuffer */
|
#define ZBUFF_STATIC_LINKING_ONLY
|
||||||
#include "xxhash.h" /* XXH64 */
|
#include "zbuff.h" /* ZBUFF_createCCtx_advanced */
|
||||||
|
#include "datagen.h" /* RDG_genBuffer */
|
||||||
|
#define XXH_STATIC_LINKING_ONLY
|
||||||
|
#include "xxhash.h" /* XXH64_* */
|
||||||
|
|
||||||
|
|
||||||
/*-************************************
|
/*-************************************
|
||||||
* Constants
|
* Constants
|
||||||
**************************************/
|
**************************************/
|
||||||
#ifndef ZSTD_VERSION
|
|
||||||
# define ZSTD_VERSION ""
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define KB *(1U<<10)
|
#define KB *(1U<<10)
|
||||||
#define MB *(1U<<20)
|
#define MB *(1U<<20)
|
||||||
#define GB *(1U<<30)
|
#define GB *(1U<<30)
|
||||||
@@ -99,7 +98,7 @@ static U32 FUZ_GetMilliStart(void)
|
|||||||
|
|
||||||
static U32 FUZ_GetMilliSpan(U32 nTimeStart)
|
static U32 FUZ_GetMilliSpan(U32 nTimeStart)
|
||||||
{
|
{
|
||||||
U32 nCurrent = FUZ_GetMilliStart();
|
U32 const nCurrent = FUZ_GetMilliStart();
|
||||||
U32 nSpan = nCurrent - nTimeStart;
|
U32 nSpan = nCurrent - nTimeStart;
|
||||||
if (nTimeStart > nCurrent)
|
if (nTimeStart > nCurrent)
|
||||||
nSpan += 0x100000 * 1000;
|
nSpan += 0x100000 * 1000;
|
||||||
@@ -131,89 +130,120 @@ static unsigned FUZ_highbit32(U32 v32)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int basicUnitTests(U32 seed, double compressibility)
|
static void* ZBUFF_allocFunction(void* opaque, size_t size)
|
||||||
|
{
|
||||||
|
void* address = malloc(size);
|
||||||
|
(void)opaque;
|
||||||
|
/* DISPLAYLEVEL(4, "alloc %p, %d opaque=%p \n", address, (int)size, opaque); */
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ZBUFF_freeFunction(void* opaque, void* address)
|
||||||
|
{
|
||||||
|
(void)opaque;
|
||||||
|
/* if (address) DISPLAYLEVEL(4, "free %p opaque=%p \n", address, opaque); */
|
||||||
|
free(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem customMem)
|
||||||
{
|
{
|
||||||
int testResult = 0;
|
int testResult = 0;
|
||||||
size_t CNBufferSize = COMPRESSIBLE_NOISE_LENGTH;
|
size_t CNBufferSize = COMPRESSIBLE_NOISE_LENGTH;
|
||||||
void* CNBuffer = malloc(CNBufferSize);
|
void* CNBuffer = malloc(CNBufferSize);
|
||||||
size_t const compressedBufferSize = ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH);
|
size_t const skippableFrameSize = 11;
|
||||||
|
size_t const compressedBufferSize = (8 + skippableFrameSize) + ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH);
|
||||||
void* compressedBuffer = malloc(compressedBufferSize);
|
void* compressedBuffer = malloc(compressedBufferSize);
|
||||||
size_t const decodedBufferSize = CNBufferSize;
|
size_t const decodedBufferSize = CNBufferSize;
|
||||||
void* decodedBuffer = malloc(decodedBufferSize);
|
void* decodedBuffer = malloc(decodedBufferSize);
|
||||||
U32 randState = seed;
|
size_t cSize, readSize, readSkipSize, genSize;
|
||||||
size_t result, cSize, readSize, genSize;
|
|
||||||
U32 testNb=0;
|
U32 testNb=0;
|
||||||
ZBUFF_CCtx* zc = ZBUFF_createCCtx();
|
ZBUFF_CCtx* zc = ZBUFF_createCCtx_advanced(customMem);
|
||||||
ZBUFF_DCtx* zd = ZBUFF_createDCtx();
|
ZBUFF_DCtx* zd = ZBUFF_createDCtx_advanced(customMem);
|
||||||
|
|
||||||
/* Create compressible test buffer */
|
/* Create compressible test buffer */
|
||||||
if (!CNBuffer || !compressedBuffer || !decodedBuffer || !zc || !zd) {
|
if (!CNBuffer || !compressedBuffer || !decodedBuffer || !zc || !zd) {
|
||||||
DISPLAY("Not enough memory, aborting\n");
|
DISPLAY("Not enough memory, aborting\n");
|
||||||
goto _output_error;
|
goto _output_error;
|
||||||
}
|
}
|
||||||
RDG_genBuffer(CNBuffer, CNBufferSize, compressibility, 0., randState);
|
RDG_genBuffer(CNBuffer, CNBufferSize, compressibility, 0., seed);
|
||||||
|
|
||||||
|
/* generate skippable frame */
|
||||||
|
MEM_writeLE32(compressedBuffer, ZSTD_MAGIC_SKIPPABLE_START);
|
||||||
|
MEM_writeLE32(((char*)compressedBuffer)+4, (U32)skippableFrameSize);
|
||||||
|
cSize = skippableFrameSize + 8;
|
||||||
|
|
||||||
/* Basic compression test */
|
/* Basic compression test */
|
||||||
DISPLAYLEVEL(4, "test%3i : compress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
|
DISPLAYLEVEL(4, "test%3i : compress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
|
||||||
ZBUFF_compressInitDictionary(zc, CNBuffer, 128 KB, 1);
|
ZBUFF_compressInitDictionary(zc, CNBuffer, 128 KB, 1);
|
||||||
readSize = CNBufferSize;
|
readSize = CNBufferSize;
|
||||||
genSize = compressedBufferSize;
|
genSize = compressedBufferSize;
|
||||||
result = ZBUFF_compressContinue(zc, compressedBuffer, &genSize, CNBuffer, &readSize);
|
{ size_t const r = ZBUFF_compressContinue(zc, ((char*)compressedBuffer)+cSize, &genSize, CNBuffer, &readSize);
|
||||||
if (ZBUFF_isError(result)) goto _output_error;
|
if (ZBUFF_isError(r)) 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 */
|
||||||
cSize = genSize;
|
cSize += genSize;
|
||||||
genSize = compressedBufferSize - cSize;
|
genSize = compressedBufferSize - cSize;
|
||||||
result = ZBUFF_compressEnd(zc, ((char*)compressedBuffer)+cSize, &genSize);
|
{ size_t const r = ZBUFF_compressEnd(zc, ((char*)compressedBuffer)+cSize, &genSize);
|
||||||
if (result != 0) goto _output_error; /* error, or some data not flushed */
|
if (r != 0) goto _output_error; } /*< error, or some data not flushed */
|
||||||
cSize += genSize;
|
cSize += genSize;
|
||||||
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/COMPRESSIBLE_NOISE_LENGTH*100);
|
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/COMPRESSIBLE_NOISE_LENGTH*100);
|
||||||
|
|
||||||
|
/* skippable frame test */
|
||||||
|
DISPLAYLEVEL(4, "test%3i : decompress skippable frame : ", testNb++);
|
||||||
|
ZBUFF_decompressInitDictionary(zd, CNBuffer, 128 KB);
|
||||||
|
readSkipSize = cSize;
|
||||||
|
genSize = CNBufferSize;
|
||||||
|
{ size_t const r = ZBUFF_decompressContinue(zd, decodedBuffer, &genSize, compressedBuffer, &readSkipSize);
|
||||||
|
if (r != 0) goto _output_error; }
|
||||||
|
if (genSize != 0) goto _output_error; /* skippable frame len is 0 */
|
||||||
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
/* 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_decompressInitDictionary(zd, CNBuffer, 128 KB);
|
ZBUFF_decompressInitDictionary(zd, CNBuffer, 128 KB);
|
||||||
readSize = cSize;
|
readSize = cSize - readSkipSize;
|
||||||
genSize = CNBufferSize;
|
genSize = CNBufferSize;
|
||||||
result = ZBUFF_decompressContinue(zd, decodedBuffer, &genSize, compressedBuffer, &readSize);
|
{ size_t const r = ZBUFF_decompressContinue(zd, decodedBuffer, &genSize, ((char*)compressedBuffer)+readSkipSize, &readSize);
|
||||||
if (result != 0) goto _output_error; /* should reach end of frame == 0; otherwise, some data left, or an error */
|
if (r != 0) goto _output_error; } /* should reach end of frame == 0; otherwise, some data left, or an error */
|
||||||
if (genSize != CNBufferSize) goto _output_error; /* should regenerate the same amount */
|
if (genSize != CNBufferSize) goto _output_error; /* should regenerate the same amount */
|
||||||
if (readSize != cSize) goto _output_error; /* should have read the entire frame */
|
if (readSize+readSkipSize != cSize) goto _output_error; /* should have read the entire frame */
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
/* check regenerated data is byte exact */
|
/* check regenerated data is byte exact */
|
||||||
|
DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++);
|
||||||
{ size_t i;
|
{ size_t i;
|
||||||
DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++);
|
|
||||||
for (i=0; i<CNBufferSize; i++) {
|
for (i=0; i<CNBufferSize; i++) {
|
||||||
if (((BYTE*)decodedBuffer)[i] != ((BYTE*)CNBuffer)[i]) goto _output_error;;
|
if (((BYTE*)decodedBuffer)[i] != ((BYTE*)CNBuffer)[i]) goto _output_error;;
|
||||||
}
|
} }
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
}
|
|
||||||
|
|
||||||
/* Byte-by-byte decompression test */
|
/* Byte-by-byte decompression test */
|
||||||
DISPLAYLEVEL(4, "test%3i : decompress byte-by-byte : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : decompress byte-by-byte : ", testNb++);
|
||||||
ZBUFF_decompressInitDictionary(zd, CNBuffer, 128 KB);
|
{ size_t r, pIn=0, pOut=0;
|
||||||
{ size_t r = 1, pIn=0, pOut=0;
|
do
|
||||||
while (r) {
|
{ ZBUFF_decompressInitDictionary(zd, CNBuffer, 128 KB);
|
||||||
size_t inS = 1;
|
r = 1;
|
||||||
size_t outS = 1;
|
while (r) {
|
||||||
r = ZBUFF_decompressContinue(zd, ((BYTE*)decodedBuffer)+pOut, &outS, ((BYTE*)compressedBuffer)+pIn, &inS);
|
size_t inS = 1;
|
||||||
pIn += inS;
|
size_t outS = 1;
|
||||||
pOut += outS;
|
r = ZBUFF_decompressContinue(zd, ((BYTE*)decodedBuffer)+pOut, &outS, ((BYTE*)compressedBuffer)+pIn, &inS);
|
||||||
}
|
pIn += inS;
|
||||||
readSize = pIn;
|
pOut += outS;
|
||||||
genSize = pOut;
|
}
|
||||||
|
readSize = pIn;
|
||||||
|
genSize = pOut;
|
||||||
|
} while (genSize==0);
|
||||||
}
|
}
|
||||||
if (genSize != CNBufferSize) goto _output_error; /* should regenerate the same amount */
|
if (genSize != CNBufferSize) goto _output_error; /* should regenerate the same amount */
|
||||||
if (readSize != cSize) goto _output_error; /* should have read the entire frame */
|
if (readSize != cSize) goto _output_error; /* should have read the entire frame */
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
/* check regenerated data is byte exact */
|
/* check regenerated data is byte exact */
|
||||||
|
DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++);
|
||||||
{ size_t i;
|
{ size_t i;
|
||||||
DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++);
|
|
||||||
for (i=0; i<CNBufferSize; i++) {
|
for (i=0; i<CNBufferSize; i++) {
|
||||||
if (((BYTE*)decodedBuffer)[i] != ((BYTE*)CNBuffer)[i]) goto _output_error;;
|
if (((BYTE*)decodedBuffer)[i] != ((BYTE*)CNBuffer)[i]) goto _output_error;;
|
||||||
}
|
} }
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
}
|
|
||||||
|
|
||||||
_end:
|
_end:
|
||||||
ZBUFF_freeCCtx(zc);
|
ZBUFF_freeCCtx(zc);
|
||||||
@@ -234,19 +264,13 @@ static size_t findDiff(const void* buf1, const void* buf2, size_t max)
|
|||||||
{
|
{
|
||||||
const BYTE* b1 = (const BYTE*)buf1;
|
const BYTE* b1 = (const BYTE*)buf1;
|
||||||
const BYTE* b2 = (const BYTE*)buf2;
|
const BYTE* b2 = (const BYTE*)buf2;
|
||||||
size_t i;
|
size_t u;
|
||||||
for (i=0; i<max; i++) {
|
for (u=0; u<max; u++) {
|
||||||
if (b1[i] != b2[i]) break;
|
if (b1[u] != b2[u]) break;
|
||||||
}
|
}
|
||||||
return i;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
|
|
||||||
|
|
||||||
#define CHECK(cond, ...) if (cond) { DISPLAY("Error => "); DISPLAY(__VA_ARGS__); \
|
|
||||||
DISPLAY(" (seed %u, test nb %u) \n", seed, testNb); goto _output_error; }
|
|
||||||
|
|
||||||
|
|
||||||
static size_t FUZ_rLogLength(U32* seed, U32 logLength)
|
static size_t FUZ_rLogLength(U32* seed, U32 logLength)
|
||||||
{
|
{
|
||||||
size_t const lengthMask = ((size_t)1 << logLength) - 1;
|
size_t const lengthMask = ((size_t)1 << logLength) - 1;
|
||||||
@@ -259,6 +283,11 @@ static size_t FUZ_randomLength(U32* seed, U32 maxLog)
|
|||||||
return FUZ_rLogLength(seed, logLength);
|
return FUZ_rLogLength(seed, logLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
|
||||||
|
|
||||||
|
#define CHECK(cond, ...) if (cond) { DISPLAY("Error => "); DISPLAY(__VA_ARGS__); \
|
||||||
|
DISPLAY(" (seed %u, test nb %u) \n", seed, testNb); goto _output_error; }
|
||||||
|
|
||||||
static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibility)
|
static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibility)
|
||||||
{
|
{
|
||||||
static const U32 maxSrcLog = 24;
|
static const U32 maxSrcLog = 24;
|
||||||
@@ -314,7 +343,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
|
|||||||
size_t cSize, totalTestSize, totalCSize, totalGenSize;
|
size_t cSize, totalTestSize, totalCSize, totalGenSize;
|
||||||
size_t errorCode;
|
size_t errorCode;
|
||||||
U32 n, nbChunks;
|
U32 n, nbChunks;
|
||||||
XXH64_CREATESTATE_STATIC(xxh64);
|
XXH64_state_t xxhState;
|
||||||
U64 crcOrig;
|
U64 crcOrig;
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
@@ -323,8 +352,8 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
|
|||||||
FUZ_rand(&coreSeed);
|
FUZ_rand(&coreSeed);
|
||||||
lseed = coreSeed ^ prime1;
|
lseed = coreSeed ^ prime1;
|
||||||
|
|
||||||
/* state total reset */
|
/* states full reset (unsynchronized) */
|
||||||
/* some problems only happen when states are re-used in a specific order */
|
/* some issues only happen when reusing states in a specific sequence of parameters */
|
||||||
if ((FUZ_rand(&lseed) & 0xFF) == 131) { ZBUFF_freeCCtx(zc); zc = ZBUFF_createCCtx(); }
|
if ((FUZ_rand(&lseed) & 0xFF) == 131) { ZBUFF_freeCCtx(zc); zc = ZBUFF_createCCtx(); }
|
||||||
if ((FUZ_rand(&lseed) & 0xFF) == 132) { ZBUFF_freeDCtx(zd); zd = ZBUFF_createDCtx(); }
|
if ((FUZ_rand(&lseed) & 0xFF) == 132) { ZBUFF_freeDCtx(zd); zd = ZBUFF_createDCtx(); }
|
||||||
|
|
||||||
@@ -347,18 +376,24 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
|
|||||||
{ U32 const testLog = FUZ_rand(&lseed) % maxSrcLog;
|
{ U32 const testLog = FUZ_rand(&lseed) % maxSrcLog;
|
||||||
U32 const cLevel = (FUZ_rand(&lseed) % (ZSTD_maxCLevel() - (testLog/3))) + 1;
|
U32 const cLevel = (FUZ_rand(&lseed) % (ZSTD_maxCLevel() - (testLog/3))) + 1;
|
||||||
maxTestSize = FUZ_rLogLength(&lseed, testLog);
|
maxTestSize = FUZ_rLogLength(&lseed, testLog);
|
||||||
|
dictSize = (FUZ_rand(&lseed)==1) ? FUZ_randomLength(&lseed, maxSampleLog) : 0;
|
||||||
/* random dictionary selection */
|
/* random dictionary selection */
|
||||||
{ size_t dictStart;
|
{ size_t const dictStart = FUZ_rand(&lseed) % (srcBufferSize - dictSize);
|
||||||
dictSize = (FUZ_rand(&lseed)==1) ? FUZ_randomLength(&lseed, maxSampleLog) : 0;
|
dict = srcBuffer + dictStart;
|
||||||
dictStart = FUZ_rand(&lseed) % (srcBufferSize - dictSize);
|
|
||||||
dict = srcBuffer + dictStart;
|
|
||||||
}
|
}
|
||||||
{ size_t const initError = ZBUFF_compressInitDictionary(zc, dict, dictSize, cLevel);
|
{ ZSTD_compressionParameters const cPar = ZSTD_getCParams(cLevel, 0, dictSize);
|
||||||
CHECK (ZBUFF_isError(initError),"init error : %s", ZBUFF_getErrorName(initError));
|
U32 const checksum = FUZ_rand(&lseed) & 1;
|
||||||
} }
|
U32 const noDictIDFlag = FUZ_rand(&lseed) & 1;
|
||||||
|
ZSTD_frameParameters const fPar = { 0, checksum, noDictIDFlag };
|
||||||
|
ZSTD_parameters params;
|
||||||
|
params.cParams = cPar;
|
||||||
|
params.fParams = fPar;
|
||||||
|
{ size_t const initError = ZBUFF_compressInit_advanced(zc, dict, dictSize, params, 0);
|
||||||
|
CHECK (ZBUFF_isError(initError),"init error : %s", ZBUFF_getErrorName(initError));
|
||||||
|
} } }
|
||||||
|
|
||||||
/* multi-segments compression test */
|
/* multi-segments compression test */
|
||||||
XXH64_reset(xxh64, 0);
|
XXH64_reset(&xxhState, 0);
|
||||||
nbChunks = (FUZ_rand(&lseed) & 127) + 2;
|
nbChunks = (FUZ_rand(&lseed) & 127) + 2;
|
||||||
for (n=0, cSize=0, totalTestSize=0 ; (n<nbChunks) && (totalTestSize < maxTestSize) ; n++) {
|
for (n=0, cSize=0, totalTestSize=0 ; (n<nbChunks) && (totalTestSize < maxTestSize) ; n++) {
|
||||||
/* compress random chunk into random size dst buffer */
|
/* compress random chunk into random size dst buffer */
|
||||||
@@ -370,7 +405,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
|
|||||||
size_t const compressionError = ZBUFF_compressContinue(zc, cBuffer+cSize, &dstBuffSize, srcBuffer+srcStart, &readChunkSize);
|
size_t const compressionError = ZBUFF_compressContinue(zc, cBuffer+cSize, &dstBuffSize, srcBuffer+srcStart, &readChunkSize);
|
||||||
CHECK (ZBUFF_isError(compressionError), "compression error : %s", ZBUFF_getErrorName(compressionError));
|
CHECK (ZBUFF_isError(compressionError), "compression error : %s", ZBUFF_getErrorName(compressionError));
|
||||||
|
|
||||||
XXH64_update(xxh64, srcBuffer+srcStart, readChunkSize);
|
XXH64_update(&xxhState, srcBuffer+srcStart, readChunkSize);
|
||||||
memcpy(copyBuffer+totalTestSize, srcBuffer+srcStart, readChunkSize);
|
memcpy(copyBuffer+totalTestSize, srcBuffer+srcStart, readChunkSize);
|
||||||
cSize += dstBuffSize;
|
cSize += dstBuffSize;
|
||||||
totalTestSize += readChunkSize;
|
totalTestSize += readChunkSize;
|
||||||
@@ -391,7 +426,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
|
|||||||
CHECK (ZBUFF_isError(flushError), "flush error : %s", ZBUFF_getErrorName(flushError));
|
CHECK (ZBUFF_isError(flushError), "flush error : %s", ZBUFF_getErrorName(flushError));
|
||||||
cSize += dstBuffSize;
|
cSize += dstBuffSize;
|
||||||
}
|
}
|
||||||
crcOrig = XXH64_digest(xxh64);
|
crcOrig = XXH64_digest(&xxhState);
|
||||||
|
|
||||||
/* multi - fragments decompression test */
|
/* multi - fragments decompression test */
|
||||||
ZBUFF_decompressInitDictionary(zd, dict, dictSize);
|
ZBUFF_decompressInitDictionary(zd, dict, dictSize);
|
||||||
@@ -489,6 +524,8 @@ int main(int argc, const char** argv)
|
|||||||
int result=0;
|
int result=0;
|
||||||
U32 mainPause = 0;
|
U32 mainPause = 0;
|
||||||
const char* programName = argv[0];
|
const char* programName = argv[0];
|
||||||
|
ZSTD_customMem customMem = { ZBUFF_allocFunction, ZBUFF_freeFunction, NULL };
|
||||||
|
ZSTD_customMem customNULL = { NULL, NULL, NULL };
|
||||||
|
|
||||||
/* Check command line */
|
/* Check command line */
|
||||||
for(argNb=1; argNb<argc; argNb++) {
|
for(argNb=1; argNb<argc; argNb++) {
|
||||||
@@ -579,7 +616,7 @@ int main(int argc, const char** argv)
|
|||||||
} } } /* for(argNb=1; argNb<argc; argNb++) */
|
} } } /* for(argNb=1; argNb<argc; argNb++) */
|
||||||
|
|
||||||
/* Get Seed */
|
/* Get Seed */
|
||||||
DISPLAY("Starting zstd_buffered tester (%i-bits, %s)\n", (int)(sizeof(size_t)*8), ZSTD_VERSION);
|
DISPLAY("Starting zstd_buffered tester (%i-bits, %s)\n", (int)(sizeof(size_t)*8), ZSTD_VERSION_STRING);
|
||||||
|
|
||||||
if (!seedset) seed = FUZ_GetMilliStart() % 10000;
|
if (!seedset) seed = FUZ_GetMilliStart() % 10000;
|
||||||
DISPLAY("Seed = %u\n", seed);
|
DISPLAY("Seed = %u\n", seed);
|
||||||
@@ -587,7 +624,13 @@ int main(int argc, const char** argv)
|
|||||||
|
|
||||||
if (nbTests<=0) nbTests=1;
|
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, customNULL); /* constant seed for predictability */
|
||||||
|
if (!result) {
|
||||||
|
DISPLAYLEVEL(4, "Unit tests using customMem :\n")
|
||||||
|
result = basicUnitTests(0, ((double)proba) / 100, customMem); /* use custom memory allocation functions */
|
||||||
|
} }
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
result = fuzzerTests(seed, nbTests, testNb, ((double)proba) / 100);
|
result = fuzzerTests(seed, nbTests, testNb, ((double)proba) / 100);
|
||||||
|
|
||||||
|
|||||||
+17
-2
@@ -43,7 +43,7 @@ It also features a very fast decoder, with speed > 500 MB/s per core.
|
|||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
.B \-#
|
.B \-#
|
||||||
# compression level [1-21] (default:1)
|
# compression level [1-22] (default:1)
|
||||||
.TP
|
.TP
|
||||||
.BR \-d ", " --decompress
|
.BR \-d ", " --decompress
|
||||||
decompression
|
decompression
|
||||||
@@ -52,7 +52,7 @@ It also features a very fast decoder, with speed > 500 MB/s per core.
|
|||||||
use `file` as Dictionary to compress or decompress FILE(s)
|
use `file` as Dictionary to compress or decompress FILE(s)
|
||||||
.TP
|
.TP
|
||||||
.B \-o file
|
.B \-o file
|
||||||
save result into `file` (only possible with a single input FILE)
|
save result into `file` (only possible with a single INPUT-FILE)
|
||||||
.TP
|
.TP
|
||||||
.BR \-f ", " --force
|
.BR \-f ", " --force
|
||||||
overwrite output without prompting
|
overwrite output without prompting
|
||||||
@@ -71,6 +71,13 @@ It also features a very fast decoder, with speed > 500 MB/s per core.
|
|||||||
.TP
|
.TP
|
||||||
.BR \-c ", " --stdout
|
.BR \-c ", " --stdout
|
||||||
force write to standard output, even if it is the console
|
force write to standard output, even if it is the console
|
||||||
|
.TP
|
||||||
|
.BR \-C ", " --check
|
||||||
|
add integrity check computed from uncompressed data
|
||||||
|
.TP
|
||||||
|
.BR \-t ", " --test
|
||||||
|
Test the integrity of compressed files. This option is equivalent to \fB--decompress --stdout > /dev/null\fR.
|
||||||
|
No files are created or removed.
|
||||||
|
|
||||||
.SH DICTIONARY
|
.SH DICTIONARY
|
||||||
.PP
|
.PP
|
||||||
@@ -92,6 +99,14 @@ Typical gains range from ~10% (at 64KB) to x5 better (at <1KB).
|
|||||||
.B \--maxdict #
|
.B \--maxdict #
|
||||||
limit dictionary to specified size (default : 112640)
|
limit dictionary to specified size (default : 112640)
|
||||||
.TP
|
.TP
|
||||||
|
.B \--dictID #
|
||||||
|
A dictionary ID is a locally unique ID that a decoder can use to verify it is using the right dictionary.
|
||||||
|
By default, zstd will create a 4-bytes random number ID.
|
||||||
|
It's possible to give a precise number instead.
|
||||||
|
Short numbers have an advantage : an ID < 256 will only need 1 byte in the compressed frame header,
|
||||||
|
and an ID < 65536 will only need 2 bytes. This compares favorably to 4 bytes default.
|
||||||
|
However, it's up to the dictionary manager to not assign twice the same ID to 2 different dictionaries.
|
||||||
|
.TP
|
||||||
.B \-s#
|
.B \-s#
|
||||||
dictionary selectivity level (default: 9)
|
dictionary selectivity level (default: 9)
|
||||||
the smaller the value, the denser the dictionary, improving its efficiency but reducing its possible maximum size.
|
the smaller the value, the denser the dictionary, improving its efficiency but reducing its possible maximum size.
|
||||||
|
|||||||
+114
-63
@@ -38,10 +38,11 @@
|
|||||||
#ifndef ZSTD_NOBENCH
|
#ifndef ZSTD_NOBENCH
|
||||||
# include "bench.h" /* BMK_benchFiles, BMK_SetNbIterations */
|
# include "bench.h" /* BMK_benchFiles, BMK_SetNbIterations */
|
||||||
#endif
|
#endif
|
||||||
#include "zstd_static.h" /* ZSTD_maxCLevel, ZSTD version numbers */
|
|
||||||
#ifndef ZSTD_NODICT
|
#ifndef ZSTD_NODICT
|
||||||
# include "dibio.h"
|
# include "dibio.h"
|
||||||
#endif
|
#endif
|
||||||
|
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_maxCLevel */
|
||||||
|
#include "zstd.h" /* ZSTD_VERSION_STRING */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -49,15 +50,15 @@
|
|||||||
* 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 <io.h> /* _isatty */
|
||||||
# include <io.h> /* _setmode, _isatty */
|
|
||||||
# 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
|
||||||
extern int fileno(FILE *stream); /* triggers fileno() within <stdio.h> on POSIX */
|
#if defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE)
|
||||||
# include <unistd.h> /* isatty */
|
# include <unistd.h> /* isatty */
|
||||||
# define SET_BINARY_MODE(file)
|
|
||||||
# define IS_CONSOLE(stdStream) isatty(fileno(stdStream))
|
# define IS_CONSOLE(stdStream) isatty(fileno(stdStream))
|
||||||
|
#else
|
||||||
|
# define IS_CONSOLE(stdStream) 0
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -125,28 +126,37 @@ static int usage_advanced(const char* programName)
|
|||||||
DISPLAY( "\n");
|
DISPLAY( "\n");
|
||||||
DISPLAY( "Advanced arguments :\n");
|
DISPLAY( "Advanced arguments :\n");
|
||||||
DISPLAY( " -V : display Version number and exit\n");
|
DISPLAY( " -V : display Version number and exit\n");
|
||||||
DISPLAY( " -t : test compressed file integrity \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( " -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");
|
||||||
|
#ifdef UTIL_HAS_CREATEFILELIST
|
||||||
|
DISPLAY( " -r : operate recursively on directories\n");
|
||||||
|
#endif
|
||||||
|
DISPLAY( "--rm : remove source files after successful de/compression \n");
|
||||||
#ifndef ZSTD_NOCOMPRESS
|
#ifndef ZSTD_NOCOMPRESS
|
||||||
DISPLAY( "--ultra : enable ultra modes (requires more memory to decompress)\n");
|
DISPLAY( "--ultra : enable ultra modes (requires more memory to decompress)\n");
|
||||||
|
DISPLAY( "--no-dictID : don't write dictID into header (dictionary compression)\n");
|
||||||
|
DISPLAY( "--check : enable integrity check\n");
|
||||||
|
#endif
|
||||||
|
#ifndef ZSTD_NODECOMPRESS
|
||||||
|
DISPLAY( "--test : test compressed file integrity \n");
|
||||||
|
DISPLAY( "--[no-]sparse : sparse mode (default:enabled on file, disabled on stdout)\n");
|
||||||
#endif
|
#endif
|
||||||
#ifndef ZSTD_NODICT
|
#ifndef ZSTD_NODICT
|
||||||
|
DISPLAY( "\n");
|
||||||
DISPLAY( "Dictionary builder :\n");
|
DISPLAY( "Dictionary builder :\n");
|
||||||
DISPLAY( "--train : create a dictionary from a training set of files \n");
|
DISPLAY( "--train ## : create a dictionary from a training set of files \n");
|
||||||
DISPLAY( " -o file: `file` is dictionary name (default: %s) \n", g_defaultDictName);
|
DISPLAY( " -o file : `file` is dictionary name (default: %s) \n", g_defaultDictName);
|
||||||
DISPLAY( "--maxdict:limit dictionary to specified size (default : %u) \n", g_defaultMaxDictSize);
|
DISPLAY( "--maxdict ## : limit dictionary to specified size (default : %u) \n", g_defaultMaxDictSize);
|
||||||
DISPLAY( " -s# : dictionary selectivity level (default: %u)\n", g_defaultSelectivityLevel);
|
DISPLAY( " -s# : dictionary selectivity level (default: %u)\n", g_defaultSelectivityLevel);
|
||||||
|
DISPLAY( "--dictID ## : force dictionary ID to specified value (default: random)\n");
|
||||||
#endif
|
#endif
|
||||||
#ifndef ZSTD_NOBENCH
|
#ifndef ZSTD_NOBENCH
|
||||||
|
DISPLAY( "\n");
|
||||||
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( " -e# : test all compression levels from -bX to # (default: 1)\n");
|
DISPLAY( " -e# : test all compression levels from -bX to # (default: 1)\n");
|
||||||
DISPLAY( " -i# : iteration loops [1-9](default : 3)\n");
|
DISPLAY( " -i# : iteration loops [1-9](default : 3)\n");
|
||||||
#ifdef UTIL_HAS_CREATEFILELIST
|
|
||||||
DISPLAY( " -r : operate recursively on directories\n");
|
|
||||||
#endif
|
|
||||||
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");
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
@@ -168,12 +178,24 @@ static void waitEnter(void)
|
|||||||
(void)unused;
|
(void)unused;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! readU32FromChar() :
|
||||||
|
@return : unsigned integer value reach from input in `char` format
|
||||||
|
Will also modify `*stringPtr`, advancing it to position where it stopped reading.
|
||||||
|
Note : this function can overflow if result > MAX_UNIT */
|
||||||
|
static unsigned readU32FromChar(const char** stringPtr)
|
||||||
|
{
|
||||||
|
unsigned result = 0;
|
||||||
|
while ((**stringPtr >='0') && (**stringPtr <='9'))
|
||||||
|
result *= 10, result += **stringPtr - '0', (*stringPtr)++ ;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define CLEAN_RETURN(i) { operationResult = (i); goto _end; }
|
#define CLEAN_RETURN(i) { operationResult = (i); goto _end; }
|
||||||
|
|
||||||
int main(int argCount, const char** argv)
|
int main(int argCount, const char** argv)
|
||||||
{
|
{
|
||||||
int i,
|
int argNb,
|
||||||
bench=0,
|
bench=0,
|
||||||
decode=0,
|
decode=0,
|
||||||
forceStdout=0,
|
forceStdout=0,
|
||||||
@@ -182,7 +204,8 @@ int main(int argCount, const char** argv)
|
|||||||
operationResult=0,
|
operationResult=0,
|
||||||
dictBuild=0,
|
dictBuild=0,
|
||||||
nextArgumentIsOutFileName=0,
|
nextArgumentIsOutFileName=0,
|
||||||
nextArgumentIsMaxDict=0;
|
nextArgumentIsMaxDict=0,
|
||||||
|
nextArgumentIsDictID=0;
|
||||||
unsigned cLevel = 1;
|
unsigned cLevel = 1;
|
||||||
unsigned cLevelLast = 1;
|
unsigned cLevelLast = 1;
|
||||||
unsigned recursive = 0;
|
unsigned recursive = 0;
|
||||||
@@ -193,25 +216,35 @@ int main(int argCount, const char** argv)
|
|||||||
const char* dictFileName = NULL;
|
const char* dictFileName = NULL;
|
||||||
char* dynNameSpace = NULL;
|
char* dynNameSpace = NULL;
|
||||||
unsigned maxDictSize = g_defaultMaxDictSize;
|
unsigned maxDictSize = g_defaultMaxDictSize;
|
||||||
|
unsigned dictID = 0;
|
||||||
unsigned dictCLevel = g_defaultDictCLevel;
|
unsigned dictCLevel = g_defaultDictCLevel;
|
||||||
unsigned dictSelect = g_defaultSelectivityLevel;
|
unsigned dictSelect = g_defaultSelectivityLevel;
|
||||||
|
#ifdef UTIL_HAS_CREATEFILELIST
|
||||||
|
const char** fileNamesTable = NULL;
|
||||||
|
char* fileNamesBuf = NULL;
|
||||||
|
unsigned fileNamesNb;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
(void)recursive; (void)cLevelLast; (void)dictCLevel; /* not used when ZSTD_NOBENCH / ZSTD_NODICT set */
|
(void)recursive; (void)cLevelLast; /* not used when ZSTD_NOBENCH set */
|
||||||
|
(void)dictCLevel; (void)dictSelect; (void)dictID; /* not used when ZSTD_NODICT set */
|
||||||
(void)decode; (void)cLevel; /* not used when ZSTD_NOCOMPRESS set */
|
(void)decode; (void)cLevel; /* not used when ZSTD_NOCOMPRESS set */
|
||||||
if (filenameTable==NULL) { DISPLAY("not enough memory\n"); exit(1); }
|
if (filenameTable==NULL) { DISPLAY("not enough memory\n"); exit(1); }
|
||||||
|
filenameTable[0] = stdinmark;
|
||||||
displayOut = stderr;
|
displayOut = stderr;
|
||||||
/* Pick out program name from path. 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--) { if (programName[i] == '/') { i++; break; } }
|
{ size_t pos;
|
||||||
programName += i;
|
for (pos = (int)strlen(programName); pos > 0; pos--) { if (programName[pos] == '/') { pos++; break; } }
|
||||||
|
programName += pos;
|
||||||
|
}
|
||||||
|
|
||||||
/* preset behaviors */
|
/* preset behaviors */
|
||||||
if (!strcmp(programName, ZSTD_UNZSTD)) decode=1;
|
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; }
|
||||||
|
|
||||||
/* command switches */
|
/* command switches */
|
||||||
for(i=1; i<argCount; i++) {
|
for(argNb=1; argNb<argCount; argNb++) {
|
||||||
const char* argument = argv[i];
|
const char* argument = argv[argNb];
|
||||||
if(!argument) continue; /* Protection if argument empty */
|
if(!argument) continue; /* Protection if argument empty */
|
||||||
|
|
||||||
/* long commands (--long-word) */
|
/* long commands (--long-word) */
|
||||||
@@ -222,11 +255,17 @@ int main(int argCount, const char** argv)
|
|||||||
if (!strcmp(argument, "--verbose")) { displayLevel=4; continue; }
|
if (!strcmp(argument, "--verbose")) { displayLevel=4; continue; }
|
||||||
if (!strcmp(argument, "--quiet")) { displayLevel--; continue; }
|
if (!strcmp(argument, "--quiet")) { displayLevel--; continue; }
|
||||||
if (!strcmp(argument, "--stdout")) { forceStdout=1; outFileName=stdoutmark; displayLevel=1; continue; }
|
if (!strcmp(argument, "--stdout")) { forceStdout=1; outFileName=stdoutmark; displayLevel=1; continue; }
|
||||||
|
if (!strcmp(argument, "--ultra")) { FIO_setMaxWLog(0); continue; }
|
||||||
|
if (!strcmp(argument, "--check")) { FIO_setChecksumFlag(2); continue; }
|
||||||
|
if (!strcmp(argument, "--no-dictID")) { FIO_setDictIDFlag(0); continue; }
|
||||||
|
if (!strcmp(argument, "--sparse")) { FIO_setSparseWrite(2); continue; }
|
||||||
|
if (!strcmp(argument, "--no-sparse")) { FIO_setSparseWrite(0); continue; }
|
||||||
if (!strcmp(argument, "--test")) { decode=1; outFileName=nulmark; FIO_overwriteMode(); continue; }
|
if (!strcmp(argument, "--test")) { decode=1; outFileName=nulmark; FIO_overwriteMode(); continue; }
|
||||||
if (!strcmp(argument, "--train")) { dictBuild=1; outFileName=g_defaultDictName; continue; }
|
if (!strcmp(argument, "--train")) { dictBuild=1; outFileName=g_defaultDictName; continue; }
|
||||||
if (!strcmp(argument, "--maxdict")) { nextArgumentIsMaxDict=1; continue; }
|
if (!strcmp(argument, "--maxdict")) { nextArgumentIsMaxDict=1; continue; }
|
||||||
|
if (!strcmp(argument, "--dictID")) { nextArgumentIsDictID=1; continue; }
|
||||||
if (!strcmp(argument, "--keep")) { continue; } /* does nothing, since preserving input is default; for gzip/xz compatibility */
|
if (!strcmp(argument, "--keep")) { continue; } /* does nothing, since preserving input is default; for gzip/xz compatibility */
|
||||||
if (!strcmp(argument, "--ultra")) { FIO_setMaxWLog(0); continue; }
|
if (!strcmp(argument, "--rm")) { FIO_setRemoveSrcFile(1); continue; }
|
||||||
|
|
||||||
/* '-' means stdin/stdout */
|
/* '-' means stdin/stdout */
|
||||||
if (!strcmp(argument, "-")){
|
if (!strcmp(argument, "-")){
|
||||||
@@ -241,12 +280,7 @@ int main(int argCount, const char** argv)
|
|||||||
#ifndef ZSTD_NOCOMPRESS
|
#ifndef ZSTD_NOCOMPRESS
|
||||||
/* compression Level */
|
/* compression Level */
|
||||||
if ((*argument>='0') && (*argument<='9')) {
|
if ((*argument>='0') && (*argument<='9')) {
|
||||||
cLevel = 0;
|
cLevel = readU32FromChar(&argument);
|
||||||
while ((*argument >= '0') && (*argument <= '9')) {
|
|
||||||
cLevel *= 10;
|
|
||||||
cLevel += *argument - '0';
|
|
||||||
argument++;
|
|
||||||
}
|
|
||||||
dictCLevel = cLevel;
|
dictCLevel = cLevel;
|
||||||
if (dictCLevel > ZSTD_maxCLevel())
|
if (dictCLevel > ZSTD_maxCLevel())
|
||||||
CLEAN_RETURN(badusage(programName));
|
CLEAN_RETURN(badusage(programName));
|
||||||
@@ -271,7 +305,7 @@ int main(int argCount, const char** argv)
|
|||||||
case 'D': nextEntryIsDictionary = 1; argument++; break;
|
case 'D': nextEntryIsDictionary = 1; argument++; break;
|
||||||
|
|
||||||
/* Overwrite */
|
/* Overwrite */
|
||||||
case 'f': FIO_overwriteMode(); argument++; break;
|
case 'f': FIO_overwriteMode(); forceStdout=1; argument++; break;
|
||||||
|
|
||||||
/* Verbose mode */
|
/* Verbose mode */
|
||||||
case 'v': displayLevel=4; argument++; break;
|
case 'v': displayLevel=4; argument++; break;
|
||||||
@@ -282,12 +316,18 @@ int main(int argCount, const char** argv)
|
|||||||
/* keep source file (default anyway, so useless; for gzip/xz compatibility) */
|
/* keep source file (default anyway, so useless; for gzip/xz compatibility) */
|
||||||
case 'k': argument++; break;
|
case 'k': argument++; break;
|
||||||
|
|
||||||
|
/* Checksum */
|
||||||
|
case 'C': argument++; FIO_setChecksumFlag(2); break;
|
||||||
|
|
||||||
/* test compressed file */
|
/* test compressed file */
|
||||||
case 't': decode=1; outFileName=nulmark; FIO_overwriteMode(); argument++; break;
|
case 't': decode=1; outFileName=nulmark; argument++; break;
|
||||||
|
|
||||||
/* dictionary name */
|
/* dictionary name */
|
||||||
case 'o': nextArgumentIsOutFileName=1; argument++; break;
|
case 'o': nextArgumentIsOutFileName=1; argument++; break;
|
||||||
|
|
||||||
|
/* recursive */
|
||||||
|
case 'r': recursive=1; argument++; break;
|
||||||
|
|
||||||
#ifndef ZSTD_NOBENCH
|
#ifndef ZSTD_NOBENCH
|
||||||
/* Benchmark */
|
/* Benchmark */
|
||||||
case 'b': bench=1; argument++; break;
|
case 'b': bench=1; argument++; break;
|
||||||
@@ -296,33 +336,22 @@ int main(int argCount, const char** argv)
|
|||||||
case 'e':
|
case 'e':
|
||||||
/* compression Level */
|
/* compression Level */
|
||||||
argument++;
|
argument++;
|
||||||
if ((*argument>='0') && (*argument<='9')) {
|
cLevelLast = readU32FromChar(&argument);
|
||||||
cLevelLast = 0;
|
|
||||||
while ((*argument >= '0') && (*argument <= '9'))
|
|
||||||
cLevelLast *= 10, cLevelLast += *argument++ - '0';
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Modify Nb Iterations (benchmark only) */
|
/* Modify Nb Iterations (benchmark only) */
|
||||||
case 'i':
|
case 'i':
|
||||||
{ U32 iters= 0;
|
argument++;
|
||||||
argument++;
|
{ U32 const iters = readU32FromChar(&argument);
|
||||||
while ((*argument >='0') && (*argument <='9'))
|
|
||||||
iters *= 10, iters += *argument++ - '0';
|
|
||||||
BMK_setNotificationLevel(displayLevel);
|
BMK_setNotificationLevel(displayLevel);
|
||||||
BMK_SetNbIterations(iters);
|
BMK_SetNbIterations(iters);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* recursive */
|
|
||||||
case 'r': recursive=1; argument++; break;
|
|
||||||
|
|
||||||
/* cut input into blocks (benchmark only) */
|
/* cut input into blocks (benchmark only) */
|
||||||
case 'B':
|
case 'B':
|
||||||
{ size_t bSize = 0;
|
argument++;
|
||||||
argument++;
|
{ size_t bSize = readU32FromChar(&argument);
|
||||||
while ((*argument >='0') && (*argument <='9'))
|
|
||||||
bSize *= 10, bSize += *argument++ - '0';
|
|
||||||
if (toupper(*argument)=='K') bSize<<=10, argument++; /* allows using KB notation */
|
if (toupper(*argument)=='K') bSize<<=10, argument++; /* allows using KB notation */
|
||||||
if (toupper(*argument)=='M') bSize<<=20, argument++;
|
if (toupper(*argument)=='M') bSize<<=20, argument++;
|
||||||
if (toupper(*argument)=='B') argument++;
|
if (toupper(*argument)=='B') argument++;
|
||||||
@@ -332,21 +361,17 @@ int main(int argCount, const char** argv)
|
|||||||
break;
|
break;
|
||||||
#endif /* ZSTD_NOBENCH */
|
#endif /* ZSTD_NOBENCH */
|
||||||
|
|
||||||
/* Selection level */
|
/* Dictionary Selection level */
|
||||||
case 's': argument++;
|
case 's':
|
||||||
dictSelect = 0;
|
argument++;
|
||||||
while ((*argument >= '0') && (*argument <= '9'))
|
dictSelect = readU32FromChar(&argument);
|
||||||
dictSelect *= 10, dictSelect += *argument++ - '0';
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Pause at the end (-p) or set an additional param (-p#) (hidden option) */
|
/* Pause at the end (-p) or set an additional param (-p#) (hidden option) */
|
||||||
case 'p': argument++;
|
case 'p': argument++;
|
||||||
#ifndef ZSTD_NOBENCH
|
#ifndef ZSTD_NOBENCH
|
||||||
if ((*argument>='0') && (*argument<='9')) {
|
if ((*argument>='0') && (*argument<='9')) {
|
||||||
int additionalParam = 0;
|
BMK_setAdditionalParam(readU32FromChar(&argument));
|
||||||
while ((*argument >= '0') && (*argument <= '9'))
|
|
||||||
additionalParam *= 10, additionalParam += *argument++ - '0';
|
|
||||||
BMK_setAdditionalParam(additionalParam);
|
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
main_pause=1;
|
main_pause=1;
|
||||||
@@ -373,10 +398,15 @@ int main(int argCount, const char** argv)
|
|||||||
|
|
||||||
if (nextArgumentIsMaxDict) {
|
if (nextArgumentIsMaxDict) {
|
||||||
nextArgumentIsMaxDict = 0;
|
nextArgumentIsMaxDict = 0;
|
||||||
maxDictSize = 0;
|
maxDictSize = readU32FromChar(&argument);
|
||||||
while ((*argument>='0') && (*argument<='9'))
|
|
||||||
maxDictSize = maxDictSize * 10 + (*argument - '0'), argument++;
|
|
||||||
if (toupper(*argument)=='K') maxDictSize <<= 10;
|
if (toupper(*argument)=='K') maxDictSize <<= 10;
|
||||||
|
if (toupper(*argument)=='M') maxDictSize <<= 20;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextArgumentIsDictID) {
|
||||||
|
nextArgumentIsDictID = 0;
|
||||||
|
dictID = readU32FromChar(&argument);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,11 +417,24 @@ int main(int argCount, const char** argv)
|
|||||||
/* Welcome message (if verbose) */
|
/* Welcome message (if verbose) */
|
||||||
DISPLAYLEVEL(3, WELCOME_MESSAGE);
|
DISPLAYLEVEL(3, WELCOME_MESSAGE);
|
||||||
|
|
||||||
|
#ifdef UTIL_HAS_CREATEFILELIST
|
||||||
|
if (recursive) {
|
||||||
|
fileNamesTable = UTIL_createFileList(filenameTable, filenameIdx, &fileNamesBuf, &fileNamesNb);
|
||||||
|
if (fileNamesTable) {
|
||||||
|
unsigned i;
|
||||||
|
for (i=0; i<fileNamesNb; i++) DISPLAYLEVEL(3, "%d %s\n", i, fileNamesTable[i]);
|
||||||
|
free((void*)filenameTable);
|
||||||
|
filenameTable = fileNamesTable;
|
||||||
|
filenameIdx = fileNamesNb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Check if benchmark is selected */
|
/* Check if benchmark is selected */
|
||||||
if (bench) {
|
if (bench) {
|
||||||
#ifndef ZSTD_NOBENCH
|
#ifndef ZSTD_NOBENCH
|
||||||
BMK_setNotificationLevel(displayLevel);
|
BMK_setNotificationLevel(displayLevel);
|
||||||
BMK_benchFiles(filenameTable, filenameIdx, dictFileName, cLevel, cLevelLast, recursive);
|
BMK_benchFiles(filenameTable, filenameIdx, dictFileName, cLevel, cLevelLast);
|
||||||
#endif
|
#endif
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
@@ -403,17 +446,20 @@ int main(int argCount, const char** argv)
|
|||||||
dictParams.compressionLevel = dictCLevel;
|
dictParams.compressionLevel = dictCLevel;
|
||||||
dictParams.selectivityLevel = dictSelect;
|
dictParams.selectivityLevel = dictSelect;
|
||||||
dictParams.notificationLevel = displayLevel;
|
dictParams.notificationLevel = displayLevel;
|
||||||
|
dictParams.dictID = dictID;
|
||||||
DiB_trainFromFiles(outFileName, maxDictSize, filenameTable, filenameIdx, dictParams);
|
DiB_trainFromFiles(outFileName, maxDictSize, filenameTable, filenameIdx, dictParams);
|
||||||
#endif
|
#endif
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No input filename ==> use stdin and stdout */
|
/* No input filename ==> use stdin and stdout */
|
||||||
if(!filenameIdx) filenameIdx=1, filenameTable[0]=stdinmark, outFileName=stdoutmark;
|
filenameIdx += !filenameIdx; /*< default input is stdin */
|
||||||
|
if (!strcmp(filenameTable[0], stdinmark) && !outFileName ) outFileName = stdoutmark; /*< when input is stdin, default output is stdout */
|
||||||
|
|
||||||
/* Check if input/output defined as console; trigger an error in this case */
|
/* Check if input/output defined as console; trigger an error in this case */
|
||||||
if (!strcmp(filenameTable[0], stdinmark) && IS_CONSOLE(stdin) ) CLEAN_RETURN(badusage(programName));
|
if (!strcmp(filenameTable[0], stdinmark) && IS_CONSOLE(stdin) ) CLEAN_RETURN(badusage(programName));
|
||||||
if (outFileName && !strcmp(outFileName, stdoutmark) && IS_CONSOLE(stdout) && !forceStdout) CLEAN_RETURN(badusage(programName));
|
if (outFileName && !strcmp(outFileName, stdoutmark) && IS_CONSOLE(stdout) && !(forceStdout && decode))
|
||||||
|
CLEAN_RETURN(badusage(programName));
|
||||||
|
|
||||||
/* user-selected output filename, only possible with a single file */
|
/* user-selected output filename, only possible with a single file */
|
||||||
if (outFileName && strcmp(outFileName,stdoutmark) && strcmp(outFileName,nulmark) && (filenameIdx>1)) {
|
if (outFileName && strcmp(outFileName,stdoutmark) && strcmp(outFileName,nulmark) && (filenameIdx>1)) {
|
||||||
@@ -438,9 +484,9 @@ int main(int argCount, const char** argv)
|
|||||||
{ /* decompression */
|
{ /* decompression */
|
||||||
#ifndef ZSTD_NODECOMPRESS
|
#ifndef ZSTD_NODECOMPRESS
|
||||||
if (filenameIdx==1 && outFileName)
|
if (filenameIdx==1 && outFileName)
|
||||||
operationResult = FIO_decompressFilename(outFileName, filenameTable[0], dictFileName);
|
operationResult = FIO_decompressFilename(outFileName, filenameTable[0], dictFileName);
|
||||||
else
|
else
|
||||||
operationResult = FIO_decompressMultipleFilenames(filenameTable, filenameIdx, outFileName ? outFileName : ZSTD_EXTENSION, dictFileName);
|
operationResult = FIO_decompressMultipleFilenames(filenameTable, filenameIdx, outFileName ? outFileName : ZSTD_EXTENSION, dictFileName);
|
||||||
#else
|
#else
|
||||||
DISPLAY("Decompression not supported\n");
|
DISPLAY("Decompression not supported\n");
|
||||||
#endif
|
#endif
|
||||||
@@ -449,6 +495,11 @@ int main(int argCount, const char** argv)
|
|||||||
_end:
|
_end:
|
||||||
if (main_pause) waitEnter();
|
if (main_pause) waitEnter();
|
||||||
free(dynNameSpace);
|
free(dynNameSpace);
|
||||||
free((void*)filenameTable);
|
#ifdef UTIL_HAS_CREATEFILELIST
|
||||||
|
if (fileNamesTable)
|
||||||
|
UTIL_freeFileList(fileNamesTable, fileNamesBuf);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
free((void*)filenameTable);
|
||||||
return operationResult;
|
return operationResult;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
build
|
||||||
|
*Copy
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
projects for various integrated development environments (IDE)
|
||||||
|
================================
|
||||||
|
|
||||||
|
#### Included projects
|
||||||
|
|
||||||
|
The following projects are included with the zstd distribution:
|
||||||
|
- cmake - CMake project contributed by Artyom Dymchenko
|
||||||
|
- VS2008 - Visual Studio 2008 project
|
||||||
|
- VS2010 - Visual Studio 2010 project (which also works well with Visual Studio 2012, 2013, 2015)
|
||||||
@@ -0,0 +1,449 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9.00"
|
||||||
|
Name="fullbench"
|
||||||
|
ProjectGUID="{CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}"
|
||||||
|
RootNamespace="fullbench"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
<Platform
|
||||||
|
Name="x64"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
WarnAsError="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="2"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
OmitFramePointers="true"
|
||||||
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
WarnAsError="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="2"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
OmitFramePointers="true"
|
||||||
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\programs\datagen.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\entropy_common.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\fse_compress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\fse_decompress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\xxhash.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\programs\fullbench.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\huf_compress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\decompress\huf_decompress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\zbuff_compress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\decompress\zbuff_decompress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zstd_common.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\zstd_compress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\decompress\zstd_decompress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\bitstream.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\error_private.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\error_public.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\fse.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\fse_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\huf.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\huf_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\xxhash.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\mem.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zbuff_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zstd.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zstd_internal.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\zstd_opt.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zstd_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
@@ -0,0 +1,461 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9.00"
|
||||||
|
Name="fuzzer"
|
||||||
|
ProjectGUID="{A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}"
|
||||||
|
RootNamespace="fuzzer"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
<Platform
|
||||||
|
Name="x64"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
WarnAsError="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="2"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
OmitFramePointers="true"
|
||||||
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
WarnAsError="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="2"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
OmitFramePointers="true"
|
||||||
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\programs\datagen.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\dictBuilder\divsufsort.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\entropy_common.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\fse_compress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\fse_decompress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\programs\fuzzer.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\huf_compress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\decompress\huf_decompress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\xxhash.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\dictBuilder\zdict.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zstd_common.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\zstd_compress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\decompress\zstd_decompress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\bitstream.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\dictBuilder\divsufsort.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\error_private.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\error_public.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\fse.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\fse_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\huf.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\huf_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\mem.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\xxhash.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zbuff_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\dictBuilder\zdict.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\dictBuilder\zdict_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zstd.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zstd_internal.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\zstd_opt.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zstd_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||||
|
# Visual Studio 2008
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zstd", "zstd\zstd.vcproj", "{1A2AB08E-5CE7-4C5B-BE55-458157C14051}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fuzzer", "fuzzer\fuzzer.vcproj", "{A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench", "fullbench\fullbench.vcproj", "{CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zstdlib", "zstdlib\zstdlib.vcproj", "{99DE2A79-7298-4004-A0ED-030D7A3796CA}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Release|x64.Build.0 = Release|x64
|
||||||
|
{A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Release|x64.Build.0 = Release|x64
|
||||||
|
{CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Release|x64.Build.0 = Release|x64
|
||||||
|
{99DE2A79-7298-4004-A0ED-030D7A3796CA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{99DE2A79-7298-4004-A0ED-030D7A3796CA}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{99DE2A79-7298-4004-A0ED-030D7A3796CA}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{99DE2A79-7298-4004-A0ED-030D7A3796CA}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{99DE2A79-7298-4004-A0ED-030D7A3796CA}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{99DE2A79-7298-4004-A0ED-030D7A3796CA}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{99DE2A79-7298-4004-A0ED-030D7A3796CA}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{99DE2A79-7298-4004-A0ED-030D7A3796CA}.Release|x64.Build.0 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
@@ -0,0 +1,545 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9.00"
|
||||||
|
Name="zstd"
|
||||||
|
ProjectGUID="{1A2AB08E-5CE7-4C5B-BE55-458157C14051}"
|
||||||
|
RootNamespace="zstd"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
<Platform
|
||||||
|
Name="x64"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
WarnAsError="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="setargv.obj"
|
||||||
|
LinkIncremental="2"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
OmitFramePointers="true"
|
||||||
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="setargv.obj"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
WarnAsError="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="setargv.obj"
|
||||||
|
LinkIncremental="2"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
OmitFramePointers="true"
|
||||||
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="setargv.obj"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\programs\bench.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\programs\datagen.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\programs\dibio.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\dictBuilder\divsufsort.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\entropy_common.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\programs\fileio.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\programs\legacy\fileio_legacy.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\fse_compress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\fse_decompress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\huf_compress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\decompress\huf_decompress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\xxhash.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\zbuff_compress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\decompress\zbuff_decompress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\dictBuilder\zdict.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zstd_common.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\zstd_compress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\decompress\zstd_decompress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v01.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v02.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v03.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v04.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v05.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v06.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\programs\zstdcli.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\bitstream.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\dictBuilder\divsufsort.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\error_private.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\error_public.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\fse.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\fse_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\huf.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\huf_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\mem.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\xxhash.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zbuff.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zbuff_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\dictBuilder\zdict.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\dictBuilder\zdict_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zstd.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zstd_internal.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_legacy.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\zstd_opt.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zstd_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v01.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v02.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v03.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v04.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v05.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v06.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
@@ -0,0 +1,495 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9.00"
|
||||||
|
Name="zstdlib"
|
||||||
|
ProjectGUID="{99DE2A79-7298-4004-A0ED-030D7A3796CA}"
|
||||||
|
RootNamespace="zstdlib"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
<Platform
|
||||||
|
Name="x64"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
|
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
WarnAsError="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="2"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
OmitFramePointers="true"
|
||||||
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
|
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
|
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
WarnAsError="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="2"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
OmitFramePointers="true"
|
||||||
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
|
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\dictBuilder\divsufsort.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\entropy_common.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\fse_compress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\fse_decompress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\huf_compress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\decompress\huf_decompress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\xxhash.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\zbuff_compress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\decompress\zbuff_decompress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\dictBuilder\zdict.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zstd_common.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\zstd_compress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\decompress\zstd_decompress.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\bitstream.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\dictBuilder\divsufsort.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\error_private.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\error_public.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\fse.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\fse_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\huf.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\huf_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\mem.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\xxhash.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zbuff.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zbuff_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\dictBuilder\zdict.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\dictBuilder\zdict_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zstd.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zstd_internal.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_legacy.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\compress\zstd_opt.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\common\zstd_static.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v01.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v02.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v03.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v04.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v05.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.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>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{037E781E-81A6-494B-B1B3-438AB1200523}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>datagen</RootNamespace>
|
||||||
|
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>MultiByte</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>
|
||||||
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
<EnablePREfast>false</EnablePREfast>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
<EnablePREfast>false</EnablePREfast>
|
||||||
|
</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>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<EnablePREfast>false</EnablePREfast>
|
||||||
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
|
<EnablePREfast>false</EnablePREfast>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\..\programs\datagen.c" />
|
||||||
|
<ClCompile Include="..\..\..\programs\datagencli.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\..\programs\datagen.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<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>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\..\programs\datagen.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\programs\datagencli.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\..\programs\datagen.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
+12
-14
@@ -29,25 +29,21 @@
|
|||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
<PlatformToolset>v110</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>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</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>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</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>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -69,22 +65,24 @@
|
|||||||
<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>$(WindowsSdkDir)\include;$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath)</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<IncludePath>$(WindowsSdkDir)\include;$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath)</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<IncludePath>$(WindowsSdkDir)\include;$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath)</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<IncludePath>$(WindowsSdkDir)\include;$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath)</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
@@ -127,7 +125,8 @@
|
|||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@@ -145,8 +144,9 @@
|
|||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@@ -158,6 +158,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\..\lib\common\entropy_common.c" />
|
<ClCompile Include="..\..\..\lib\common\entropy_common.c" />
|
||||||
<ClCompile Include="..\..\..\lib\common\zstd_common.c" />
|
<ClCompile Include="..\..\..\lib\common\zstd_common.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\common\xxhash.c" />
|
||||||
<ClCompile Include="..\..\..\lib\common\fse_decompress.c" />
|
<ClCompile Include="..\..\..\lib\common\fse_decompress.c" />
|
||||||
<ClCompile Include="..\..\..\lib\compress\fse_compress.c" />
|
<ClCompile Include="..\..\..\lib\compress\fse_compress.c" />
|
||||||
<ClCompile Include="..\..\..\lib\compress\huf_compress.c" />
|
<ClCompile Include="..\..\..\lib\compress\huf_compress.c" />
|
||||||
@@ -171,14 +172,11 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\lib\common\fse.h" />
|
<ClInclude Include="..\..\..\lib\common\fse.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\fse_static.h" />
|
|
||||||
<ClInclude Include="..\..\..\lib\common\huf.h" />
|
<ClInclude Include="..\..\..\lib\common\huf.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\huf_static.h" />
|
<ClInclude Include="..\..\..\lib\common\xxhash.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff.h" />
|
<ClInclude Include="..\..\..\lib\common\zbuff.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff_static.h" />
|
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd.h" />
|
<ClInclude Include="..\..\..\lib\common\zstd.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd_internal.h" />
|
<ClInclude Include="..\..\..\lib\common\zstd_internal.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd_static.h" />
|
|
||||||
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h" />
|
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h" />
|
||||||
<ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h" />
|
<ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h" />
|
||||||
<ClInclude Include="..\..\..\programs\datagen.h" />
|
<ClInclude Include="..\..\..\programs\datagen.h" />
|
||||||
+6
-12
@@ -47,38 +47,29 @@
|
|||||||
<ClCompile Include="..\..\..\lib\common\entropy_common.c">
|
<ClCompile Include="..\..\..\lib\common\entropy_common.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\lib\common\xxhash.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\lib\common\fse.h">
|
<ClInclude Include="..\..\..\lib\common\fse.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\fse_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd.h">
|
<ClInclude Include="..\..\..\lib\common\zstd.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\programs\datagen.h">
|
<ClInclude Include="..\..\..\programs\datagen.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\huf.h">
|
<ClInclude Include="..\..\..\lib\common\huf.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\huf_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h">
|
<ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff.h">
|
<ClInclude Include="..\..\..\lib\common\zbuff.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h">
|
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -88,5 +79,8 @@
|
|||||||
<ClInclude Include="..\..\..\programs\util.h">
|
<ClInclude Include="..\..\..\programs\util.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\common\xxhash.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -28,26 +28,22 @@
|
|||||||
<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>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</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>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</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>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</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>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -69,23 +65,25 @@
|
|||||||
<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>$(WindowsSdkDir)\include;$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath)</IncludePath>
|
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<IncludePath>$(WindowsSdkDir)\include;$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath)</IncludePath>
|
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<IncludePath>$(WindowsSdkDir)\include;$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath)</IncludePath>
|
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<IncludePath>$(WindowsSdkDir)\include;$(UniversalCRT_IncludePath);$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath)</IncludePath>
|
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
@@ -127,7 +125,8 @@
|
|||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@@ -145,8 +144,9 @@
|
|||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@@ -158,30 +158,30 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\..\lib\common\entropy_common.c" />
|
<ClCompile Include="..\..\..\lib\common\entropy_common.c" />
|
||||||
<ClCompile Include="..\..\..\lib\common\fse_decompress.c" />
|
<ClCompile Include="..\..\..\lib\common\fse_decompress.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\common\xxhash.c" />
|
||||||
<ClCompile Include="..\..\..\lib\common\zstd_common.c" />
|
<ClCompile Include="..\..\..\lib\common\zstd_common.c" />
|
||||||
<ClCompile Include="..\..\..\lib\compress\fse_compress.c" />
|
<ClCompile Include="..\..\..\lib\compress\fse_compress.c" />
|
||||||
<ClCompile Include="..\..\..\lib\compress\huf_compress.c" />
|
<ClCompile Include="..\..\..\lib\compress\huf_compress.c" />
|
||||||
<ClCompile Include="..\..\..\lib\compress\zstd_compress.c" />
|
<ClCompile Include="..\..\..\lib\compress\zstd_compress.c" />
|
||||||
<ClCompile Include="..\..\..\lib\decompress\huf_decompress.c" />
|
<ClCompile Include="..\..\..\lib\decompress\huf_decompress.c" />
|
||||||
<ClCompile Include="..\..\..\lib\decompress\zstd_decompress.c" />
|
<ClCompile Include="..\..\..\lib\decompress\zstd_decompress.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\dictBuilder\divsufsort.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\dictBuilder\zdict.c" />
|
||||||
<ClCompile Include="..\..\..\programs\datagen.c" />
|
<ClCompile Include="..\..\..\programs\datagen.c" />
|
||||||
<ClCompile Include="..\..\..\programs\fuzzer.c" />
|
<ClCompile Include="..\..\..\programs\fuzzer.c" />
|
||||||
<ClCompile Include="..\..\..\programs\xxhash.c" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\lib\common\fse.h" />
|
<ClInclude Include="..\..\..\lib\common\fse.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\fse_static.h" />
|
|
||||||
<ClInclude Include="..\..\..\lib\common\huf.h" />
|
<ClInclude Include="..\..\..\lib\common\huf.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\huf_static.h" />
|
<ClInclude Include="..\..\..\lib\common\xxhash.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff.h" />
|
<ClInclude Include="..\..\..\lib\common\zbuff.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd_internal.h" />
|
<ClInclude Include="..\..\..\lib\common\zstd_internal.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff_static.h" />
|
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd.h" />
|
<ClInclude Include="..\..\..\lib\common\zstd.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd_static.h" />
|
|
||||||
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h" />
|
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\dictBuilder\divsufsort.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\dictBuilder\zdict.h" />
|
||||||
<ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h" />
|
<ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h" />
|
||||||
<ClInclude Include="..\..\..\programs\datagen.h" />
|
<ClInclude Include="..\..\..\programs\datagen.h" />
|
||||||
<ClInclude Include="..\..\..\programs\xxhash.h" />
|
|
||||||
<ClInclude Include="..\..\..\programs\util.h" />
|
<ClInclude Include="..\..\..\programs\util.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
+18
-18
@@ -14,9 +14,6 @@
|
|||||||
<ClCompile Include="..\..\..\programs\fuzzer.c">
|
<ClCompile Include="..\..\..\programs\fuzzer.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\..\programs\xxhash.c">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\programs\datagen.c">
|
<ClCompile Include="..\..\..\programs\datagen.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -44,11 +41,17 @@
|
|||||||
<ClCompile Include="..\..\..\lib\common\entropy_common.c">
|
<ClCompile Include="..\..\..\lib\common\entropy_common.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\lib\common\xxhash.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\lib\dictBuilder\divsufsort.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\lib\dictBuilder\zdict.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\programs\xxhash.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\programs\datagen.h">
|
<ClInclude Include="..\..\..\programs\datagen.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -58,35 +61,32 @@
|
|||||||
<ClInclude Include="..\..\..\lib\common\fse.h">
|
<ClInclude Include="..\..\..\lib\common\fse.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\fse_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\common\huf.h">
|
<ClInclude Include="..\..\..\lib\common\huf.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\huf_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff.h">
|
<ClInclude Include="..\..\..\lib\common\zbuff.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd_internal.h">
|
<ClInclude Include="..\..\..\lib\common\zstd_internal.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd.h">
|
<ClInclude Include="..\..\..\lib\common\zstd.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h">
|
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\programs\util.h">
|
<ClInclude Include="..\..\..\programs\util.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\common\xxhash.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\dictBuilder\divsufsort.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\dictBuilder\zdict.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -9,6 +9,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench", "fullbench\full
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zstdlib", "zstdlib\zstdlib.vcxproj", "{8BFD8150-94D5-4BF9-8A50-7BD9929A0850}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zstdlib", "zstdlib\zstdlib.vcxproj", "{8BFD8150-94D5-4BF9-8A50-7BD9929A0850}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "datagen", "datagen\datagen.vcxproj", "{037E781E-81A6-494B-B1B3-438AB1200523}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
@@ -49,6 +51,14 @@ Global
|
|||||||
{8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Release|Win32.Build.0 = 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.ActiveCfg = Release|x64
|
||||||
{8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Release|x64.Build.0 = Release|x64
|
{8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Release|x64.Build.0 = Release|x64
|
||||||
|
{037E781E-81A6-494B-B1B3-438AB1200523}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{037E781E-81A6-494B-B1B3-438AB1200523}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{037E781E-81A6-494B-B1B3-438AB1200523}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{037E781E-81A6-494B-B1B3-438AB1200523}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{037E781E-81A6-494B-B1B3-438AB1200523}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{037E781E-81A6-494B-B1B3-438AB1200523}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{037E781E-81A6-494B-B1B3-438AB1200523}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{037E781E-81A6-494B-B1B3-438AB1200523}.Release|x64.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
Executable → Regular
+21
-20
@@ -20,6 +20,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\..\lib\common\entropy_common.c" />
|
<ClCompile Include="..\..\..\lib\common\entropy_common.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\common\xxhash.c" />
|
||||||
<ClCompile Include="..\..\..\lib\common\zstd_common.c" />
|
<ClCompile Include="..\..\..\lib\common\zstd_common.c" />
|
||||||
<ClCompile Include="..\..\..\lib\common\fse_decompress.c" />
|
<ClCompile Include="..\..\..\lib\common\fse_decompress.c" />
|
||||||
<ClCompile Include="..\..\..\lib\compress\fse_compress.c" />
|
<ClCompile Include="..\..\..\lib\compress\fse_compress.c" />
|
||||||
@@ -36,27 +37,23 @@
|
|||||||
<ClCompile Include="..\..\..\lib\legacy\zstd_v03.c" />
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v03.c" />
|
||||||
<ClCompile Include="..\..\..\lib\legacy\zstd_v04.c" />
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v04.c" />
|
||||||
<ClCompile Include="..\..\..\lib\legacy\zstd_v05.c" />
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v05.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v06.c" />
|
||||||
<ClCompile Include="..\..\..\programs\bench.c" />
|
<ClCompile Include="..\..\..\programs\bench.c" />
|
||||||
<ClCompile Include="..\..\..\programs\datagen.c" />
|
<ClCompile Include="..\..\..\programs\datagen.c" />
|
||||||
<ClCompile Include="..\..\..\programs\dibio.c" />
|
<ClCompile Include="..\..\..\programs\dibio.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\zstdcli.c" />
|
<ClCompile Include="..\..\..\programs\zstdcli.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\..\lib\common\xxhash.h" />
|
||||||
<ClInclude Include="..\..\..\lib\dictBuilder\zdict.h" />
|
<ClInclude Include="..\..\..\lib\dictBuilder\zdict.h" />
|
||||||
<ClInclude Include="..\..\..\lib\dictBuilder\zdict_static.h" />
|
|
||||||
<ClInclude Include="..\..\..\lib\dictBuilder\divsufsort.h" />
|
<ClInclude Include="..\..\..\lib\dictBuilder\divsufsort.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\fse.h" />
|
<ClInclude Include="..\..\..\lib\common\fse.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\fse_static.h" />
|
|
||||||
<ClInclude Include="..\..\..\lib\common\huf.h" />
|
<ClInclude Include="..\..\..\lib\common\huf.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\huf_static.h" />
|
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff.h" />
|
<ClInclude Include="..\..\..\lib\common\zbuff.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff_static.h" />
|
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd.h" />
|
<ClInclude Include="..\..\..\lib\common\zstd.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd_internal.h" />
|
<ClInclude Include="..\..\..\lib\common\zstd_internal.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd_static.h" />
|
|
||||||
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h" />
|
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h" />
|
||||||
<ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h" />
|
<ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h" />
|
||||||
<ClInclude Include="..\..\..\lib\legacy\zstd_v01.h" />
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v01.h" />
|
||||||
@@ -64,12 +61,12 @@
|
|||||||
<ClInclude Include="..\..\..\lib\legacy\zstd_v03.h" />
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v03.h" />
|
||||||
<ClInclude Include="..\..\..\lib\legacy\zstd_v04.h" />
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v04.h" />
|
||||||
<ClInclude Include="..\..\..\lib\legacy\zstd_v05.h" />
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v05.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v06.h" />
|
||||||
<ClInclude Include="..\..\..\programs\bench.h" />
|
<ClInclude Include="..\..\..\programs\bench.h" />
|
||||||
<ClInclude Include="..\..\..\programs\datagen.h" />
|
<ClInclude Include="..\..\..\programs\datagen.h" />
|
||||||
<ClInclude Include="..\..\..\programs\dibio.h" />
|
<ClInclude Include="..\..\..\programs\dibio.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\util.h" />
|
<ClInclude Include="..\..\..\programs\util.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
@@ -82,27 +79,23 @@
|
|||||||
<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>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</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>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</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>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</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>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
@@ -123,23 +116,29 @@
|
|||||||
<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>$(WindowsSdkDir)\include;$(UniversalCRT_IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||||
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<IncludePath>$(WindowsSdkDir)\include;$(UniversalCRT_IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
<LibraryPath>$(LibraryPath);</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<IncludePath>$(WindowsSdkDir)\include;$(UniversalCRT_IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||||
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<IncludePath>$(WindowsSdkDir)\include;$(UniversalCRT_IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
|
<LibraryPath>$(LibraryPath);</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
@@ -154,6 +153,7 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>setargv.obj;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
@@ -163,12 +163,13 @@
|
|||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>false</TreatWarningAsError>
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>setargv.obj;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
@@ -176,12 +177,12 @@
|
|||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<PrecompiledHeader>
|
<PrecompiledHeader>
|
||||||
</PrecompiledHeader>
|
</PrecompiledHeader>
|
||||||
<Optimization>Full</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
@@ -189,7 +190,7 @@
|
|||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<AdditionalDependencies>setargv.obj; kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>setargv.obj;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
@@ -210,7 +211,7 @@
|
|||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<AdditionalDependencies>setargv.obj;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>setargv.obj;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
Executable → Regular
+31
-40
@@ -17,10 +17,16 @@
|
|||||||
<ClCompile Include="..\..\..\programs\fileio.c">
|
<ClCompile Include="..\..\..\programs\fileio.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\..\programs\xxhash.c">
|
<ClCompile Include="..\..\..\programs\zstdcli.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\..\programs\zstdcli.c">
|
<ClCompile Include="..\..\..\programs\dibio.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\programs\datagen.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\programs\legacy\fileio_legacy.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\..\lib\legacy\zstd_v01.c">
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v01.c">
|
||||||
@@ -29,22 +35,16 @@
|
|||||||
<ClCompile Include="..\..\..\lib\legacy\zstd_v02.c">
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v02.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\..\programs\legacy\fileio_legacy.c">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\lib\legacy\zstd_v03.c">
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v03.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\..\programs\datagen.c">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\..\lib\legacy\zstd_v04.c">
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v04.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\..\programs\dibio.c">
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v05.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\..\lib\legacy\zstd_v05.c">
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v06.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\..\lib\common\zstd_common.c">
|
<ClCompile Include="..\..\..\lib\common\zstd_common.c">
|
||||||
@@ -83,6 +83,9 @@
|
|||||||
<ClCompile Include="..\..\..\lib\common\entropy_common.c">
|
<ClCompile Include="..\..\..\lib\common\entropy_common.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\lib\common\xxhash.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\programs\bench.h">
|
<ClInclude Include="..\..\..\programs\bench.h">
|
||||||
@@ -91,28 +94,31 @@
|
|||||||
<ClInclude Include="..\..\..\programs\fileio.h">
|
<ClInclude Include="..\..\..\programs\fileio.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\programs\xxhash.h">
|
<ClInclude Include="..\..\..\programs\datagen.h">
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\legacy\zstd_v01.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\legacy\zstd_v02.h">
|
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\programs\legacy\fileio_legacy.h">
|
<ClInclude Include="..\..\..\programs\legacy\fileio_legacy.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v01.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v02.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\legacy\zstd_v03.h">
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v03.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\programs\datagen.h">
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v04.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\legacy\zstd_v04.h">
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v05.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v06.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\programs\dibio.h">
|
<ClInclude Include="..\..\..\programs\dibio.h">
|
||||||
@@ -121,47 +127,32 @@
|
|||||||
<ClInclude Include="..\..\..\lib\dictBuilder\zdict.h">
|
<ClInclude Include="..\..\..\lib\dictBuilder\zdict.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\dictBuilder\zdict_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\dictBuilder\divsufsort.h">
|
<ClInclude Include="..\..\..\lib\dictBuilder\divsufsort.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\fse.h">
|
<ClInclude Include="..\..\..\lib\common\fse.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\fse_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\common\huf.h">
|
<ClInclude Include="..\..\..\lib\common\huf.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\huf_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff.h">
|
<ClInclude Include="..\..\..\lib\common\zbuff.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd.h">
|
<ClInclude Include="..\..\..\lib\common\zstd.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd_internal.h">
|
<ClInclude Include="..\..\..\lib\common\zstd_internal.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h">
|
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\legacy\zstd_v05.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\programs\util.h">
|
<ClInclude Include="..\..\..\programs\util.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\common\xxhash.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
// Microsoft Visual C++ generated resource script.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "zstd.h" /* ZSTD_VERSION_STRING */
|
||||||
|
#define APSTUDIO_READONLY_SYMBOLS
|
||||||
|
#include "verrsrc.h"
|
||||||
|
#undef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||||
|
LANGUAGE 9, 1
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Version
|
||||||
|
//
|
||||||
|
|
||||||
|
VS_VERSION_INFO VERSIONINFO
|
||||||
|
FILEVERSION ZSTD_LIB_VERSION
|
||||||
|
PRODUCTVERSION ZSTD_LIB_VERSION
|
||||||
|
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FILEFLAGS VS_FF_DEBUG
|
||||||
|
#else
|
||||||
|
FILEFLAGS 0x0L
|
||||||
|
#endif
|
||||||
|
FILEOS VOS_NT_WINDOWS32
|
||||||
|
FILETYPE VFT_DLL
|
||||||
|
FILESUBTYPE VFT2_UNKNOWN
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904B0"
|
||||||
|
BEGIN
|
||||||
|
VALUE "CompanyName", "Yann Collet"
|
||||||
|
VALUE "FileDescription", "Fast and efficient compression algorithm"
|
||||||
|
VALUE "FileVersion", ZSTD_VERSION_STRING
|
||||||
|
VALUE "InternalName", "zstdlib.dll"
|
||||||
|
VALUE "LegalCopyright", "Copyright (C) 2013-2015, Yann Collet"
|
||||||
|
VALUE "OriginalFilename", "zstdlib.dll"
|
||||||
|
VALUE "ProductName", "Zstandard"
|
||||||
|
VALUE "ProductVersion", ZSTD_VERSION_STRING
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x0409, 1200
|
||||||
|
END
|
||||||
|
END
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\..\lib\common\entropy_common.c" />
|
<ClCompile Include="..\..\..\lib\common\entropy_common.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\common\xxhash.c" />
|
||||||
<ClCompile Include="..\..\..\lib\common\zstd_common.c" />
|
<ClCompile Include="..\..\..\lib\common\zstd_common.c" />
|
||||||
<ClCompile Include="..\..\..\lib\common\fse_decompress.c" />
|
<ClCompile Include="..\..\..\lib\common\fse_decompress.c" />
|
||||||
<ClCompile Include="..\..\..\lib\compress\fse_compress.c" />
|
<ClCompile Include="..\..\..\lib\compress\fse_compress.c" />
|
||||||
@@ -36,17 +37,13 @@
|
|||||||
<ClInclude Include="..\..\..\lib\common\error_public.h" />
|
<ClInclude Include="..\..\..\lib\common\error_public.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\mem.h" />
|
<ClInclude Include="..\..\..\lib\common\mem.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\fse.h" />
|
<ClInclude Include="..\..\..\lib\common\fse.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\fse_static.h" />
|
|
||||||
<ClInclude Include="..\..\..\lib\common\huf.h" />
|
<ClInclude Include="..\..\..\lib\common\huf.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\huf_static.h" />
|
<ClInclude Include="..\..\..\lib\common\xxhash.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff.h" />
|
<ClInclude Include="..\..\..\lib\common\zbuff.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff_static.h" />
|
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd.h" />
|
<ClInclude Include="..\..\..\lib\common\zstd.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd_internal.h" />
|
<ClInclude Include="..\..\..\lib\common\zstd_internal.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd_static.h" />
|
|
||||||
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h" />
|
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h" />
|
||||||
<ClInclude Include="..\..\..\programs\util.h" />
|
<ClInclude Include="..\..\..\programs\util.h" />
|
||||||
<ClInclude Include="resource.h" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="zstdlib.rc" />
|
<ResourceCompile Include="zstdlib.rc" />
|
||||||
@@ -61,27 +58,23 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
@@ -104,28 +97,28 @@
|
|||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<TargetName>zstdlib_x86</TargetName>
|
<TargetName>zstdlib_x86</TargetName>
|
||||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
<IncludePath>$(WindowsSdkDir)\include;$(UniversalCRT_IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<TargetName>zstdlib_x64</TargetName>
|
<TargetName>zstdlib_x64</TargetName>
|
||||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
<IncludePath>$(WindowsSdkDir)\include;$(UniversalCRT_IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<TargetName>zstdlib_x86</TargetName>
|
<TargetName>zstdlib_x86</TargetName>
|
||||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
<IncludePath>$(WindowsSdkDir)\include;$(UniversalCRT_IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<TargetName>zstdlib_x64</TargetName>
|
<TargetName>zstdlib_x64</TargetName>
|
||||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
<IncludePath>$(WindowsSdkDir)\include;$(UniversalCRT_IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
@@ -155,7 +148,7 @@
|
|||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>false</TreatWarningAsError>
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
@@ -176,7 +169,7 @@
|
|||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<AssemblerOutput>All</AssemblerOutput>
|
<AssemblerOutput>All</AssemblerOutput>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -199,7 +192,7 @@
|
|||||||
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>false</TreatWarningAsError>
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<OmitFramePointers>true</OmitFramePointers>
|
<OmitFramePointers>true</OmitFramePointers>
|
||||||
+7
-22
@@ -9,10 +9,6 @@
|
|||||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
</Filter>
|
</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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\..\lib\common\zstd_common.c">
|
<ClCompile Include="..\..\..\lib\common\zstd_common.c">
|
||||||
@@ -51,11 +47,11 @@
|
|||||||
<ClCompile Include="..\..\..\lib\common\entropy_common.c">
|
<ClCompile Include="..\..\..\lib\common\entropy_common.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\lib\common\xxhash.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="resource.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\common\bitstream.h">
|
<ClInclude Include="..\..\..\lib\common\bitstream.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -71,40 +67,29 @@
|
|||||||
<ClInclude Include="..\..\..\lib\common\fse.h">
|
<ClInclude Include="..\..\..\lib\common\fse.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\fse_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\common\huf.h">
|
<ClInclude Include="..\..\..\lib\common\huf.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\huf_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff.h">
|
<ClInclude Include="..\..\..\lib\common\zbuff.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd.h">
|
<ClInclude Include="..\..\..\lib\common\zstd.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd_internal.h">
|
<ClInclude Include="..\..\..\lib\common\zstd_internal.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd_static.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h">
|
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\programs\util.h">
|
<ClInclude Include="..\..\..\programs\util.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\lib\common\xxhash.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="zstdlib.rc">
|
<ResourceCompile Include="zstdlib.rc" />
|
||||||
<Filter>Resource Files</Filter>
|
|
||||||
</ResourceCompile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
Here are a few command lines for reference :
|
||||||
|
|
||||||
|
### Build with Visual Studio 2013 for msvcr120.dll
|
||||||
|
|
||||||
|
Running the following command will build both the `Release Win32` and `Release x64` versions:
|
||||||
|
```batch
|
||||||
|
build\build.VS2013.cmd
|
||||||
|
```
|
||||||
|
The result of each build will be in the corresponding `build\bin\Release\{ARCH}\` folder.
|
||||||
|
|
||||||
|
If you want to only need one architecture:
|
||||||
|
- Win32: `build\build.generic.cmd VS2013 Win32 Release v120`
|
||||||
|
- x64: `build\build.generic.cmd VS2013 x64 Release v120`
|
||||||
|
|
||||||
|
If you want a Debug build:
|
||||||
|
- Win32: `build\build.generic.cmd VS2013 Win32 Debug v120`
|
||||||
|
- x64: `build\build.generic.cmd VS2013 x64 Debug v120`
|
||||||
|
|
||||||
|
### Build with Visual Studio 2015 for msvcr140.dll
|
||||||
|
|
||||||
|
Running the following command will build both the `Release Win32` and `Release x64` versions:
|
||||||
|
```batch
|
||||||
|
build\build.VS2015.cmd
|
||||||
|
```
|
||||||
|
The result of each build will be in the corresponding `build\bin\Release\{ARCH}\` folder.
|
||||||
|
|
||||||
|
If you want to only need one architecture:
|
||||||
|
- Win32: `build\build.generic.cmd VS2015 Win32 Release v140`
|
||||||
|
- x64: `build\build.generic.cmd VS2015 x64 Release v140`
|
||||||
|
|
||||||
|
If you want a Debug build:
|
||||||
|
- Win32: `build\build.generic.cmd VS2015 Win32 Debug v140`
|
||||||
|
- x64: `build\build.generic.cmd VS2015 x64 Debug v140`
|
||||||
|
|
||||||
|
### Build with Visual Studio 2015 for msvcr120.dll
|
||||||
|
|
||||||
|
You need to invoke `build\build.generic.cmd` with the proper arguments:
|
||||||
|
|
||||||
|
**For Win32**
|
||||||
|
```batch
|
||||||
|
build\build.generic.cmd VS2015 Win32 Release v120
|
||||||
|
```
|
||||||
|
The result of the build will be in the `build\bin\Release\Win32\` folder.
|
||||||
|
|
||||||
|
**For x64**
|
||||||
|
```batch
|
||||||
|
build\build.generic.cmd VS2015 x64 Release v120
|
||||||
|
```
|
||||||
|
The result of the build will be in the `build\bin\Release\x64\` folder.
|
||||||
|
|
||||||
|
If you want Debug builds, replace `Release` with `Debug`.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
rem build 32-bit
|
||||||
|
call "%~p0%build.generic.cmd" VS2010 Win32 Release v100
|
||||||
|
|
||||||
|
rem build 64-bit
|
||||||
|
call "%~p0%build.generic.cmd" VS2010 x64 Release v100
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
rem build 32-bit
|
||||||
|
call "%~p0%build.generic.cmd" VS2012 Win32 Release v110
|
||||||
|
rem build 64-bit
|
||||||
|
call "%~p0%build.generic.cmd" VS2012 x64 Release v110
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
rem build 32-bit
|
||||||
|
call "%~p0%build.generic.cmd" VS2013 Win32 Release v120
|
||||||
|
|
||||||
|
rem build 64-bit
|
||||||
|
call "%~p0%build.generic.cmd" VS2013 x64 Release v120
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
rem build 32-bit
|
||||||
|
call "%~p0%build.generic.cmd" VS2015 Win32 Release v140
|
||||||
|
|
||||||
|
rem build 64-bit
|
||||||
|
call "%~p0%build.generic.cmd" VS2015 x64 Release v140
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
IF "%1%" == "" GOTO display_help
|
||||||
|
|
||||||
|
SETLOCAL
|
||||||
|
|
||||||
|
SET msbuild_version=%1
|
||||||
|
|
||||||
|
SET msbuild_platform=%2
|
||||||
|
IF "%msbuild_platform%" == "" SET msbuild_platform=x64
|
||||||
|
|
||||||
|
SET msbuild_configuration=%3
|
||||||
|
IF "%msbuild_configuration%" == "" SET msbuild_configuration=Release
|
||||||
|
|
||||||
|
SET msbuild_toolset=%4
|
||||||
|
|
||||||
|
GOTO build
|
||||||
|
|
||||||
|
:display_help
|
||||||
|
|
||||||
|
echo Syntax: build.generic.cmd msbuild_version msbuild_platform msbuild_configuration msbuild_toolset
|
||||||
|
echo msbuild_version: VS installed version (VS2012, VS2013, VS2015, ...)
|
||||||
|
echo msbuild_platform: Platform (x64 or Win32)
|
||||||
|
echo msbuild_configuration: VS configuration (Release or Debug)
|
||||||
|
echo msbuild_toolset: Platform Toolset (v100, v110, v120, v140)
|
||||||
|
|
||||||
|
EXIT /B 1
|
||||||
|
|
||||||
|
:build
|
||||||
|
|
||||||
|
SET msbuild="%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe"
|
||||||
|
IF %msbuild_version% == VS2013 SET msbuild="%programfiles(x86)%\MSBuild\12.0\Bin\MSBuild.exe"
|
||||||
|
IF %msbuild_version% == VS2015 SET msbuild="%programfiles(x86)%\MSBuild\14.0\Bin\MSBuild.exe"
|
||||||
|
rem TODO: Visual Studio "15" (vNext) will use MSBuild 15.0 ?
|
||||||
|
|
||||||
|
SET project="%~p0\..\VS2010\zstd.sln"
|
||||||
|
|
||||||
|
SET msbuild_params=/verbosity:minimal /nologo /t:Clean,Build /p:Platform=%msbuild_platform% /p:Configuration=%msbuild_configuration%
|
||||||
|
IF NOT "%msbuild_toolset%" == "" SET msbuild_params=%msbuild_params% /p:PlatformToolset=%msbuild_toolset%
|
||||||
|
|
||||||
|
SET output=%~p0%bin
|
||||||
|
SET output="%output%/%msbuild_configuration%/%msbuild_platform%/"
|
||||||
|
SET msbuild_params=%msbuild_params% /p:OutDir=%output%
|
||||||
|
|
||||||
|
echo ### Building %msbuild_version% project for %msbuild_configuration% %msbuild_platform% (%msbuild_toolset%)...
|
||||||
|
echo ### Build Params: %msbuild_params%
|
||||||
|
|
||||||
|
%msbuild% %project% %msbuild_params%
|
||||||
|
IF ERRORLEVEL 1 EXIT /B 1
|
||||||
|
echo # Success
|
||||||
|
echo # OutDir: %output%
|
||||||
|
echo #
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# cmake producted
|
||||||
|
CMakeCache.txt
|
||||||
|
CMakeFiles
|
||||||
|
Makefile
|
||||||
|
cmake_install.cmake
|
||||||
|
cmake_uninstall.cmake
|
||||||
@@ -44,13 +44,6 @@ ELSE (ZSTD_LEGACY_SUPPORT)
|
|||||||
ADD_DEFINITIONS(-DZSTD_LEGACY_SUPPORT=0)
|
ADD_DEFINITIONS(-DZSTD_LEGACY_SUPPORT=0)
|
||||||
ENDIF (ZSTD_LEGACY_SUPPORT)
|
ENDIF (ZSTD_LEGACY_SUPPORT)
|
||||||
|
|
||||||
# TARGET_INCLUDE_DIRECTORIES can use in version 2.8.11 and greate
|
|
||||||
IF ((${CMAKE_MAJOR_VERSION} EQUAL 2) AND (${CMAKE_MINOR_VERSION} EQUAL 8) AND (${CMAKE_PATCH_VERSION} LESS 11))
|
|
||||||
SET(WORKAROUND_OUTDATED_CODE_STYLE TRUE)
|
|
||||||
ELSE ()
|
|
||||||
SET(WORKAROUND_OUTDATED_CODE_STYLE FALSE)
|
|
||||||
ENDIF ((${CMAKE_MAJOR_VERSION} EQUAL 2) AND (${CMAKE_MINOR_VERSION} EQUAL 8) AND (${CMAKE_PATCH_VERSION} LESS 11))
|
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(lib)
|
ADD_SUBDIRECTORY(lib)
|
||||||
ADD_SUBDIRECTORY(programs)
|
ADD_SUBDIRECTORY(programs)
|
||||||
|
|
||||||
@@ -59,3 +52,8 @@ ADD_SUBDIRECTORY(programs)
|
|||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
INCLUDE(CMakeModules/AddExtraCompilationFlags.cmake)
|
INCLUDE(CMakeModules/AddExtraCompilationFlags.cmake)
|
||||||
ADD_EXTRA_COMPILATION_FLAGS()
|
ADD_EXTRA_COMPILATION_FLAGS()
|
||||||
|
|
||||||
|
ADD_CUSTOM_TARGET(clean-all
|
||||||
|
COMMAND ${CMAKE_BUILD_TOOL} clean
|
||||||
|
COMMAND rm -rf ${CMAKE_BINARY_DIR}/
|
||||||
|
)
|
||||||
@@ -59,6 +59,7 @@ MESSAGE("ZSTD VERSION ${LIBVER_MAJOR}.${LIBVER_MINOR}.${LIBVER_RELEASE}")
|
|||||||
SET(Sources
|
SET(Sources
|
||||||
${LIBRARY_DIR}/common/entropy_common.c
|
${LIBRARY_DIR}/common/entropy_common.c
|
||||||
${LIBRARY_DIR}/common/zstd_common.c
|
${LIBRARY_DIR}/common/zstd_common.c
|
||||||
|
${LIBRARY_DIR}/common/xxhash.c
|
||||||
${LIBRARY_DIR}/common/fse_decompress.c
|
${LIBRARY_DIR}/common/fse_decompress.c
|
||||||
${LIBRARY_DIR}/compress/fse_compress.c
|
${LIBRARY_DIR}/compress/fse_compress.c
|
||||||
${LIBRARY_DIR}/compress/huf_compress.c
|
${LIBRARY_DIR}/compress/huf_compress.c
|
||||||
@@ -75,17 +76,12 @@ SET(Headers
|
|||||||
${LIBRARY_DIR}/common/error_private.h
|
${LIBRARY_DIR}/common/error_private.h
|
||||||
${LIBRARY_DIR}/common/error_public.h
|
${LIBRARY_DIR}/common/error_public.h
|
||||||
${LIBRARY_DIR}/common/fse.h
|
${LIBRARY_DIR}/common/fse.h
|
||||||
${LIBRARY_DIR}/common/fse_static.h
|
|
||||||
${LIBRARY_DIR}/common/huf.h
|
${LIBRARY_DIR}/common/huf.h
|
||||||
${LIBRARY_DIR}/common/huf_static.h
|
|
||||||
${LIBRARY_DIR}/common/mem.h
|
${LIBRARY_DIR}/common/mem.h
|
||||||
${LIBRARY_DIR}/common/zbuff.h
|
${LIBRARY_DIR}/common/zbuff.h
|
||||||
${LIBRARY_DIR}/common/zbuff_static.h
|
|
||||||
${LIBRARY_DIR}/common/zstd_internal.h
|
${LIBRARY_DIR}/common/zstd_internal.h
|
||||||
${LIBRARY_DIR}/common/zstd_static.h
|
|
||||||
${LIBRARY_DIR}/common/zstd.h
|
${LIBRARY_DIR}/common/zstd.h
|
||||||
${LIBRARY_DIR}/dictBuilder/zdict.h
|
${LIBRARY_DIR}/dictBuilder/zdict.h)
|
||||||
${LIBRARY_DIR}/dictBuilder/zdict_static.h)
|
|
||||||
|
|
||||||
IF (ZSTD_LEGACY_SUPPORT)
|
IF (ZSTD_LEGACY_SUPPORT)
|
||||||
SET(LIBRARY_LEGACY_DIR ${LIBRARY_DIR}/legacy)
|
SET(LIBRARY_LEGACY_DIR ${LIBRARY_DIR}/legacy)
|
||||||
@@ -95,19 +91,23 @@ IF (ZSTD_LEGACY_SUPPORT)
|
|||||||
${LIBRARY_LEGACY_DIR}/zstd_v01.c
|
${LIBRARY_LEGACY_DIR}/zstd_v01.c
|
||||||
${LIBRARY_LEGACY_DIR}/zstd_v02.c
|
${LIBRARY_LEGACY_DIR}/zstd_v02.c
|
||||||
${LIBRARY_LEGACY_DIR}/zstd_v03.c
|
${LIBRARY_LEGACY_DIR}/zstd_v03.c
|
||||||
${LIBRARY_LEGACY_DIR}/zstd_v04.c)
|
${LIBRARY_LEGACY_DIR}/zstd_v04.c
|
||||||
|
${LIBRARY_LEGACY_DIR}/zstd_v05.c
|
||||||
|
${LIBRARY_LEGACY_DIR}/zstd_v06.c)
|
||||||
|
|
||||||
SET(Headers ${Headers}
|
SET(Headers ${Headers}
|
||||||
${LIBRARY_LEGACY_DIR}/zstd_legacy.h
|
${LIBRARY_LEGACY_DIR}/zstd_legacy.h
|
||||||
${LIBRARY_LEGACY_DIR}/zstd_v01.h
|
${LIBRARY_LEGACY_DIR}/zstd_v01.h
|
||||||
${LIBRARY_LEGACY_DIR}/zstd_v02.h
|
${LIBRARY_LEGACY_DIR}/zstd_v02.h
|
||||||
${LIBRARY_LEGACY_DIR}/zstd_v03.h
|
${LIBRARY_LEGACY_DIR}/zstd_v03.h
|
||||||
${LIBRARY_LEGACY_DIR}/zstd_v04.h)
|
${LIBRARY_LEGACY_DIR}/zstd_v04.h
|
||||||
|
${LIBRARY_LEGACY_DIR}/zstd_v05.h
|
||||||
|
${LIBRARY_LEGACY_DIR}/zstd_v06.h)
|
||||||
ENDIF (ZSTD_LEGACY_SUPPORT)
|
ENDIF (ZSTD_LEGACY_SUPPORT)
|
||||||
|
|
||||||
IF (MSVC)
|
IF (MSVC)
|
||||||
SET(MSVC_RESOURCE_DIR ${ROOT_DIR}/visual/2013/zstdlib)
|
SET(MSVC_RESOURCE_DIR ${ROOT_DIR}/projects/VS2010/zstdlib)
|
||||||
SET(PlatformDependResources ${MSVC_RESOURCE_DIR}/resource.h ${MSVC_RESOURCE_DIR}/zstdlib.rc)
|
SET(PlatformDependResources ${MSVC_RESOURCE_DIR}/zstdlib.rc)
|
||||||
ENDIF (MSVC)
|
ENDIF (MSVC)
|
||||||
|
|
||||||
# Split project to static and shared libraries build
|
# Split project to static and shared libraries build
|
||||||
@@ -120,24 +120,12 @@ IF (MSVC)
|
|||||||
SET_TARGET_PROPERTIES(libzstd_shared PROPERTIES COMPILE_DEFINITIONS "ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;_CONSOLE;_CRT_SECURE_NO_WARNINGS")
|
SET_TARGET_PROPERTIES(libzstd_shared PROPERTIES COMPILE_DEFINITIONS "ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;_CONSOLE;_CRT_SECURE_NO_WARNINGS")
|
||||||
ENDIF (MSVC)
|
ENDIF (MSVC)
|
||||||
|
|
||||||
# Define include directories
|
|
||||||
IF (NOT WORKAROUND_OUTDATED_CODE_STYLE)
|
|
||||||
TARGET_INCLUDE_DIRECTORIES(libzstd_static PUBLIC ${LIBRARY_DIR}/common)
|
|
||||||
TARGET_INCLUDE_DIRECTORIES(libzstd_shared PUBLIC ${LIBRARY_DIR}/common)
|
|
||||||
IF (ZSTD_LEGACY_SUPPORT)
|
|
||||||
TARGET_INCLUDE_DIRECTORIES(libzstd_static PUBLIC ${LIBRARY_LEGACY_DIR})
|
|
||||||
TARGET_INCLUDE_DIRECTORIES(libzstd_shared PUBLIC ${LIBRARY_LEGACY_DIR})
|
|
||||||
ENDIF (ZSTD_LEGACY_SUPPORT)
|
|
||||||
ENDIF (NOT WORKAROUND_OUTDATED_CODE_STYLE)
|
|
||||||
|
|
||||||
# Define library base name
|
# Define library base name
|
||||||
IF (UNIX)
|
IF (MSVC)
|
||||||
SET(LIBRARY_BASE_NAME libzstd)
|
|
||||||
ELSEIF (MSVC)
|
|
||||||
SET(LIBRARY_BASE_NAME zstdlib)
|
SET(LIBRARY_BASE_NAME zstdlib)
|
||||||
ELSE ()
|
ELSE ()
|
||||||
MESSAGE(FATAL_ERROR "Unsupported build type")
|
SET(LIBRARY_BASE_NAME libzstd)
|
||||||
ENDIF (UNIX)
|
ENDIF (MSVC)
|
||||||
|
|
||||||
# Define static and shared library names
|
# Define static and shared library names
|
||||||
SET(STATIC_LIBRARY_OUTPUT_NAME ${LIBRARY_BASE_NAME})
|
SET(STATIC_LIBRARY_OUTPUT_NAME ${LIBRARY_BASE_NAME})
|
||||||
@@ -166,12 +154,15 @@ SET_TARGET_PROPERTIES(
|
|||||||
OUTPUT_NAME ${SHARED_LIBRARY_OUTPUT_NAME})
|
OUTPUT_NAME ${SHARED_LIBRARY_OUTPUT_NAME})
|
||||||
|
|
||||||
IF (UNIX)
|
IF (UNIX)
|
||||||
SET(PREFIX /usr/local)
|
IF ("${PREFIX}" STREQUAL "")
|
||||||
|
SET(PREFIX /usr/local)
|
||||||
|
ENDIF()
|
||||||
|
MESSAGE("the variable PREFIX=${PREFIX}")
|
||||||
SET(INSTALL_LIBRARY_DIR ${PREFIX}/lib)
|
SET(INSTALL_LIBRARY_DIR ${PREFIX}/lib)
|
||||||
SET(INSTALL_INCLUDE_DIR ${PREFIX}/include)
|
SET(INSTALL_INCLUDE_DIR ${PREFIX}/include)
|
||||||
|
|
||||||
# install target
|
# install target
|
||||||
INSTALL(FILES ${LIBRARY_DIR}/zstd.h ${LIBRARY_DIR}/zstd_buffered.h ${LIBRARY_DIR}/dictBuilder.h DESTINATION ${INSTALL_INCLUDE_DIR})
|
INSTALL(FILES ${LIBRARY_DIR}/common/zstd.h ${LIBRARY_DIR}/common/zbuff.h ${LIBRARY_DIR}/dictBuilder/zdict.h DESTINATION ${INSTALL_INCLUDE_DIR})
|
||||||
INSTALL(TARGETS libzstd_static DESTINATION ${INSTALL_LIBRARY_DIR})
|
INSTALL(TARGETS libzstd_static DESTINATION ${INSTALL_LIBRARY_DIR})
|
||||||
INSTALL(TARGETS libzstd_shared LIBRARY DESTINATION ${INSTALL_LIBRARY_DIR})
|
INSTALL(TARGETS libzstd_shared LIBRARY DESTINATION ${INSTALL_LIBRARY_DIR})
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# produced by make
|
||||||
|
datagen
|
||||||
|
fullbench
|
||||||
|
fuzzer
|
||||||
|
paramgrill
|
||||||
|
zbufftest
|
||||||
|
zstd
|
||||||
|
zstd-frugal
|
||||||
@@ -38,33 +38,23 @@ SET(CMAKE_INCLUDE_CURRENT_DIR TRUE)
|
|||||||
SET(ROOT_DIR ../../..)
|
SET(ROOT_DIR ../../..)
|
||||||
|
|
||||||
# Define programs directory, where sources and header files are located
|
# Define programs directory, where sources and header files are located
|
||||||
|
SET(LIBRARY_DIR ${ROOT_DIR}/lib)
|
||||||
SET(PROGRAMS_DIR ${ROOT_DIR}/programs)
|
SET(PROGRAMS_DIR ${ROOT_DIR}/programs)
|
||||||
INCLUDE_DIRECTORIES(${PROGRAMS_DIR})
|
INCLUDE_DIRECTORIES(${PROGRAMS_DIR} ${LIBRARY_DIR}/common ${LIBRARY_DIR}/dictBuilder)
|
||||||
|
|
||||||
IF (WORKAROUND_OUTDATED_CODE_STYLE)
|
|
||||||
# Define library directory, where sources and header files are located
|
|
||||||
SET(LIBRARY_DIR ${ROOT_DIR}/lib)
|
|
||||||
INCLUDE_DIRECTORIES(${LIBRARY_DIR}/common)
|
|
||||||
ENDIF (WORKAROUND_OUTDATED_CODE_STYLE)
|
|
||||||
|
|
||||||
IF (ZSTD_LEGACY_SUPPORT)
|
IF (ZSTD_LEGACY_SUPPORT)
|
||||||
SET(PROGRAMS_LEGACY_DIR ${PROGRAMS_DIR}/legacy)
|
SET(PROGRAMS_LEGACY_DIR ${PROGRAMS_DIR}/legacy)
|
||||||
INCLUDE_DIRECTORIES(${PROGRAMS_LEGACY_DIR})
|
INCLUDE_DIRECTORIES(${PROGRAMS_LEGACY_DIR} ${LIBRARY_DIR}/legacy)
|
||||||
|
|
||||||
IF (WORKAROUND_OUTDATED_CODE_STYLE)
|
|
||||||
INCLUDE_DIRECTORIES(${LIBRARY_DIR}/legacy)
|
|
||||||
ENDIF (WORKAROUND_OUTDATED_CODE_STYLE)
|
|
||||||
|
|
||||||
SET(ZSTD_FILEIO_LEGACY ${PROGRAMS_LEGACY_DIR}/fileio_legacy.c)
|
SET(ZSTD_FILEIO_LEGACY ${PROGRAMS_LEGACY_DIR}/fileio_legacy.c)
|
||||||
ENDIF (ZSTD_LEGACY_SUPPORT)
|
ENDIF (ZSTD_LEGACY_SUPPORT)
|
||||||
|
|
||||||
ADD_EXECUTABLE(zstd ${PROGRAMS_DIR}/zstdcli.c ${PROGRAMS_DIR}/fileio.c ${PROGRAMS_DIR}/bench.c ${PROGRAMS_DIR}/xxhash.c ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/dibio.c ${ZSTD_FILEIO_LEGACY})
|
ADD_EXECUTABLE(zstd ${PROGRAMS_DIR}/zstdcli.c ${PROGRAMS_DIR}/fileio.c ${PROGRAMS_DIR}/bench.c ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/dibio.c ${ZSTD_FILEIO_LEGACY})
|
||||||
TARGET_LINK_LIBRARIES(zstd libzstd_static)
|
TARGET_LINK_LIBRARIES(zstd libzstd_static)
|
||||||
|
|
||||||
ADD_EXECUTABLE(fullbench ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/fullbench.c)
|
ADD_EXECUTABLE(fullbench ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/fullbench.c)
|
||||||
TARGET_LINK_LIBRARIES(fullbench libzstd_static)
|
TARGET_LINK_LIBRARIES(fullbench libzstd_static)
|
||||||
|
|
||||||
ADD_EXECUTABLE(fuzzer ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/xxhash.c ${PROGRAMS_DIR}/fuzzer.c)
|
ADD_EXECUTABLE(fuzzer ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/fuzzer.c)
|
||||||
TARGET_LINK_LIBRARIES(fuzzer libzstd_static)
|
TARGET_LINK_LIBRARIES(fuzzer libzstd_static)
|
||||||
|
|
||||||
IF (UNIX)
|
IF (UNIX)
|
||||||
@@ -72,10 +62,10 @@ IF (UNIX)
|
|||||||
TARGET_LINK_LIBRARIES(zstd-frugal libzstd_static)
|
TARGET_LINK_LIBRARIES(zstd-frugal libzstd_static)
|
||||||
SET_TARGET_PROPERTIES(zstd-frugal PROPERTIES COMPILE_DEFINITIONS "ZSTD_NOBENCH;ZSTD_NODICT")
|
SET_TARGET_PROPERTIES(zstd-frugal PROPERTIES COMPILE_DEFINITIONS "ZSTD_NOBENCH;ZSTD_NODICT")
|
||||||
|
|
||||||
ADD_EXECUTABLE(zbufftest ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/xxhash.c ${PROGRAMS_DIR}/zbufftest.c)
|
ADD_EXECUTABLE(zbufftest ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/zbufftest.c)
|
||||||
TARGET_LINK_LIBRARIES(zbufftest libzstd_static)
|
TARGET_LINK_LIBRARIES(zbufftest libzstd_static)
|
||||||
|
|
||||||
ADD_EXECUTABLE(paramgrill ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/xxhash.c ${PROGRAMS_DIR}/paramgrill.c)
|
ADD_EXECUTABLE(paramgrill ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/paramgrill.c)
|
||||||
TARGET_LINK_LIBRARIES(paramgrill libzstd_static m) #m is math library
|
TARGET_LINK_LIBRARIES(paramgrill libzstd_static m) #m is math library
|
||||||
|
|
||||||
ADD_EXECUTABLE(datagen ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/datagencli.c)
|
ADD_EXECUTABLE(datagen ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/datagencli.c)
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Tmp test directory
|
||||||
|
zstdtest
|
||||||
|
speedTest
|
||||||
|
versionsTest
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# ##########################################################################
|
||||||
|
# Zstd tests - Makefile
|
||||||
|
# Based on LZ4 version test, by Takayuki Matsuoka - 2015-2016
|
||||||
|
#
|
||||||
|
# GPL v2 License
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
#
|
||||||
|
# You can contact the author at :
|
||||||
|
# - ZSTD homepage : http://www.zstd.net/
|
||||||
|
# ##########################################################################
|
||||||
|
# versionstest : Compatibility test between zstd versions stored on Github (v0.1+)
|
||||||
|
# ##########################################################################
|
||||||
|
|
||||||
|
PYTHON?= python3
|
||||||
|
TESTDIR := zstdtest
|
||||||
|
|
||||||
|
.PHONY: default all clean versionsTest
|
||||||
|
|
||||||
|
default: all
|
||||||
|
|
||||||
|
all: versionsTest
|
||||||
|
|
||||||
|
versionsTest:
|
||||||
|
$(PYTHON) test-zstd-versions.py
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -fR $(TESTDIR)
|
||||||
|
@echo Cleaning completed
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
scripts for automated testing of zstd
|
||||||
|
================================
|
||||||
|
|
||||||
|
#### test-zstd-versions.py - script for testing zstd interoperability between versions
|
||||||
|
|
||||||
|
This script creates `versionsTest` directory to which zstd repository is cloned.
|
||||||
|
Then all taged (released) versions of zstd are compiled.
|
||||||
|
In the following step interoperability between zstd versions is checked.
|
||||||
|
|
||||||
|
|
||||||
|
#### test-zstd-speed.py - script for testing zstd speed difference between commits
|
||||||
|
|
||||||
|
This script creates `speedTest` directory to which zstd repository is cloned.
|
||||||
|
Then it compiles all branches of zstd and performs a speed benchmark for a given list of files (the `testFileNames` parameter).
|
||||||
|
After `sleepTime` (an optional parameter, default 300 seconds) seconds the script checks repository for new commits.
|
||||||
|
If a new commit is found it is compiled and a speed benchmark for this commit is performed.
|
||||||
|
The results of the speed benchmark are compared to the previous results.
|
||||||
|
If compression or decompression speed for one of zstd levels is lower than `lowerLimit` (an optional parameter, default 0.98) the speed benchmark is restarted.
|
||||||
|
If second results are also lower than `lowerLimit` the warning e-mail is send to recipients from the list (the `emails` parameter).
|
||||||
|
|
||||||
|
Additional remarks:
|
||||||
|
- To be sure that speed results are accurate the script should be run on a "stable" target system with no other jobs running in parallel
|
||||||
|
- Using the script with virtual machines can lead to large variations of speed results
|
||||||
|
- The speed benchmark is not performed until computers' load average is lower than `maxLoadAvg` (an optional parameter, default 0.75)
|
||||||
|
- The script sends e-mails using `mutt`; if `mutt` is not available it sends e-mails without attachments using `mail`; if both are not available it only prints a warning
|
||||||
|
|
||||||
|
|
||||||
|
The example usage with two test files, one e-mail address, and with an additional message:
|
||||||
|
```
|
||||||
|
./test-zstd-speed.py "silesia.tar calgary.tar" "email@gmail.com" --message "tested on my laptop" --sleepTime 60
|
||||||
|
```
|
||||||
|
|
||||||
|
To run the script in background please use:
|
||||||
|
```
|
||||||
|
nohup ./test-zstd-speed.py testFileNames emails &
|
||||||
|
```
|
||||||
|
|
||||||
|
The full list of parameters:
|
||||||
|
```
|
||||||
|
positional arguments:
|
||||||
|
testFileNames file names list for speed benchmark
|
||||||
|
emails list of e-mail addresses to send warnings
|
||||||
|
|
||||||
|
optional arguments:
|
||||||
|
-h, --help show this help message and exit
|
||||||
|
--message MESSAGE attach an additional message to e-mail
|
||||||
|
--lowerLimit LOWERLIMIT
|
||||||
|
send email if speed is lower than given limit
|
||||||
|
--maxLoadAvg MAXLOADAVG
|
||||||
|
maximum load average to start testing
|
||||||
|
--lastCLevel LASTCLEVEL
|
||||||
|
last compression level for testing
|
||||||
|
--sleepTime SLEEPTIME
|
||||||
|
frequency of repository checking in seconds
|
||||||
|
```
|
||||||
Executable
+249
@@ -0,0 +1,249 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
# execute(), fetch(), notify() are based on https://github.com/getlantern/build-automation/blob/master/build.py
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import string
|
||||||
|
import time
|
||||||
|
import traceback
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
|
||||||
|
repo_url = 'https://github.com/Cyan4973/zstd.git'
|
||||||
|
test_dir_name = 'speedTest'
|
||||||
|
|
||||||
|
|
||||||
|
def log(text):
|
||||||
|
print time.strftime("%Y/%m/%d %H:%M:%S") + ' - ' + text
|
||||||
|
|
||||||
|
def execute(command, print_output=False, print_error=True):
|
||||||
|
log("> " + command)
|
||||||
|
popen = Popen(command, stdout=PIPE, stderr=PIPE, shell=True, cwd=execute.cwd)
|
||||||
|
itout = iter(popen.stdout.readline, b"")
|
||||||
|
iterr = iter(popen.stderr.readline, b"")
|
||||||
|
stdout_lines = list(itout)
|
||||||
|
if print_output:
|
||||||
|
print ''.join(stdout_lines)
|
||||||
|
stderr_lines = list(iterr)
|
||||||
|
if print_output:
|
||||||
|
print ''.join(stderr_lines)
|
||||||
|
popen.communicate()
|
||||||
|
if popen.returncode is not None and popen.returncode != 0:
|
||||||
|
if not print_output and print_error:
|
||||||
|
print ''.join(stderr_lines)
|
||||||
|
raise RuntimeError(''.join(stderr_lines))
|
||||||
|
return stdout_lines + stderr_lines
|
||||||
|
execute.cwd = None
|
||||||
|
|
||||||
|
|
||||||
|
def does_command_exist(command):
|
||||||
|
try:
|
||||||
|
execute(command, False, False);
|
||||||
|
except Exception as e:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def fetch():
|
||||||
|
execute('git fetch -p')
|
||||||
|
output = execute('git branch -rl')
|
||||||
|
for line in output:
|
||||||
|
if "HEAD" in line:
|
||||||
|
output.remove(line) # remove "origin/HEAD -> origin/dev"
|
||||||
|
branches = map(lambda l: l.strip(), output)
|
||||||
|
return map(lambda b: (b, execute('git show -s --format=%h ' + b)[0].strip()), branches)
|
||||||
|
|
||||||
|
|
||||||
|
def notify(branch, commit, last_commit):
|
||||||
|
text_tmpl = string.Template('Changes since $last_commit:\r\n$commits')
|
||||||
|
branch = branch.split('/')[1]
|
||||||
|
fmt = '--format="%h: (%an) %s, %ar"'
|
||||||
|
if last_commit is None:
|
||||||
|
commits = execute('git log -n 10 %s %s' % (fmt, commit))
|
||||||
|
else:
|
||||||
|
commits = execute('git --no-pager log %s %s..%s' % (fmt, last_commit, commit))
|
||||||
|
|
||||||
|
text = text_tmpl.substitute({'last_commit': last_commit, 'commits': ''.join(commits)})
|
||||||
|
print str("commits for %s: %s" % (commit, text))
|
||||||
|
|
||||||
|
|
||||||
|
def compile(branch, commit, dry_run):
|
||||||
|
local_branch = string.split(branch, '/')[1]
|
||||||
|
version = local_branch.rpartition('-')[2]
|
||||||
|
version = version + '_' + commit
|
||||||
|
execute('git checkout -- . && git checkout ' + branch)
|
||||||
|
if not dry_run:
|
||||||
|
execute('VERSION=' + version + '; make clean zstdprogram')
|
||||||
|
|
||||||
|
|
||||||
|
def get_last_commit(resultsFileName):
|
||||||
|
if not os.path.isfile(resultsFileName):
|
||||||
|
return None, None, None
|
||||||
|
commit = None
|
||||||
|
cspeed = []
|
||||||
|
dspeed = []
|
||||||
|
with open(resultsFileName,'r') as f:
|
||||||
|
for line in f:
|
||||||
|
words = line.split()
|
||||||
|
if len(words) == 2: # branch + commit
|
||||||
|
commit = words[1];
|
||||||
|
cspeed = []
|
||||||
|
dspeed = []
|
||||||
|
if (len(words) == 8):
|
||||||
|
cspeed.append(float(words[3]))
|
||||||
|
dspeed.append(float(words[5]))
|
||||||
|
#if commit != None:
|
||||||
|
# print "commit=%s cspeed=%s dspeed=%s" % (commit, cspeed, dspeed)
|
||||||
|
return commit, cspeed, dspeed
|
||||||
|
|
||||||
|
|
||||||
|
def benchmark_and_compare(branch, commit, resultsFileName, lastCLevel, testFilePath, fileName, last_cspeed, last_dspeed, lower_limit, maxLoadAvg, message):
|
||||||
|
sleepTime = 30
|
||||||
|
while os.getloadavg()[0] > maxLoadAvg:
|
||||||
|
log("WARNING: bench loadavg=%.2f is higher than %s, sleeping for %s seconds" % (os.getloadavg()[0], maxLoadAvg, sleepTime))
|
||||||
|
time.sleep(sleepTime)
|
||||||
|
start_load = str(os.getloadavg())
|
||||||
|
result = execute('programs/zstd -qi5b1e' + str(lastCLevel) + ' ' + testFilePath)
|
||||||
|
end_load = str(os.getloadavg())
|
||||||
|
linesExpected = lastCLevel + 2;
|
||||||
|
if len(result) != linesExpected:
|
||||||
|
log("ERROR: number of result lines=%d is different that expected %d" % (len(result), linesExpected))
|
||||||
|
return ""
|
||||||
|
with open(resultsFileName, "a") as myfile:
|
||||||
|
myfile.write(branch + " " + commit + "\n")
|
||||||
|
myfile.writelines(result)
|
||||||
|
myfile.close()
|
||||||
|
if (last_cspeed == None):
|
||||||
|
return ""
|
||||||
|
commit, cspeed, dspeed = get_last_commit(resultsFileName)
|
||||||
|
text = ""
|
||||||
|
for i in range(0, min(len(cspeed), len(last_cspeed))):
|
||||||
|
if (cspeed[i]/last_cspeed[i] < lower_limit):
|
||||||
|
text += "WARNING: File=%s level=%d cspeed=%s last=%s diff=%s\n" % (fileName, i+1, cspeed[i], last_cspeed[i], cspeed[i]/last_cspeed[i])
|
||||||
|
if (dspeed[i]/last_dspeed[i] < lower_limit):
|
||||||
|
text += "WARNING: File=%s level=%d dspeed=%s last=%s diff=%s\n" % (fileName, i+1, dspeed[i], last_dspeed[i], dspeed[i]/last_dspeed[i])
|
||||||
|
if text:
|
||||||
|
text = message + ("\nmaxLoadAvg=%s load average at start=%s end=%s\n" % (maxLoadAvg, start_load, end_load)) + text
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def send_email(branch, commit, last_commit, emails, text, results_files, logFileName, lower_limit, have_mutt, have_mail):
|
||||||
|
with open(logFileName, "w") as myfile:
|
||||||
|
myfile.writelines(text)
|
||||||
|
myfile.close()
|
||||||
|
if have_mutt:
|
||||||
|
execute("mutt -s \"[ZSTD_speedTest] Warning for branch=" + branch + " commit=" + commit + " last_commit=" + last_commit + " speed<" + str(lower_limit) + "\" " + emails + " -a " + results_files + " < " + logFileName)
|
||||||
|
elif have_mail:
|
||||||
|
execute("mail -s \"[ZSTD_speedTest] Warning for branch=" + branch + " commit=" + commit + " last_commit=" + last_commit + " speed<" + str(lower_limit) + "\" " + emails + " < " + logFileName)
|
||||||
|
else:
|
||||||
|
log("e-mail cannot be sent (mail and mutt not found)")
|
||||||
|
|
||||||
|
|
||||||
|
def check_branches(args, test_path, testFilePaths, have_mutt, have_mail):
|
||||||
|
for branch, commit in fetch():
|
||||||
|
try:
|
||||||
|
commitFileName = test_path + "/commit_" + branch.replace("/", "_")
|
||||||
|
if os.path.isfile(commitFileName):
|
||||||
|
last_commit = file(commitFileName, 'r').read()
|
||||||
|
else:
|
||||||
|
last_commit = None
|
||||||
|
file(commitFileName, 'w').write(commit)
|
||||||
|
|
||||||
|
if commit == last_commit:
|
||||||
|
log("skipping branch %s: head %s already processed" % (branch, commit))
|
||||||
|
else:
|
||||||
|
log("build branch %s: head %s is different from prev %s" % (branch, commit, last_commit))
|
||||||
|
compile(branch, commit, args.dry_run)
|
||||||
|
|
||||||
|
logFileName = test_path + "/log_" + branch.replace("/", "_")
|
||||||
|
text_to_send = []
|
||||||
|
results_files = ""
|
||||||
|
for filePath in testFilePaths:
|
||||||
|
fileName = filePath.rpartition('/')[2]
|
||||||
|
resultsFileName = test_path + "/results_" + branch.replace("/", "_") + "_" + fileName
|
||||||
|
last_commit, cspeed, dspeed = get_last_commit(resultsFileName)
|
||||||
|
|
||||||
|
if not args.dry_run:
|
||||||
|
text = benchmark_and_compare(branch, commit, resultsFileName, args.lastCLevel, filePath, fileName, cspeed, dspeed, args.lowerLimit, args.maxLoadAvg, args.message)
|
||||||
|
if text:
|
||||||
|
text = benchmark_and_compare(branch, commit, resultsFileName, args.lastCLevel, filePath, fileName, cspeed, dspeed, args.lowerLimit, args.maxLoadAvg, args.message)
|
||||||
|
if text:
|
||||||
|
text_to_send.append(text)
|
||||||
|
results_files += resultsFileName + " "
|
||||||
|
if text_to_send:
|
||||||
|
send_email(branch, commit, last_commit, args.emails, text_to_send, results_files, logFileName, args.lowerLimit, have_mutt, have_mail)
|
||||||
|
notify(branch, commit, last_commit)
|
||||||
|
except Exception as e:
|
||||||
|
stack = traceback.format_exc()
|
||||||
|
log("ERROR: build %s, error %s" % (branch, str(e)) )
|
||||||
|
print stack
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('testFileNames', help='file names list for speed benchmark')
|
||||||
|
parser.add_argument('emails', help='list of e-mail addresses to send warnings')
|
||||||
|
parser.add_argument('--message', help='attach an additional message to e-mail', default="")
|
||||||
|
parser.add_argument('--lowerLimit', type=float, help='send email if speed is lower than given limit', default=0.98)
|
||||||
|
parser.add_argument('--maxLoadAvg', type=float, help='maximum load average to start testing', default=0.75)
|
||||||
|
parser.add_argument('--lastCLevel', type=int, help='last compression level for testing', default=5)
|
||||||
|
parser.add_argument('--sleepTime', type=int, help='frequency of repository checking in seconds', default=300)
|
||||||
|
parser.add_argument('--dry-run', dest='dry_run', action='store_true', help='not build', default=False)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# check if test files are accessible
|
||||||
|
testFileNames = args.testFileNames.split()
|
||||||
|
testFilePaths = []
|
||||||
|
for fileName in testFileNames:
|
||||||
|
if os.path.isfile(fileName):
|
||||||
|
testFilePaths.append(os.path.abspath(fileName))
|
||||||
|
else:
|
||||||
|
raise RuntimeError("File not found: " + fileName)
|
||||||
|
|
||||||
|
test_path = os.getcwd() + '/' + test_dir_name # /path/to/zstd/tests/speedTest
|
||||||
|
clone_path = test_path + '/' + 'zstd' # /path/to/zstd/tests/speedTest/zstd
|
||||||
|
|
||||||
|
# check availability of e-mail senders
|
||||||
|
have_mutt = does_command_exist("mutt --help");
|
||||||
|
have_mail = does_command_exist("mail -V");
|
||||||
|
if not have_mutt and not have_mail:
|
||||||
|
log("WARNING: e-mail senders mail and mutt not found")
|
||||||
|
|
||||||
|
# clone ZSTD repo if needed
|
||||||
|
if not os.path.isdir(test_path):
|
||||||
|
os.mkdir(test_path)
|
||||||
|
if not os.path.isdir(clone_path):
|
||||||
|
execute.cwd = test_path
|
||||||
|
execute('git clone ' + repo_url)
|
||||||
|
if not os.path.isdir(clone_path):
|
||||||
|
raise RuntimeError("ZSTD clone not found: " + clone_path)
|
||||||
|
execute.cwd = clone_path
|
||||||
|
|
||||||
|
print "PARAMETERS:\ntest_path=%s" % test_path
|
||||||
|
print "clone_path=%s" % clone_path
|
||||||
|
print "testFilePath(%s)=%s" % (len(testFilePaths), testFilePaths)
|
||||||
|
print "message=%s" % args.message
|
||||||
|
print "emails=%s" % args.emails
|
||||||
|
print "maxLoadAvg=%s" % args.maxLoadAvg
|
||||||
|
print "lowerLimit=%s" % args.lowerLimit
|
||||||
|
print "lastCLevel=%s" % args.lastCLevel
|
||||||
|
print "sleepTime=%s" % args.sleepTime
|
||||||
|
print "dry_run=%s" % args.dry_run
|
||||||
|
print "have_mutt=%s have_mail=%s" % (have_mutt, have_mail)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
pid = str(os.getpid())
|
||||||
|
pidfile = "./speedTest.pid"
|
||||||
|
if os.path.isfile(pidfile):
|
||||||
|
log("%s already exists, exiting" % pidfile)
|
||||||
|
else:
|
||||||
|
file(pidfile, 'w').write(pid)
|
||||||
|
try:
|
||||||
|
loadavg = os.getloadavg()[0]
|
||||||
|
if (loadavg <= args.maxLoadAvg):
|
||||||
|
check_branches(args, test_path, testFilePaths, have_mutt, have_mail)
|
||||||
|
else:
|
||||||
|
log("WARNING: main loadavg=%.2f is higher than %s" % (loadavg, args.maxLoadAvg))
|
||||||
|
finally:
|
||||||
|
os.unlink(pidfile)
|
||||||
|
log("sleep for %s seconds" % args.sleepTime)
|
||||||
|
time.sleep(args.sleepTime)
|
||||||
Executable
+173
@@ -0,0 +1,173 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Test zstd interoperability between versions"""
|
||||||
|
# Based on LZ4 version test script, by Takayuki Matsuoka
|
||||||
|
|
||||||
|
import filecmp
|
||||||
|
import glob
|
||||||
|
import hashlib
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
repo_url = 'https://github.com/Cyan4973/zstd.git'
|
||||||
|
tmp_dir_name = 'tests/versionsTest'
|
||||||
|
make_cmd = 'make'
|
||||||
|
git_cmd = 'git'
|
||||||
|
test_dat_src = 'README.md'
|
||||||
|
test_dat = 'test_dat'
|
||||||
|
head = 'vdevel'
|
||||||
|
|
||||||
|
|
||||||
|
def proc(cmd_args, pipe=True, dummy=False):
|
||||||
|
if dummy:
|
||||||
|
return
|
||||||
|
if pipe:
|
||||||
|
subproc = subprocess.Popen(cmd_args,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE)
|
||||||
|
else:
|
||||||
|
subproc = subprocess.Popen(cmd_args)
|
||||||
|
return subproc.communicate()
|
||||||
|
|
||||||
|
|
||||||
|
def make(args, pipe=True):
|
||||||
|
return proc([make_cmd] + args, pipe)
|
||||||
|
|
||||||
|
|
||||||
|
def git(args, pipe=True):
|
||||||
|
return proc([git_cmd] + args, pipe)
|
||||||
|
|
||||||
|
|
||||||
|
def get_git_tags():
|
||||||
|
stdout, stderr = git(['tag', '-l', 'v[0-9].[0-9].[0-9]'])
|
||||||
|
tags = stdout.decode('utf-8').split()
|
||||||
|
return tags
|
||||||
|
|
||||||
|
|
||||||
|
def compress_sample(tag, sample):
|
||||||
|
try:
|
||||||
|
from subprocess import DEVNULL # py3k
|
||||||
|
except ImportError:
|
||||||
|
DEVNULL = open(os.devnull, 'wb')
|
||||||
|
if subprocess.call(['./zstd.' + tag, '-f', sample], stderr=DEVNULL) == 0:
|
||||||
|
os.rename(sample + '.zst', sample + '_01_64_' + tag + '.zst')
|
||||||
|
if subprocess.call(['./zstd.' + tag, '-5f', sample], stderr=DEVNULL) == 0:
|
||||||
|
os.rename(sample + '.zst', sample + '_05_64_' + tag + '.zst')
|
||||||
|
if subprocess.call(['./zstd.' + tag, '-9f', sample], stderr=DEVNULL) == 0:
|
||||||
|
os.rename(sample + '.zst', sample + '_09_64_' + tag + '.zst')
|
||||||
|
if subprocess.call(['./zstd.' + tag, '-15f', sample], stderr=DEVNULL) == 0:
|
||||||
|
os.rename(sample + '.zst', sample + '_15_64_' + tag + '.zst')
|
||||||
|
if subprocess.call(['./zstd.' + tag, '-18f', sample], stderr=DEVNULL) == 0:
|
||||||
|
os.rename(sample + '.zst', sample + '_18_64_' + tag + '.zst')
|
||||||
|
# zstdFiles = glob.glob("*.zst*")
|
||||||
|
# print(zstdFiles)
|
||||||
|
print(tag + " : compression completed")
|
||||||
|
|
||||||
|
|
||||||
|
# http://stackoverflow.com/a/19711609/2132223
|
||||||
|
def sha1_of_file(filepath):
|
||||||
|
with open(filepath, 'rb') as f:
|
||||||
|
return hashlib.sha1(f.read()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def remove_duplicates():
|
||||||
|
list_of_zst = sorted(glob.glob('*.zst'))
|
||||||
|
for i, ref_zst in enumerate(list_of_zst):
|
||||||
|
if not os.path.isfile(ref_zst):
|
||||||
|
continue
|
||||||
|
for j in range(i + 1, len(list_of_zst)):
|
||||||
|
compared_zst = list_of_zst[j]
|
||||||
|
if not os.path.isfile(compared_zst):
|
||||||
|
continue
|
||||||
|
if filecmp.cmp(ref_zst, compared_zst):
|
||||||
|
os.remove(compared_zst)
|
||||||
|
print('duplicated : {} == {}'.format(ref_zst, compared_zst))
|
||||||
|
|
||||||
|
|
||||||
|
def decompress_zst(tag):
|
||||||
|
dec_error = 0
|
||||||
|
list_zst = sorted(glob.glob('*.zst'))
|
||||||
|
try:
|
||||||
|
from subprocess import DEVNULL # py3k
|
||||||
|
except ImportError:
|
||||||
|
DEVNULL = open(os.devnull, 'wb')
|
||||||
|
for file_zst in list_zst:
|
||||||
|
print(file_zst, end=' ')
|
||||||
|
print(tag, end=' ')
|
||||||
|
file_dec = file_zst + '_d64_' + tag + '.dec'
|
||||||
|
if subprocess.call(['./zstd.' + tag, '-df', file_zst, '-o', file_dec], stderr=DEVNULL) == 0:
|
||||||
|
if not filecmp.cmp(file_dec, test_dat):
|
||||||
|
print('ERR !! ')
|
||||||
|
dec_error = 1
|
||||||
|
else:
|
||||||
|
print('OK ')
|
||||||
|
else:
|
||||||
|
print('command does not work')
|
||||||
|
return dec_error
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
error_code = 0
|
||||||
|
base_dir = os.getcwd() + '/..' # /path/to/zstd
|
||||||
|
tmp_dir = base_dir + '/' + tmp_dir_name # /path/to/zstd/tests/versionsTest
|
||||||
|
clone_dir = tmp_dir + '/' + 'zstd' # /path/to/zstd/tests/versionsTest/zstd
|
||||||
|
programs_dir = base_dir + '/programs' # /path/to/zstd/programs
|
||||||
|
os.makedirs(tmp_dir, exist_ok=True)
|
||||||
|
|
||||||
|
# since Travis clones limited depth, we should clone full repository
|
||||||
|
if not os.path.isdir(clone_dir):
|
||||||
|
git(['clone', repo_url, clone_dir])
|
||||||
|
|
||||||
|
shutil.copy2(base_dir + '/' + test_dat_src, tmp_dir + '/' + test_dat)
|
||||||
|
|
||||||
|
# Retrieve all release tags
|
||||||
|
print('Retrieve all release tags :')
|
||||||
|
os.chdir(clone_dir)
|
||||||
|
tags = get_git_tags() + [head]
|
||||||
|
print(tags)
|
||||||
|
|
||||||
|
# Build all release zstd
|
||||||
|
for tag in tags:
|
||||||
|
os.chdir(base_dir)
|
||||||
|
dst_zstd = '{}/zstd.{}'.format(tmp_dir, tag) # /path/to/zstd/tests/versionsTest/zstd.<TAG>
|
||||||
|
if not os.path.isfile(dst_zstd) or tag == head:
|
||||||
|
if tag != head:
|
||||||
|
r_dir = '{}/{}'.format(tmp_dir, tag) # /path/to/zstd/tests/versionsTest/<TAG>
|
||||||
|
os.makedirs(r_dir, exist_ok=True)
|
||||||
|
os.chdir(clone_dir)
|
||||||
|
git(['--work-tree=' + r_dir, 'checkout', tag, '--', '.'], False)
|
||||||
|
os.chdir(r_dir + '/programs') # /path/to/zstd/tests/versionsTest/<TAG>/programs
|
||||||
|
make(['clean', 'zstd'], False)
|
||||||
|
else:
|
||||||
|
os.chdir(programs_dir)
|
||||||
|
make(['zstd'], False)
|
||||||
|
shutil.copy2('zstd', dst_zstd)
|
||||||
|
|
||||||
|
# remove any remaining *.zst and *.dec from previous test
|
||||||
|
os.chdir(tmp_dir)
|
||||||
|
for compressed in glob.glob("*.zst"):
|
||||||
|
os.remove(compressed)
|
||||||
|
for dec in glob.glob("*.dec"):
|
||||||
|
os.remove(dec)
|
||||||
|
|
||||||
|
print('Compress test.dat by all released zstd')
|
||||||
|
|
||||||
|
error_code = 0
|
||||||
|
for tag in tags:
|
||||||
|
print(tag)
|
||||||
|
compress_sample(tag, test_dat)
|
||||||
|
remove_duplicates()
|
||||||
|
if tag >= 'v0.5.1':
|
||||||
|
error_code += decompress_zst(tag)
|
||||||
|
|
||||||
|
print('')
|
||||||
|
print('Enumerate different compressed files')
|
||||||
|
zstds = sorted(glob.glob('*.zst'))
|
||||||
|
for zstd in zstds:
|
||||||
|
print(zstd + ' : ' + repr(os.path.getsize(zstd)) + ', ' + sha1_of_file(zstd))
|
||||||
|
|
||||||
|
if error_code != 0:
|
||||||
|
print('==== ERROR !!! =====')
|
||||||
|
|
||||||
|
sys.exit(error_code)
|
||||||
Binary file not shown.
Binary file not shown.
@@ -19,6 +19,9 @@
|
|||||||
|
|
||||||
# Default result files
|
# Default result files
|
||||||
_*
|
_*
|
||||||
|
example
|
||||||
|
example_zstd
|
||||||
|
foo.gz
|
||||||
|
|
||||||
# Misc files
|
# Misc files
|
||||||
*.bat
|
*.bat
|
||||||
|
|||||||
+19
-12
@@ -6,23 +6,25 @@
|
|||||||
|
|
||||||
|
|
||||||
# Paths to static and dynamic zlib and zstd libraries
|
# Paths to static and dynamic zlib and zstd libraries
|
||||||
ifneq (,$(filter Windows%,$(OS)))
|
# Use "make ZLIBDIR=path/to/zlib" to select a path to library
|
||||||
STATICLIB = ../../zlib/libz.a ../lib/libzstd.a
|
ifdef ZLIBDIR
|
||||||
IMPLIB = ../../zlib/libz.dll.a ../lib/libzstd.a
|
STATICLIB = $(ZLIBDIR)/libz.a ../lib/libzstd.a
|
||||||
|
IMPLIB = $(ZLIBDIR)/libz.dll.a ../lib/libzstd.a
|
||||||
else
|
else
|
||||||
STATICLIB = -static -lz ../lib/libzstd.a
|
STATICLIB = -static -lz ../lib/libzstd.a
|
||||||
IMPLIB = -lz ../lib/libzstd.a
|
IMPLIB = -lz ../lib/libzstd.a
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ZLIBWRAPPER_PATH = .
|
ZLIBWRAPPER_PATH = .
|
||||||
EXAMPLE_PATH = examples/
|
EXAMPLE_PATH = examples
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = $(LOC) -I../lib/common -I$(ZLIBWRAPPER_PATH) -O3 -Wall -std=gnu89
|
CFLAGS = $(LOC) -I../lib/common -I$(ZLIBDIR) -I$(ZLIBWRAPPER_PATH) -O3 -std=gnu90
|
||||||
|
CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef
|
||||||
LDFLAGS = $(LOC)
|
LDFLAGS = $(LOC)
|
||||||
RM = rm -f
|
RM = rm -f
|
||||||
|
|
||||||
|
|
||||||
all: example example_d
|
all: clean test testzstd
|
||||||
|
|
||||||
test: example
|
test: example
|
||||||
./example
|
./example
|
||||||
@@ -30,6 +32,9 @@ test: example
|
|||||||
testdll: example_d
|
testdll: example_d
|
||||||
./example_d
|
./example_d
|
||||||
|
|
||||||
|
testzstd: example_zstd
|
||||||
|
./example_zstd
|
||||||
|
|
||||||
.c.o:
|
.c.o:
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
@@ -39,16 +44,18 @@ example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o
|
|||||||
example_d: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o
|
example_d: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o
|
||||||
$(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(IMPLIB)
|
$(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(IMPLIB)
|
||||||
|
|
||||||
|
example_zstd: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(STATICLIB)
|
||||||
|
|
||||||
$(EXAMPLE_PATH)/example.o: $(EXAMPLE_PATH)/example.c
|
$(EXAMPLE_PATH)/example.o: $(EXAMPLE_PATH)/example.c
|
||||||
$(CC) $(CFLAGS) -I. -c -o $@ $(EXAMPLE_PATH)/example.c
|
$(CC) $(CFLAGS) -I. -c -o $@ $(EXAMPLE_PATH)/example.c
|
||||||
|
|
||||||
$(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.h
|
$(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.h
|
||||||
$(CC) $(CFLAGS) -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c
|
$(CC) $(CFLAGS) -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c
|
||||||
|
|
||||||
clean:
|
$(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.h
|
||||||
-$(RM) $(ZLIBWRAPPER_PATH)/*.o
|
$(CC) $(CFLAGS) -DZWRAP_USE_ZSTD=1 -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c
|
||||||
-$(RM) $(EXAMPLE_PATH)/*.o
|
|
||||||
-$(RM) *.o
|
|
||||||
-$(RM) *.exe
|
|
||||||
-$(RM) foo.gz
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_d example_zstd
|
||||||
|
@echo Cleaning completed
|
||||||
|
|||||||
@@ -61,12 +61,15 @@ void *myalloc(q, n, m)
|
|||||||
void *q;
|
void *q;
|
||||||
unsigned n, m;
|
unsigned n, m;
|
||||||
{
|
{
|
||||||
|
void *buf = calloc(n, m);
|
||||||
q = Z_NULL;
|
q = Z_NULL;
|
||||||
return calloc(n, m);
|
/* printf("myalloc %p n=%d m=%d\n", buf, n, m); */
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void myfree(void *q, void *p)
|
void myfree(void *q, void *p)
|
||||||
{
|
{
|
||||||
|
/* printf("myfree %p\n", p); */
|
||||||
q = Z_NULL;
|
q = Z_NULL;
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|||||||
+219
-143
@@ -29,30 +29,35 @@
|
|||||||
- zstd source repository : https://github.com/Cyan4973/zstd
|
- zstd source repository : https://github.com/Cyan4973/zstd
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h> /* fprintf */
|
#include <stdarg.h> /* va_list, for z_gzprintf */
|
||||||
#include <stdlib.h> /* malloc */
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include "zstd_zlibwrapper.h"
|
#include "zstd_zlibwrapper.h"
|
||||||
|
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_MAGICNUMBER */
|
||||||
#include "zstd.h"
|
#include "zstd.h"
|
||||||
#include "zstd_static.h" /* ZSTD_MAGICNUMBER */
|
#define ZBUFF_STATIC_LINKING_ONLY /* ZBUFF_createCCtx_advanced */
|
||||||
#include "zstd_internal.h" /* MIN */
|
|
||||||
#include "zbuff.h"
|
#include "zbuff.h"
|
||||||
|
#include "zstd_internal.h" /* defaultCustomMem */
|
||||||
|
|
||||||
|
|
||||||
#define Z_INFLATE_SYNC 8
|
#define Z_INFLATE_SYNC 8
|
||||||
#define ZWRAP_HEADERSIZE 4
|
#define ZWRAP_HEADERSIZE 4
|
||||||
#define ZSTD_FRAMEHEADERSIZE_MIN 5
|
#define ZWRAP_DEFAULT_CLEVEL 5 /* Z_DEFAULT_COMPRESSION is translated to ZWRAP_DEFAULT_CLEVEL for zstd */
|
||||||
|
|
||||||
#define LOG_WRAPPER(...) // printf(__VA_ARGS__)
|
#define LOG_WRAPPER(...) // printf(__VA_ARGS__)
|
||||||
|
|
||||||
|
|
||||||
#define FINISH_WITH_ERR(msg) { \
|
#define FINISH_WITH_GZ_ERR(msg) { \
|
||||||
fprintf(stderr, "ERROR: %s\n", msg); \
|
(void)msg; \
|
||||||
|
return Z_MEM_ERROR; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FINISH_WITH_ERR(strm, message) { \
|
||||||
|
strm->msg = message; \
|
||||||
return Z_MEM_ERROR; \
|
return Z_MEM_ERROR; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FINISH_WITH_NULL_ERR(msg) { \
|
#define FINISH_WITH_NULL_ERR(msg) { \
|
||||||
fprintf(stderr, "ERROR: %s\n", msg); \
|
(void)msg; \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,13 +71,29 @@ static int g_useZSTD = ZWRAP_USE_ZSTD; /* 0 = don't use ZSTD */
|
|||||||
|
|
||||||
void useZSTD(int turn_on) { g_useZSTD = turn_on; }
|
void useZSTD(int turn_on) { g_useZSTD = turn_on; }
|
||||||
|
|
||||||
int isUsingZSTD() { return g_useZSTD; }
|
int isUsingZSTD(void) { return g_useZSTD; }
|
||||||
|
|
||||||
const char * zstdVersion() { return ZSTD_VERSION_STRING; }
|
const char * zstdVersion(void) { return ZSTD_VERSION_STRING; }
|
||||||
|
|
||||||
ZEXTERN const char * ZEXPORT z_zlibVersion OF((void)) { return zlibVersion(); }
|
ZEXTERN const char * ZEXPORT z_zlibVersion OF((void)) { return zlibVersion(); }
|
||||||
|
|
||||||
|
|
||||||
|
static void* ZWRAP_allocFunction(void* opaque, size_t size)
|
||||||
|
{
|
||||||
|
z_streamp strm = (z_streamp) opaque;
|
||||||
|
void* address = strm->zalloc(strm->opaque, 1, size);
|
||||||
|
/* printf("ZWRAP alloc %p, %d \n", address, (int)size); */
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ZWRAP_freeFunction(void* opaque, void* address)
|
||||||
|
{
|
||||||
|
z_streamp strm = (z_streamp) opaque;
|
||||||
|
strm->zfree(strm->opaque, address);
|
||||||
|
/* if (address) printf("ZWRAP free %p \n", address); */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *** Compression *** */
|
/* *** Compression *** */
|
||||||
|
|
||||||
@@ -80,28 +101,45 @@ typedef struct {
|
|||||||
ZBUFF_CCtx* zbc;
|
ZBUFF_CCtx* zbc;
|
||||||
size_t bytesLeft;
|
size_t bytesLeft;
|
||||||
int compressionLevel;
|
int compressionLevel;
|
||||||
|
ZSTD_customMem customMem;
|
||||||
|
z_stream allocFunc; /* copy of zalloc, zfree, opaque */
|
||||||
} ZWRAP_CCtx;
|
} ZWRAP_CCtx;
|
||||||
|
|
||||||
|
|
||||||
ZWRAP_CCtx* ZWRAP_createCCtx()
|
|
||||||
{
|
|
||||||
ZWRAP_CCtx* zwc = (ZWRAP_CCtx*)malloc(sizeof(ZWRAP_CCtx));
|
|
||||||
if (zwc==NULL) return NULL;
|
|
||||||
memset(zwc, 0, sizeof(*zwc));
|
|
||||||
zwc->zbc = ZBUFF_createCCtx();
|
|
||||||
return zwc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t ZWRAP_freeCCtx(ZWRAP_CCtx* zwc)
|
size_t ZWRAP_freeCCtx(ZWRAP_CCtx* zwc)
|
||||||
{
|
{
|
||||||
if (zwc==NULL) return 0; /* support free on NULL */
|
if (zwc==NULL) return 0; /* support free on NULL */
|
||||||
ZBUFF_freeCCtx(zwc->zbc);
|
ZBUFF_freeCCtx(zwc->zbc);
|
||||||
free(zwc);
|
zwc->customMem.customFree(zwc->customMem.opaque, zwc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ZWRAP_CCtx* ZWRAP_createCCtx(z_streamp strm)
|
||||||
|
{
|
||||||
|
ZWRAP_CCtx* zwc;
|
||||||
|
|
||||||
|
if (strm->zalloc && strm->zfree) {
|
||||||
|
zwc = (ZWRAP_CCtx*)strm->zalloc(strm->opaque, 1, sizeof(ZWRAP_CCtx));
|
||||||
|
if (zwc==NULL) return NULL;
|
||||||
|
memset(zwc, 0, sizeof(ZWRAP_CCtx));
|
||||||
|
memcpy(&zwc->allocFunc, strm, sizeof(z_stream));
|
||||||
|
{ ZSTD_customMem ZWRAP_customMem = { ZWRAP_allocFunction, ZWRAP_freeFunction, &zwc->allocFunc };
|
||||||
|
memcpy(&zwc->customMem, &ZWRAP_customMem, sizeof(ZSTD_customMem));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
zwc = (ZWRAP_CCtx*)defaultCustomMem.customAlloc(defaultCustomMem.opaque, sizeof(ZWRAP_CCtx));
|
||||||
|
if (zwc==NULL) return NULL;
|
||||||
|
memset(zwc, 0, sizeof(ZWRAP_CCtx));
|
||||||
|
memcpy(&zwc->customMem, &defaultCustomMem, sizeof(ZSTD_customMem));
|
||||||
|
}
|
||||||
|
|
||||||
|
zwc->zbc = ZBUFF_createCCtx_advanced(zwc->customMem);
|
||||||
|
if (zwc->zbc == NULL) { ZWRAP_freeCCtx(zwc); return NULL; }
|
||||||
|
return zwc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level,
|
ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level,
|
||||||
const char *version, int stream_size))
|
const char *version, int stream_size))
|
||||||
{
|
{
|
||||||
@@ -113,21 +151,24 @@ ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level,
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOG_WRAPPER("- deflateInit level=%d\n", level);
|
LOG_WRAPPER("- deflateInit level=%d\n", level);
|
||||||
zwc = ZWRAP_createCCtx();
|
zwc = ZWRAP_createCCtx(strm);
|
||||||
if (zwc == NULL) return Z_MEM_ERROR;
|
if (zwc == NULL) return Z_MEM_ERROR;
|
||||||
|
|
||||||
|
if (level == Z_DEFAULT_COMPRESSION)
|
||||||
|
level = ZWRAP_DEFAULT_CLEVEL;
|
||||||
|
|
||||||
{ size_t const errorCode = ZBUFF_compressInit(zwc->zbc, level);
|
{ size_t const errorCode = ZBUFF_compressInit(zwc->zbc, level);
|
||||||
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; }
|
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; }
|
||||||
|
|
||||||
zwc->compressionLevel = level;
|
zwc->compressionLevel = level;
|
||||||
strm->opaque = (voidpf) zwc;
|
strm->state = (struct internal_state*) zwc; /* use state which in not used by user */
|
||||||
strm->total_in = 0;
|
strm->total_in = 0;
|
||||||
strm->total_out = 0;
|
strm->total_out = 0;
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_deflateInit2_ OF((z_streamp strm, int level, int method,
|
ZEXTERN int ZEXPORT z_deflateInit2_ OF((z_streamp strm, int level, int method,
|
||||||
int windowBits, int memLevel,
|
int windowBits, int memLevel,
|
||||||
int strategy, const char *version,
|
int strategy, const char *version,
|
||||||
int stream_size))
|
int stream_size))
|
||||||
@@ -146,7 +187,7 @@ ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm,
|
|||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return deflateSetDictionary(strm, dictionary, dictLength);
|
return deflateSetDictionary(strm, dictionary, dictLength);
|
||||||
|
|
||||||
{ ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->opaque;
|
{ ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
|
||||||
LOG_WRAPPER("- deflateSetDictionary level=%d\n", (int)strm->data_type);
|
LOG_WRAPPER("- deflateSetDictionary level=%d\n", (int)strm->data_type);
|
||||||
{ size_t const errorCode = ZBUFF_compressInitDictionary(zwc->zbc, dictionary, dictLength, zwc->compressionLevel);
|
{ size_t const errorCode = ZBUFF_compressInitDictionary(zwc->zbc, dictionary, dictLength, zwc->compressionLevel);
|
||||||
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; }
|
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; }
|
||||||
@@ -166,7 +207,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush))
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
zwc = (ZWRAP_CCtx*) strm->opaque;
|
zwc = (ZWRAP_CCtx*) strm->state;
|
||||||
|
|
||||||
LOG_WRAPPER("deflate flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
|
LOG_WRAPPER("deflate flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
|
||||||
if (strm->avail_in > 0) {
|
if (strm->avail_in > 0) {
|
||||||
@@ -183,7 +224,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush))
|
|||||||
strm->avail_in -= srcSize;
|
strm->avail_in -= srcSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flush == Z_FULL_FLUSH) FINISH_WITH_ERR("Z_FULL_FLUSH is not supported!");
|
if (flush == Z_FULL_FLUSH) FINISH_WITH_ERR(strm, "Z_FULL_FLUSH is not supported!");
|
||||||
|
|
||||||
if (flush == Z_FINISH || flush == Z_FULL_FLUSH) {
|
if (flush == Z_FINISH || flush == Z_FULL_FLUSH) {
|
||||||
size_t bytesLeft;
|
size_t bytesLeft;
|
||||||
@@ -215,7 +256,7 @@ ZEXTERN int ZEXPORT z_deflateEnd OF((z_streamp strm))
|
|||||||
return deflateEnd(strm);
|
return deflateEnd(strm);
|
||||||
}
|
}
|
||||||
LOG_WRAPPER("- deflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out));
|
LOG_WRAPPER("- deflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out));
|
||||||
{ ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->opaque;
|
{ ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
|
||||||
size_t const errorCode = ZWRAP_freeCCtx(zwc);
|
size_t const errorCode = ZWRAP_freeCCtx(zwc);
|
||||||
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
|
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
|
||||||
}
|
}
|
||||||
@@ -253,25 +294,37 @@ ZEXTERN int ZEXPORT z_deflateParams OF((z_streamp strm,
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ZBUFF_DCtx* zbd;
|
ZBUFF_DCtx* zbd;
|
||||||
char headerBuf[ZSTD_FRAMEHEADERSIZE_MIN];
|
char headerBuf[ZWRAP_HEADERSIZE];
|
||||||
int errorCount;
|
int errorCount;
|
||||||
int requiredHeaderSize;
|
|
||||||
|
|
||||||
/* zlib params */
|
/* zlib params */
|
||||||
int stream_size;
|
int stream_size;
|
||||||
char *version;
|
char *version;
|
||||||
int windowBits;
|
int windowBits;
|
||||||
alloc_func zalloc; /* used to allocate the internal state */
|
ZSTD_customMem customMem;
|
||||||
free_func zfree; /* used to free the internal state */
|
z_stream allocFunc; /* copy of zalloc, zfree, opaque */
|
||||||
voidpf opaque; /* private data object passed to zalloc and zfree */
|
|
||||||
} ZWRAP_DCtx;
|
} ZWRAP_DCtx;
|
||||||
|
|
||||||
|
|
||||||
ZWRAP_DCtx* ZWRAP_createDCtx(void)
|
ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm)
|
||||||
{
|
{
|
||||||
ZWRAP_DCtx* zwd = (ZWRAP_DCtx*)malloc(sizeof(ZWRAP_DCtx));
|
ZWRAP_DCtx* zwd;
|
||||||
if (zwd==NULL) return NULL;
|
|
||||||
memset(zwd, 0, sizeof(*zwd));
|
if (strm->zalloc && strm->zfree) {
|
||||||
|
zwd = (ZWRAP_DCtx*)strm->zalloc(strm->opaque, 1, sizeof(ZWRAP_DCtx));
|
||||||
|
if (zwd==NULL) return NULL;
|
||||||
|
memset(zwd, 0, sizeof(ZWRAP_DCtx));
|
||||||
|
memcpy(&zwd->allocFunc, strm, sizeof(z_stream));
|
||||||
|
{ ZSTD_customMem ZWRAP_customMem = { ZWRAP_allocFunction, ZWRAP_freeFunction, &zwd->allocFunc };
|
||||||
|
memcpy(&zwd->customMem, &ZWRAP_customMem, sizeof(ZSTD_customMem));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
zwd = (ZWRAP_DCtx*)defaultCustomMem.customAlloc(defaultCustomMem.opaque, sizeof(ZWRAP_DCtx));
|
||||||
|
if (zwd==NULL) return NULL;
|
||||||
|
memset(zwd, 0, sizeof(ZWRAP_DCtx));
|
||||||
|
memcpy(&zwd->customMem, &defaultCustomMem, sizeof(ZSTD_customMem));
|
||||||
|
}
|
||||||
|
|
||||||
return zwd;
|
return zwd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,9 +332,9 @@ ZWRAP_DCtx* ZWRAP_createDCtx(void)
|
|||||||
size_t ZWRAP_freeDCtx(ZWRAP_DCtx* zwd)
|
size_t ZWRAP_freeDCtx(ZWRAP_DCtx* zwd)
|
||||||
{
|
{
|
||||||
if (zwd==NULL) return 0; /* support free on null */
|
if (zwd==NULL) return 0; /* support free on null */
|
||||||
if (zwd->version) free(zwd->version);
|
ZBUFF_freeDCtx(zwd->zbd);
|
||||||
if (zwd->zbd) ZBUFF_freeDCtx(zwd->zbd);
|
if (zwd->version) zwd->customMem.customFree(zwd->customMem.opaque, zwd->version);
|
||||||
free(zwd);
|
zwd->customMem.customFree(zwd->customMem.opaque, zwd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,18 +342,16 @@ size_t ZWRAP_freeDCtx(ZWRAP_DCtx* zwd)
|
|||||||
ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm,
|
ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm,
|
||||||
const char *version, int stream_size))
|
const char *version, int stream_size))
|
||||||
{
|
{
|
||||||
ZWRAP_DCtx* zwd = ZWRAP_createDCtx();
|
ZWRAP_DCtx* zwd = ZWRAP_createDCtx(strm);
|
||||||
LOG_WRAPPER("- inflateInit\n");
|
LOG_WRAPPER("- inflateInit\n");
|
||||||
if (zwd == NULL) return Z_MEM_ERROR;
|
if (zwd == NULL) { strm->state = NULL; return Z_MEM_ERROR; }
|
||||||
|
|
||||||
|
zwd->version = zwd->customMem.customAlloc(zwd->customMem.opaque, strlen(version) + 1);
|
||||||
|
if (zwd->version == NULL) { ZWRAP_freeDCtx(zwd); strm->state = NULL; return Z_MEM_ERROR; }
|
||||||
|
strcpy(zwd->version, version);
|
||||||
|
|
||||||
zwd->stream_size = stream_size;
|
zwd->stream_size = stream_size;
|
||||||
zwd->version = strdup(version);
|
strm->state = (struct internal_state*) zwd; /* use state which in not used by user */
|
||||||
zwd->zalloc = strm->zalloc;
|
|
||||||
zwd->zfree = strm->zfree;
|
|
||||||
zwd->opaque = strm->opaque;
|
|
||||||
zwd->requiredHeaderSize = ZWRAP_HEADERSIZE;
|
|
||||||
|
|
||||||
strm->state = (struct internal_state*) zwd;
|
|
||||||
strm->total_in = 0;
|
strm->total_in = 0;
|
||||||
strm->total_out = 0;
|
strm->total_out = 0;
|
||||||
strm->reserved = 1; /* mark as unknown steam */
|
strm->reserved = 1; /* mark as unknown steam */
|
||||||
@@ -321,8 +372,6 @@ ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int windowBits,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm,
|
ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm,
|
||||||
const Bytef *dictionary,
|
const Bytef *dictionary,
|
||||||
uInt dictLength))
|
uInt dictLength))
|
||||||
@@ -331,9 +380,11 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm,
|
|||||||
return inflateSetDictionary(strm, dictionary, dictLength);
|
return inflateSetDictionary(strm, dictionary, dictLength);
|
||||||
|
|
||||||
LOG_WRAPPER("- inflateSetDictionary\n");
|
LOG_WRAPPER("- inflateSetDictionary\n");
|
||||||
{ ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
|
{ size_t errorCode;
|
||||||
size_t errorCode = ZBUFF_decompressInitDictionary(zwd->zbd, dictionary, dictLength);
|
ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
|
||||||
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
|
if (strm->state == NULL) return Z_MEM_ERROR;
|
||||||
|
errorCode = ZBUFF_decompressInitDictionary(zwd->zbd, dictionary, dictLength);
|
||||||
|
if (ZSTD_isError(errorCode)) { ZWRAP_freeDCtx(zwd); strm->state = NULL; return Z_MEM_ERROR; }
|
||||||
|
|
||||||
if (strm->total_in == ZSTD_frameHeaderSize_min) {
|
if (strm->total_in == ZSTD_frameHeaderSize_min) {
|
||||||
size_t dstCapacity = 0;
|
size_t dstCapacity = 0;
|
||||||
@@ -342,6 +393,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm,
|
|||||||
LOG_WRAPPER("ZBUFF_decompressContinue3 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)srcSize, (int)dstCapacity);
|
LOG_WRAPPER("ZBUFF_decompressContinue3 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)srcSize, (int)dstCapacity);
|
||||||
if (dstCapacity > 0 || ZSTD_isError(errorCode)) {
|
if (dstCapacity > 0 || ZSTD_isError(errorCode)) {
|
||||||
LOG_WRAPPER("ERROR: ZBUFF_decompressContinue %s\n", ZSTD_getErrorName(errorCode));
|
LOG_WRAPPER("ERROR: ZBUFF_decompressContinue %s\n", ZSTD_getErrorName(errorCode));
|
||||||
|
ZWRAP_freeDCtx(zwd); strm->state = NULL;
|
||||||
return Z_MEM_ERROR;
|
return Z_MEM_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -359,15 +411,16 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush))
|
|||||||
if (strm->avail_in > 0) {
|
if (strm->avail_in > 0) {
|
||||||
size_t errorCode, dstCapacity, srcSize;
|
size_t errorCode, dstCapacity, srcSize;
|
||||||
ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
|
ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
|
||||||
|
if (strm->state == NULL) return Z_MEM_ERROR;
|
||||||
LOG_WRAPPER("inflate avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
|
LOG_WRAPPER("inflate avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
|
||||||
while (strm->total_in < ZSTD_FRAMEHEADERSIZE_MIN)
|
if (strm->total_in < ZWRAP_HEADERSIZE)
|
||||||
{
|
{
|
||||||
srcSize = MIN(strm->avail_in, zwd->requiredHeaderSize - strm->total_in);
|
srcSize = MIN(strm->avail_in, ZWRAP_HEADERSIZE - strm->total_in);
|
||||||
memcpy(zwd->headerBuf+strm->total_in, strm->next_in, srcSize);
|
memcpy(zwd->headerBuf+strm->total_in, strm->next_in, srcSize);
|
||||||
strm->total_in += srcSize;
|
strm->total_in += srcSize;
|
||||||
strm->next_in += srcSize;
|
strm->next_in += srcSize;
|
||||||
strm->avail_in -= srcSize;
|
strm->avail_in -= srcSize;
|
||||||
if (strm->total_in < zwd->requiredHeaderSize) return Z_OK;
|
if (strm->total_in < ZWRAP_HEADERSIZE) return Z_OK;
|
||||||
|
|
||||||
if (MEM_readLE32(zwd->headerBuf) != ZSTD_MAGICNUMBER) {
|
if (MEM_readLE32(zwd->headerBuf) != ZSTD_MAGICNUMBER) {
|
||||||
z_stream strm2;
|
z_stream strm2;
|
||||||
@@ -381,7 +434,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush))
|
|||||||
else
|
else
|
||||||
errorCode = inflateInit_(strm, zwd->version, zwd->stream_size);
|
errorCode = inflateInit_(strm, zwd->version, zwd->stream_size);
|
||||||
LOG_WRAPPER("ZLIB inflateInit errorCode=%d\n", (int)errorCode);
|
LOG_WRAPPER("ZLIB inflateInit errorCode=%d\n", (int)errorCode);
|
||||||
if (errorCode != Z_OK) return errorCode;
|
if (errorCode != Z_OK) { ZWRAP_freeDCtx(zwd); strm->state = NULL; return errorCode; }
|
||||||
|
|
||||||
/* inflate header */
|
/* inflate header */
|
||||||
strm->next_in = (unsigned char*)zwd->headerBuf;
|
strm->next_in = (unsigned char*)zwd->headerBuf;
|
||||||
@@ -389,37 +442,37 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush))
|
|||||||
strm->avail_out = 0;
|
strm->avail_out = 0;
|
||||||
errorCode = inflate(strm, Z_NO_FLUSH);
|
errorCode = inflate(strm, Z_NO_FLUSH);
|
||||||
LOG_WRAPPER("ZLIB inflate errorCode=%d strm->avail_in=%d\n", (int)errorCode, (int)strm->avail_in);
|
LOG_WRAPPER("ZLIB inflate errorCode=%d strm->avail_in=%d\n", (int)errorCode, (int)strm->avail_in);
|
||||||
if (errorCode != Z_OK) return errorCode;
|
if (errorCode != Z_OK) { ZWRAP_freeDCtx(zwd); strm->state = NULL; return errorCode; }
|
||||||
if (strm->avail_in > 0) return Z_MEM_ERROR;
|
if (strm->avail_in > 0) goto error;
|
||||||
|
|
||||||
strm->next_in = strm2.next_in;
|
strm->next_in = strm2.next_in;
|
||||||
strm->avail_in = strm2.avail_in;
|
strm->avail_in = strm2.avail_in;
|
||||||
strm->next_out = strm2.next_out;
|
strm->next_out = strm2.next_out;
|
||||||
strm->avail_out = strm2.avail_out;
|
strm->avail_out = strm2.avail_out;
|
||||||
|
|
||||||
strm->reserved = 0; /* mark as zlib stream */
|
strm->reserved = 0; /* mark as zlib stream */
|
||||||
|
errorCode = ZWRAP_freeDCtx(zwd);
|
||||||
|
if (ZSTD_isError(errorCode)) goto error;
|
||||||
|
|
||||||
if (flush == Z_INFLATE_SYNC) return inflateSync(strm);
|
if (flush == Z_INFLATE_SYNC) return inflateSync(strm);
|
||||||
return inflate(strm, flush);
|
return inflate(strm, flush);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zwd->requiredHeaderSize < ZSTD_FRAMEHEADERSIZE_MIN) {
|
zwd->zbd = ZBUFF_createDCtx_advanced(zwd->customMem);
|
||||||
zwd->requiredHeaderSize = ZSTD_FRAMEHEADERSIZE_MIN;
|
if (zwd->zbd == NULL) goto error;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
zwd->zbd = ZBUFF_createDCtx();
|
errorCode = ZBUFF_decompressInit(zwd->zbd);
|
||||||
{ size_t const errorCode = ZBUFF_decompressInit(zwd->zbd);
|
if (ZSTD_isError(errorCode)) goto error;
|
||||||
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; }
|
|
||||||
|
|
||||||
srcSize = ZSTD_FRAMEHEADERSIZE_MIN;
|
srcSize = ZWRAP_HEADERSIZE;
|
||||||
dstCapacity = 0;
|
dstCapacity = 0;
|
||||||
errorCode = ZBUFF_decompressContinue(zwd->zbd, strm->next_out, &dstCapacity, zwd->headerBuf, &srcSize);
|
errorCode = ZBUFF_decompressContinue(zwd->zbd, strm->next_out, &dstCapacity, zwd->headerBuf, &srcSize);
|
||||||
LOG_WRAPPER("ZBUFF_decompressContinue1 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)srcSize, (int)dstCapacity);
|
LOG_WRAPPER("ZBUFF_decompressContinue1 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)srcSize, (int)dstCapacity);
|
||||||
if (ZSTD_isError(errorCode)) {
|
if (ZSTD_isError(errorCode)) {
|
||||||
LOG_WRAPPER("ERROR: ZBUFF_decompressContinue %s\n", ZSTD_getErrorName(errorCode));
|
LOG_WRAPPER("ERROR: ZBUFF_decompressContinue %s\n", ZSTD_getErrorName(errorCode));
|
||||||
return Z_MEM_ERROR;
|
goto error;
|
||||||
}
|
}
|
||||||
if (strm->avail_in == 0) return Z_OK;
|
if (strm->avail_in == 0) return Z_OK;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
srcSize = strm->avail_in;
|
srcSize = strm->avail_in;
|
||||||
@@ -429,7 +482,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush))
|
|||||||
if (ZSTD_isError(errorCode)) {
|
if (ZSTD_isError(errorCode)) {
|
||||||
LOG_WRAPPER("ERROR: ZBUFF_decompressContinue %s\n", ZSTD_getErrorName(errorCode));
|
LOG_WRAPPER("ERROR: ZBUFF_decompressContinue %s\n", ZSTD_getErrorName(errorCode));
|
||||||
zwd->errorCount++;
|
zwd->errorCount++;
|
||||||
return (zwd->errorCount<=1) ? Z_NEED_DICT : Z_MEM_ERROR;
|
if (zwd->errorCount<=1) return Z_NEED_DICT; else goto error;
|
||||||
}
|
}
|
||||||
strm->next_out += dstCapacity;
|
strm->next_out += dstCapacity;
|
||||||
strm->total_out += dstCapacity;
|
strm->total_out += dstCapacity;
|
||||||
@@ -438,6 +491,11 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush))
|
|||||||
strm->next_in += srcSize;
|
strm->next_in += srcSize;
|
||||||
strm->avail_in -= srcSize;
|
strm->avail_in -= srcSize;
|
||||||
if (errorCode == 0) return Z_STREAM_END;
|
if (errorCode == 0) return Z_STREAM_END;
|
||||||
|
return Z_OK;
|
||||||
|
error:
|
||||||
|
ZWRAP_freeDCtx(zwd);
|
||||||
|
strm->state = NULL;
|
||||||
|
return Z_MEM_ERROR;
|
||||||
}
|
}
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
@@ -447,11 +505,12 @@ ZEXTERN int ZEXPORT z_inflateEnd OF((z_streamp strm))
|
|||||||
{
|
{
|
||||||
int ret = Z_OK;
|
int ret = Z_OK;
|
||||||
if (!strm->reserved)
|
if (!strm->reserved)
|
||||||
ret = inflateEnd(strm);
|
return inflateEnd(strm);
|
||||||
|
|
||||||
LOG_WRAPPER("- inflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out));
|
LOG_WRAPPER("- inflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out));
|
||||||
{ ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
|
{ ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
|
||||||
size_t const errorCode = ZWRAP_freeDCtx(zwd);
|
size_t const errorCode = ZWRAP_freeDCtx(zwd);
|
||||||
|
strm->state = NULL;
|
||||||
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
|
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -472,7 +531,7 @@ ZEXTERN int ZEXPORT z_deflateCopy OF((z_streamp dest,
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return deflateCopy(dest, source);
|
return deflateCopy(dest, source);
|
||||||
FINISH_WITH_ERR("deflateCopy is not supported!");
|
FINISH_WITH_ERR(source, "deflateCopy is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -480,7 +539,7 @@ ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm))
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return deflateReset(strm);
|
return deflateReset(strm);
|
||||||
FINISH_WITH_ERR("deflateReset is not supported!");
|
FINISH_WITH_ERR(strm, "deflateReset is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -492,18 +551,20 @@ ZEXTERN int ZEXPORT z_deflateTune OF((z_streamp strm,
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return deflateTune(strm, good_length, max_lazy, nice_length, max_chain);
|
return deflateTune(strm, good_length, max_lazy, nice_length, max_chain);
|
||||||
FINISH_WITH_ERR("deflateTune is not supported!");
|
FINISH_WITH_ERR(strm, "deflateTune is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if ZLIB_VERNUM >= 0x1260
|
||||||
ZEXTERN int ZEXPORT z_deflatePending OF((z_streamp strm,
|
ZEXTERN int ZEXPORT z_deflatePending OF((z_streamp strm,
|
||||||
unsigned *pending,
|
unsigned *pending,
|
||||||
int *bits))
|
int *bits))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return deflatePending(strm, pending, bits);
|
return deflatePending(strm, pending, bits);
|
||||||
FINISH_WITH_ERR("deflatePending is not supported!");
|
FINISH_WITH_ERR(strm, "deflatePending is not supported!");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_deflatePrime OF((z_streamp strm,
|
ZEXTERN int ZEXPORT z_deflatePrime OF((z_streamp strm,
|
||||||
@@ -512,7 +573,7 @@ ZEXTERN int ZEXPORT z_deflatePrime OF((z_streamp strm,
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return deflatePrime(strm, bits, value);
|
return deflatePrime(strm, bits, value);
|
||||||
FINISH_WITH_ERR("deflatePrime is not supported!");
|
FINISH_WITH_ERR(strm, "deflatePrime is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -521,22 +582,23 @@ ZEXTERN int ZEXPORT z_deflateSetHeader OF((z_streamp strm,
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return deflateSetHeader(strm, head);
|
return deflateSetHeader(strm, head);
|
||||||
FINISH_WITH_ERR("deflateSetHeader is not supported!");
|
FINISH_WITH_ERR(strm, "deflateSetHeader is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Advanced compression functions */
|
/* Advanced compression functions */
|
||||||
|
#if ZLIB_VERNUM >= 0x1280
|
||||||
ZEXTERN int ZEXPORT z_inflateGetDictionary OF((z_streamp strm,
|
ZEXTERN int ZEXPORT z_inflateGetDictionary OF((z_streamp strm,
|
||||||
Bytef *dictionary,
|
Bytef *dictionary,
|
||||||
uInt *dictLength))
|
uInt *dictLength))
|
||||||
{
|
{
|
||||||
if (!strm->reserved)
|
if (!strm->reserved)
|
||||||
return inflateGetDictionary(strm, dictionary, dictLength);
|
return inflateGetDictionary(strm, dictionary, dictLength);
|
||||||
FINISH_WITH_ERR("inflateGetDictionary is not supported!");
|
FINISH_WITH_ERR(strm, "inflateGetDictionary is not supported!");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_inflateCopy OF((z_streamp dest,
|
ZEXTERN int ZEXPORT z_inflateCopy OF((z_streamp dest,
|
||||||
@@ -544,7 +606,7 @@ ZEXTERN int ZEXPORT z_inflateCopy OF((z_streamp dest,
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return inflateCopy(dest, source);
|
return inflateCopy(dest, source);
|
||||||
FINISH_WITH_ERR("inflateCopy is not supported!");
|
FINISH_WITH_ERR(source, "inflateCopy is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -552,17 +614,29 @@ ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm))
|
|||||||
{
|
{
|
||||||
if (!strm->reserved)
|
if (!strm->reserved)
|
||||||
return inflateReset(strm);
|
return inflateReset(strm);
|
||||||
FINISH_WITH_ERR("inflateReset is not supported!");
|
FINISH_WITH_ERR(strm, "inflateReset is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if ZLIB_VERNUM >= 0x1240
|
||||||
ZEXTERN int ZEXPORT z_inflateReset2 OF((z_streamp strm,
|
ZEXTERN int ZEXPORT z_inflateReset2 OF((z_streamp strm,
|
||||||
int windowBits))
|
int windowBits))
|
||||||
{
|
{
|
||||||
if (!strm->reserved)
|
if (!strm->reserved)
|
||||||
return inflateReset2(strm, windowBits);
|
return inflateReset2(strm, windowBits);
|
||||||
FINISH_WITH_ERR("inflateReset2 is not supported!");
|
FINISH_WITH_ERR(strm, "inflateReset2 is not supported!");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if ZLIB_VERNUM >= 0x1240
|
||||||
|
ZEXTERN long ZEXPORT z_inflateMark OF((z_streamp strm))
|
||||||
|
{
|
||||||
|
if (!strm->reserved)
|
||||||
|
return inflateMark(strm);
|
||||||
|
FINISH_WITH_ERR(strm, "inflateMark is not supported!");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_inflatePrime OF((z_streamp strm,
|
ZEXTERN int ZEXPORT z_inflatePrime OF((z_streamp strm,
|
||||||
@@ -571,15 +645,7 @@ ZEXTERN int ZEXPORT z_inflatePrime OF((z_streamp strm,
|
|||||||
{
|
{
|
||||||
if (!strm->reserved)
|
if (!strm->reserved)
|
||||||
return inflatePrime(strm, bits, value);
|
return inflatePrime(strm, bits, value);
|
||||||
FINISH_WITH_ERR("inflatePrime is not supported!");
|
FINISH_WITH_ERR(strm, "inflatePrime is not supported!");
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN long ZEXPORT z_inflateMark OF((z_streamp strm))
|
|
||||||
{
|
|
||||||
if (!strm->reserved)
|
|
||||||
return inflateMark(strm);
|
|
||||||
FINISH_WITH_ERR("inflateMark is not supported!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -588,7 +654,7 @@ ZEXTERN int ZEXPORT z_inflateGetHeader OF((z_streamp strm,
|
|||||||
{
|
{
|
||||||
if (!strm->reserved)
|
if (!strm->reserved)
|
||||||
return inflateGetHeader(strm, head);
|
return inflateGetHeader(strm, head);
|
||||||
FINISH_WITH_ERR("inflateGetHeader is not supported!");
|
FINISH_WITH_ERR(strm, "inflateGetHeader is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -599,7 +665,7 @@ ZEXTERN int ZEXPORT z_inflateBackInit_ OF((z_streamp strm, int windowBits,
|
|||||||
{
|
{
|
||||||
if (!strm->reserved)
|
if (!strm->reserved)
|
||||||
return inflateBackInit_(strm, windowBits, window, version, stream_size);
|
return inflateBackInit_(strm, windowBits, window, version, stream_size);
|
||||||
FINISH_WITH_ERR("inflateBackInit is not supported!");
|
FINISH_WITH_ERR(strm, "inflateBackInit is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -609,7 +675,7 @@ ZEXTERN int ZEXPORT z_inflateBack OF((z_streamp strm,
|
|||||||
{
|
{
|
||||||
if (!strm->reserved)
|
if (!strm->reserved)
|
||||||
return inflateBack(strm, in, in_desc, out, out_desc);
|
return inflateBack(strm, in, in_desc, out, out_desc);
|
||||||
FINISH_WITH_ERR("inflateBack is not supported!");
|
FINISH_WITH_ERR(strm, "inflateBack is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -617,7 +683,7 @@ ZEXTERN int ZEXPORT z_inflateBackEnd OF((z_streamp strm))
|
|||||||
{
|
{
|
||||||
if (!strm->reserved)
|
if (!strm->reserved)
|
||||||
return inflateBackEnd(strm);
|
return inflateBackEnd(strm);
|
||||||
FINISH_WITH_ERR("inflateBackEnd is not supported!");
|
FINISH_WITH_ERR(strm, "inflateBackEnd is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -634,9 +700,9 @@ ZEXTERN int ZEXPORT z_compress OF((Bytef *dest, uLongf *destLen,
|
|||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return compress(dest, destLen, source, sourceLen);
|
return compress(dest, destLen, source, sourceLen);
|
||||||
|
|
||||||
size_t dstCapacity = *destLen;
|
{ size_t dstCapacity = *destLen;
|
||||||
LOG_WRAPPER("z_compress sourceLen=%d dstCapacity=%d\n", (int)sourceLen, (int)dstCapacity);
|
size_t const errorCode = ZSTD_compress(dest, dstCapacity, source, sourceLen, ZWRAP_DEFAULT_CLEVEL);
|
||||||
{ size_t const errorCode = ZSTD_compress(dest, dstCapacity, source, sourceLen, -1);
|
LOG_WRAPPER("z_compress sourceLen=%d dstCapacity=%d\n", (int)sourceLen, (int)dstCapacity);
|
||||||
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
|
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
|
||||||
*destLen = errorCode;
|
*destLen = errorCode;
|
||||||
}
|
}
|
||||||
@@ -651,8 +717,8 @@ ZEXTERN int ZEXPORT z_compress2 OF((Bytef *dest, uLongf *destLen,
|
|||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return compress2(dest, destLen, source, sourceLen, level);
|
return compress2(dest, destLen, source, sourceLen, level);
|
||||||
|
|
||||||
size_t dstCapacity = *destLen;
|
{ size_t dstCapacity = *destLen;
|
||||||
{ size_t const errorCode = ZSTD_compress(dest, dstCapacity, source, sourceLen, level);
|
size_t const errorCode = ZSTD_compress(dest, dstCapacity, source, sourceLen, level);
|
||||||
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
|
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
|
||||||
*destLen = errorCode;
|
*destLen = errorCode;
|
||||||
}
|
}
|
||||||
@@ -676,8 +742,8 @@ ZEXTERN int ZEXPORT z_uncompress OF((Bytef *dest, uLongf *destLen,
|
|||||||
// if (!g_useZSTD)
|
// if (!g_useZSTD)
|
||||||
return uncompress(dest, destLen, source, sourceLen);
|
return uncompress(dest, destLen, source, sourceLen);
|
||||||
|
|
||||||
size_t dstCapacity = *destLen;
|
{ size_t dstCapacity = *destLen;
|
||||||
{ size_t const errorCode = ZSTD_decompress(dest, dstCapacity, source, sourceLen);
|
size_t const errorCode = ZSTD_decompress(dest, dstCapacity, source, sourceLen);
|
||||||
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
|
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
|
||||||
*destLen = errorCode;
|
*destLen = errorCode;
|
||||||
}
|
}
|
||||||
@@ -703,19 +769,45 @@ ZEXTERN gzFile ZEXPORT z_gzdopen OF((int fd, const char *mode))
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if ZLIB_VERNUM >= 0x1240
|
||||||
ZEXTERN int ZEXPORT z_gzbuffer OF((gzFile file, unsigned size))
|
ZEXTERN int ZEXPORT z_gzbuffer OF((gzFile file, unsigned size))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return gzbuffer(file, size);
|
return gzbuffer(file, size);
|
||||||
FINISH_WITH_ERR("gzbuffer is not supported!");
|
FINISH_WITH_GZ_ERR("gzbuffer is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ZEXTERN z_off_t ZEXPORT z_gzoffset OF((gzFile file))
|
||||||
|
{
|
||||||
|
if (!g_useZSTD)
|
||||||
|
return gzoffset(file);
|
||||||
|
FINISH_WITH_GZ_ERR("gzoffset is not supported!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ZEXTERN int ZEXPORT z_gzclose_r OF((gzFile file))
|
||||||
|
{
|
||||||
|
if (!g_useZSTD)
|
||||||
|
return gzclose_r(file);
|
||||||
|
FINISH_WITH_GZ_ERR("gzclose_r is not supported!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ZEXTERN int ZEXPORT z_gzclose_w OF((gzFile file))
|
||||||
|
{
|
||||||
|
if (!g_useZSTD)
|
||||||
|
return gzclose_w(file);
|
||||||
|
FINISH_WITH_GZ_ERR("gzclose_w is not supported!");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_gzsetparams OF((gzFile file, int level, int strategy))
|
ZEXTERN int ZEXPORT z_gzsetparams OF((gzFile file, int level, int strategy))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return gzsetparams(file, level, strategy);
|
return gzsetparams(file, level, strategy);
|
||||||
FINISH_WITH_ERR("gzsetparams is not supported!");
|
FINISH_WITH_GZ_ERR("gzsetparams is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -723,7 +815,7 @@ ZEXTERN int ZEXPORT z_gzread OF((gzFile file, voidp buf, unsigned len))
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return gzread(file, buf, len);
|
return gzread(file, buf, len);
|
||||||
FINISH_WITH_ERR("gzread is not supported!");
|
FINISH_WITH_GZ_ERR("gzread is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -732,11 +824,15 @@ ZEXTERN int ZEXPORT z_gzwrite OF((gzFile file,
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return gzwrite(file, buf, len);
|
return gzwrite(file, buf, len);
|
||||||
FINISH_WITH_ERR("gzwrite is not supported!");
|
FINISH_WITH_GZ_ERR("gzwrite is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if ZLIB_VERNUM >= 0x1260
|
||||||
ZEXTERN int ZEXPORTVA z_gzprintf Z_ARG((gzFile file, const char *format, ...))
|
ZEXTERN int ZEXPORTVA z_gzprintf Z_ARG((gzFile file, const char *format, ...))
|
||||||
|
#else
|
||||||
|
ZEXTERN int ZEXPORTVA z_gzprintf OF((gzFile file, const char *format, ...))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if (!g_useZSTD) {
|
if (!g_useZSTD) {
|
||||||
int ret;
|
int ret;
|
||||||
@@ -750,7 +846,7 @@ ZEXTERN int ZEXPORTVA z_gzprintf Z_ARG((gzFile file, const char *format, ...))
|
|||||||
// printf("gzprintf ret=%d\n", ret);
|
// printf("gzprintf ret=%d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
FINISH_WITH_ERR("gzprintf is not supported!");
|
FINISH_WITH_GZ_ERR("gzprintf is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -758,7 +854,7 @@ ZEXTERN int ZEXPORT z_gzputs OF((gzFile file, const char *s))
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return gzputs(file, s);
|
return gzputs(file, s);
|
||||||
FINISH_WITH_ERR("gzputs is not supported!");
|
FINISH_WITH_GZ_ERR("gzputs is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -774,15 +870,19 @@ ZEXTERN int ZEXPORT z_gzputc OF((gzFile file, int c))
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return gzputc(file, c);
|
return gzputc(file, c);
|
||||||
FINISH_WITH_ERR("gzputc is not supported!");
|
FINISH_WITH_GZ_ERR("gzputc is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if ZLIB_VERNUM == 0x1260
|
||||||
|
ZEXTERN int ZEXPORT z_gzgetc_ OF((gzFile file))
|
||||||
|
#else
|
||||||
ZEXTERN int ZEXPORT z_gzgetc OF((gzFile file))
|
ZEXTERN int ZEXPORT z_gzgetc OF((gzFile file))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return gzgetc(file);
|
return gzgetc(file);
|
||||||
FINISH_WITH_ERR("gzgetc is not supported!");
|
FINISH_WITH_GZ_ERR("gzgetc is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -790,7 +890,7 @@ ZEXTERN int ZEXPORT z_gzungetc OF((int c, gzFile file))
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return gzungetc(c, file);
|
return gzungetc(c, file);
|
||||||
FINISH_WITH_ERR("gzungetc is not supported!");
|
FINISH_WITH_GZ_ERR("gzungetc is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -798,7 +898,7 @@ ZEXTERN int ZEXPORT z_gzflush OF((gzFile file, int flush))
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return gzflush(file, flush);
|
return gzflush(file, flush);
|
||||||
FINISH_WITH_ERR("gzflush is not supported!");
|
FINISH_WITH_GZ_ERR("gzflush is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -806,7 +906,7 @@ ZEXTERN z_off_t ZEXPORT z_gzseek OF((gzFile file, z_off_t offset, int whence))
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return gzseek(file, offset, whence);
|
return gzseek(file, offset, whence);
|
||||||
FINISH_WITH_ERR("gzseek is not supported!");
|
FINISH_WITH_GZ_ERR("gzseek is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -814,7 +914,7 @@ ZEXTERN int ZEXPORT z_gzrewind OF((gzFile file))
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return gzrewind(file);
|
return gzrewind(file);
|
||||||
FINISH_WITH_ERR("gzrewind is not supported!");
|
FINISH_WITH_GZ_ERR("gzrewind is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -822,15 +922,7 @@ ZEXTERN z_off_t ZEXPORT z_gztell OF((gzFile file))
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return gztell(file);
|
return gztell(file);
|
||||||
FINISH_WITH_ERR("gztell is not supported!");
|
FINISH_WITH_GZ_ERR("gztell is not supported!");
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN z_off_t ZEXPORT z_gzoffset OF((gzFile file))
|
|
||||||
{
|
|
||||||
if (!g_useZSTD)
|
|
||||||
return gzoffset(file);
|
|
||||||
FINISH_WITH_ERR("gzoffset is not supported!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -838,7 +930,7 @@ ZEXTERN int ZEXPORT z_gzeof OF((gzFile file))
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return gzeof(file);
|
return gzeof(file);
|
||||||
FINISH_WITH_ERR("gzeof is not supported!");
|
FINISH_WITH_GZ_ERR("gzeof is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -846,7 +938,7 @@ ZEXTERN int ZEXPORT z_gzdirect OF((gzFile file))
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return gzdirect(file);
|
return gzdirect(file);
|
||||||
FINISH_WITH_ERR("gzdirect is not supported!");
|
FINISH_WITH_GZ_ERR("gzdirect is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -854,23 +946,7 @@ ZEXTERN int ZEXPORT z_gzclose OF((gzFile file))
|
|||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_useZSTD)
|
||||||
return gzclose(file);
|
return gzclose(file);
|
||||||
FINISH_WITH_ERR("gzclose is not supported!");
|
FINISH_WITH_GZ_ERR("gzclose is not supported!");
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_gzclose_r OF((gzFile file))
|
|
||||||
{
|
|
||||||
if (!g_useZSTD)
|
|
||||||
return gzclose_r(file);
|
|
||||||
FINISH_WITH_ERR("gzclose_r is not supported!");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_gzclose_w OF((gzFile file))
|
|
||||||
{
|
|
||||||
if (!g_useZSTD)
|
|
||||||
return gzclose_w(file);
|
|
||||||
FINISH_WITH_ERR("gzclose_w is not supported!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -40,10 +40,17 @@ extern "C" {
|
|||||||
#define Z_PREFIX
|
#define Z_PREFIX
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
|
#if !defined(z_const)
|
||||||
|
#if ZLIB_VERNUM >= 0x1260
|
||||||
|
#define z_const const
|
||||||
|
#else
|
||||||
|
#define z_const
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
void useZSTD(int turn_on);
|
void useZSTD(int turn_on);
|
||||||
int isUsingZSTD();
|
int isUsingZSTD(void);
|
||||||
const char * zstdVersion();
|
const char * zstdVersion(void);
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
|
|||||||
Reference in New Issue
Block a user