Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83543a7b26 | ||
|
|
9ef72aa6b0 | ||
|
|
22e2730081 | ||
|
|
20859afb4c | ||
|
|
856f91ebef | ||
|
|
706876f09a | ||
|
|
572d428b59 | ||
|
|
6072eaaa21 | ||
|
|
df6797447f | ||
|
|
8675394d0d | ||
|
|
60dddc2109 | ||
|
|
ad468ab25c | ||
|
|
a03b7a7f1b | ||
|
|
c941d396c0 | ||
|
|
0ff0f2a259 | ||
|
|
67a1f4d72a | ||
|
|
cbd7bdca1e | ||
|
|
47094ea66b | ||
|
|
cf409a7e2a | ||
|
|
2f2639438a | ||
|
|
58d5dfea54 | ||
|
|
02c17e18d8 | ||
|
|
3980167488 | ||
|
|
ee2a45735e | ||
|
|
5fa2158e78 | ||
|
|
dac0376908 | ||
|
|
d249889b9f | ||
|
|
e5b60e859b | ||
|
|
bb85fe064d | ||
|
|
2fb7e6b15d | ||
|
|
611cd094d1 | ||
|
|
eb32d88980 | ||
|
|
cd2f6b680b | ||
|
|
2bb83e8271 | ||
|
|
26ec32b37f | ||
|
|
dc245e91cb | ||
|
|
e82c811946 | ||
|
|
c9e2ccd8c9 | ||
|
|
f18703e896 | ||
|
|
faa3fd34a7 | ||
|
|
57b9708054 | ||
|
|
b88accfb5f | ||
|
|
cf4f048de9 | ||
|
|
68cd4766c9 | ||
|
|
f77a1132a7 | ||
|
|
4602e53021 | ||
|
|
cf3ec08840 | ||
|
|
252c20dd34 | ||
|
|
cd5c52fe37 | ||
|
|
5ca471990b | ||
|
|
2b4de225e1 | ||
|
|
3b4093ca5c | ||
|
|
5b2c0dbed0 | ||
|
|
5eaf5da723 | ||
|
|
16fa12a51a | ||
|
|
f7ab3adaaa | ||
|
|
21412bb3f6 | ||
|
|
51f4d566c2 | ||
|
|
f71828f2c4 | ||
|
|
8e8b046f64 | ||
|
|
54320ce905 | ||
|
|
d755717941 | ||
|
|
bd76017329 | ||
|
|
3be5c6e6db | ||
|
|
dfef5ddc9e | ||
|
|
c3b8f2b715 | ||
|
|
0a5910b23b | ||
|
|
5c9adff7f8 | ||
|
|
f1073c1da7 | ||
|
|
1c209a4feb | ||
|
|
254c5b1692 | ||
|
|
adc4c1640f | ||
|
|
61abecc417 | ||
|
|
97b378a6f8 | ||
|
|
7e7925710d | ||
|
|
230a61fff2 | ||
|
|
993060e0f2 | ||
|
|
714464f05d | ||
|
|
27b5ac666e | ||
|
|
146ef58ff8 | ||
|
|
3fa1b748d6 | ||
|
|
0977f7ece6 | ||
|
|
84484cc656 | ||
|
|
2da5396c34 | ||
|
|
6c7e7ddee9 | ||
|
|
694130015b | ||
|
|
86fc8e0003 | ||
|
|
554b3b935c | ||
|
|
c038c30048 | ||
|
|
18f66459d5 | ||
|
|
7b546e5da9 | ||
|
|
47f3697f32 | ||
|
|
86bdcd83c1 | ||
|
|
0704df3259 | ||
|
|
dbe70bad48 | ||
|
|
4c9a4c18a9 | ||
|
|
c4ab571d89 | ||
|
|
0bb930b128 | ||
|
|
6101687547 | ||
|
|
e46bad0b2c | ||
|
|
1eb2fdc74f | ||
|
|
4ca3d4bc25 | ||
|
|
88aa179347 | ||
|
|
60038948e6 | ||
|
|
8fc5848bcb | ||
|
|
b077345f08 | ||
|
|
f47a0a8480 | ||
|
|
3e70cf8036 | ||
|
|
dd8905b351 | ||
|
|
ed0ea8d271 | ||
|
|
d28afac4f8 | ||
|
|
6173931868 | ||
|
|
55f276949c | ||
|
|
a6bdf55759 | ||
|
|
3e47dbcc8c | ||
|
|
644a8da88a | ||
|
|
43eeea4725 | ||
|
|
4cb212938c | ||
|
|
fa0c09760c | ||
|
|
d7c6589df8 | ||
|
|
55981a9ad6 | ||
|
|
6f358f5925 | ||
|
|
0b01a8ef09 | ||
|
|
35ad602c26 | ||
|
|
6fb4d675c6 | ||
|
|
3ecbe6a37c | ||
|
|
e91c4b4cef | ||
|
|
c03f15e89d | ||
|
|
d092d77cfc | ||
|
|
64deef3bee | ||
|
|
838beb27d3 | ||
|
|
220c567aa1 | ||
|
|
64a84edef5 | ||
|
|
c4cc9bf973 | ||
|
|
0be21d790a | ||
|
|
30d305615a | ||
|
|
0a43c80510 | ||
|
|
26ec254066 | ||
|
|
9f25fcf804 | ||
|
|
4d0efc8a16 | ||
|
|
362708d4d2 | ||
|
|
1c5ba8a5e7 | ||
|
|
ac175d46d4 | ||
|
|
716a9e8bb3 | ||
|
|
f747be1096 | ||
|
|
279a999265 | ||
|
|
4b83b9678d | ||
|
|
437bbec116 | ||
|
|
c6f0ee934b | ||
|
|
e8e531193b | ||
|
|
0dad121a1a | ||
|
|
e9ae30af46 | ||
|
|
a3481d6de0 | ||
|
|
d77f2ceee6 | ||
|
|
a2664649df | ||
|
|
746b51de51 | ||
|
|
7b0c261623 | ||
|
|
2c6779f948 | ||
|
|
b3060f7a9e | ||
|
|
b94fcc8d8a | ||
|
|
4a38d22668 | ||
|
|
75ba29b117 | ||
|
|
264c733ad6 | ||
|
|
661fcc955f | ||
|
|
01c199226a | ||
|
|
81ad632b72 | ||
|
|
e48fbb9f4c | ||
|
|
5c6d244973 | ||
|
|
ac8bace6b1 | ||
|
|
03d3f238de | ||
|
|
aad9fe5470 | ||
|
|
0e07bf3f60 | ||
|
|
bfa30f086d | ||
|
|
4d4d1ad3b3 | ||
|
|
823bf3d08d | ||
|
|
b3ed23e18e | ||
|
|
4db9fbdec7 | ||
|
|
378d12bb0c | ||
|
|
4c202815c7 | ||
|
|
95d07d7447 | ||
|
|
3e21ec5b01 | ||
|
|
ff306ae2f6 | ||
|
|
5c956d593c | ||
|
|
12083a45d4 | ||
|
|
edbcd9f5b2 | ||
|
|
b624922b14 | ||
|
|
a7737f6a60 | ||
|
|
7ae67bb18a | ||
|
|
1d4208c029 | ||
|
|
5e43b289bf | ||
|
|
3650b2193f | ||
|
|
e8b28a052b | ||
|
|
7c83dfd5c2 | ||
|
|
7bdfcead56 | ||
|
|
fa72f6bdce | ||
|
|
a4c212c001 | ||
|
|
c73a8109bb | ||
|
|
45db83f98d | ||
|
|
476964f6a1 | ||
|
|
c13faa1b0f | ||
|
|
8161e7321a | ||
|
|
7932d86fa5 | ||
|
|
0dcaef7b38 | ||
|
|
b85cdabd50 | ||
|
|
78b102d21d | ||
|
|
33a0465a51 | ||
|
|
1ea0b2c5e0 | ||
|
|
9622fe499d | ||
|
|
d56dbc02d3 | ||
|
|
d69798f858 | ||
|
|
855766d73d | ||
|
|
6e1b95b01c | ||
|
|
2b26ad1947 | ||
|
|
d725427a3c | ||
|
|
64c1c065cc | ||
|
|
2fcf8a4b99 | ||
|
|
ac14348a28 | ||
|
|
1e2f6a1f5d | ||
|
|
1563bfeabc | ||
|
|
5b8c024716 | ||
|
|
04f3276304 | ||
|
|
2ebe1cf732 | ||
|
|
7bf8c4d7ff | ||
|
|
724e3d534f | ||
|
|
779c489a9c | ||
|
|
4738e221ca | ||
|
|
7aa7e5aaab | ||
|
|
7df55e17e9 | ||
|
|
c53926c077 | ||
|
|
5153a084f3 | ||
|
|
b1a3ab1804 | ||
|
|
bff1c92c87 | ||
|
|
2741677a8d | ||
|
|
60181e3aaf | ||
|
|
be38198ef0 | ||
|
|
ef9999f0b9 | ||
|
|
2b0830b067 | ||
|
|
0c28f62d26 | ||
|
|
040cfd8e7d | ||
|
|
7304eb7c09 | ||
|
|
b2490e975a | ||
|
|
4c3b1881f2 | ||
|
|
f381d2d39c | ||
|
|
c932520960 | ||
|
|
c843142ad0 | ||
|
|
3427e68266 | ||
|
|
47987930e7 | ||
|
|
89de74416f | ||
|
|
6c61c11825 | ||
|
|
f45c550842 | ||
|
|
38816f93ff | ||
|
|
0588ee66cc | ||
|
|
901e85fe26 | ||
|
|
5c33c32d55 | ||
|
|
1c59c20903 | ||
|
|
599c69d917 | ||
|
|
309f113028 | ||
|
|
e10f7f3dcb | ||
|
|
4ded9e591c | ||
|
|
3b15f1f10f | ||
|
|
240795bef7 | ||
|
|
14200a20f0 | ||
|
|
da9d3b7057 | ||
|
|
09c3c8e885 | ||
|
|
6416b0d705 | ||
|
|
23b6e05d8e | ||
|
|
080940c628 | ||
|
|
54caf6893e | ||
|
|
dea67a66ab | ||
|
|
9097f7b156 | ||
|
|
1c69baa1a9 | ||
|
|
4b7b9fca32 | ||
|
|
5f53b0335e | ||
|
|
ab267e772c | ||
|
|
767d8f66fa | ||
|
|
4bf317dd00 | ||
|
|
bbd5bb75a6 | ||
|
|
e19a9ef05d | ||
|
|
9a021c1aae | ||
|
|
cb5a320705 | ||
|
|
87c18b2ebd | ||
|
|
0baa64a763 | ||
|
|
0d59a6f73a | ||
|
|
5a02b69215 | ||
|
|
bb93d77ab8 | ||
|
|
bb8558164e | ||
|
|
94376acfb0 | ||
|
|
baf7ecbdfd | ||
|
|
12731a9644 | ||
|
|
24a738c668 | ||
|
|
de9d13068f | ||
|
|
96bdd87de4 | ||
|
|
2c9e90e711 | ||
|
|
0132375ba6 | ||
|
|
637d33566d | ||
|
|
ab2f7708c1 | ||
|
|
7f18c6e5ef | ||
|
|
c23a07830e | ||
|
|
a3a47ec4d0 | ||
|
|
a2cdffe556 | ||
|
|
e416e30019 | ||
|
|
4e90f6c1e0 | ||
|
|
83388e109f | ||
|
|
8a36f8527c | ||
|
|
57ef4b1a0d | ||
|
|
7bcdbcf51d | ||
|
|
24b68a5b23 | ||
|
|
c54692faeb | ||
|
|
17e482efdd | ||
|
|
b62e696992 | ||
|
|
3071c3e303 | ||
|
|
70e3b31306 | ||
|
|
cb3276329a | ||
|
|
d1733f7417 | ||
|
|
70c2326bf1 | ||
|
|
8baf78a291 | ||
|
|
1bee2d5e08 | ||
|
|
0cfe2ec2fd | ||
|
|
af1960396b | ||
|
|
7be46bf8f2 | ||
|
|
fdba57d513 | ||
|
|
da3fbcb302 | ||
|
|
c629776b31 | ||
|
|
b571a0eab4 | ||
|
|
80b0e53c37 | ||
|
|
b944ce0b3a | ||
|
|
b6514d2496 | ||
|
|
7feafdd7b8 | ||
|
|
b7d3449d5d | ||
|
|
6ca9b853a1 | ||
|
|
49775e3a60 | ||
|
|
b1421f2d36 | ||
|
|
63e335704e | ||
|
|
2d5eb2beb9 | ||
|
|
a1c8115df5 | ||
|
|
2868d565e4 |
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
*.vcxproj* text eol=crlf
|
*.vcxproj* text eol=crlf
|
||||||
*.vcproj* text eol=crlf
|
*.vcproj* text eol=crlf
|
||||||
*.suo binary
|
*.suo binary
|
||||||
*.rc binary
|
*.rc text eol=crlf
|
||||||
|
|
||||||
# Windows
|
# Windows
|
||||||
*.bat text eol=crlf
|
*.bat text eol=crlf
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Object files
|
# Object files
|
||||||
*.o
|
*.o
|
||||||
*.ko
|
*.ko
|
||||||
|
*.dSYM
|
||||||
|
|
||||||
# Libraries
|
# Libraries
|
||||||
*.lib
|
*.lib
|
||||||
@@ -30,3 +31,4 @@ _zstdbench/
|
|||||||
*.idea
|
*.idea
|
||||||
*.swp
|
*.swp
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
googletest/
|
||||||
|
|||||||
+49
-28
@@ -3,13 +3,26 @@ compiler: gcc
|
|||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
include:
|
include:
|
||||||
|
# OS X Mavericks
|
||||||
|
- os: osx
|
||||||
|
env: PLATFORM="OS X Mavericks" CMD="make gnu90test && make clean && make test && make clean && make travis-install"
|
||||||
# Container-based Ubuntu 12.04 LTS Server Edition 64 bit (doesn't support 32-bit includes)
|
# Container-based Ubuntu 12.04 LTS Server Edition 64 bit (doesn't support 32-bit includes)
|
||||||
- os: linux
|
- os: linux
|
||||||
sudo: false
|
sudo: false
|
||||||
env: PLATFORM="Ubuntu 12.04 container" CMD="make test && make clean && make travis-install"
|
env: PLATFORM="Ubuntu 12.04 container" CMD="make test && make clean && make travis-install"
|
||||||
- os: linux
|
- os: linux
|
||||||
sudo: false
|
sudo: false
|
||||||
env: PLATFORM="Ubuntu 12.04 container" CMD="make -C programs test-zstd_nolegacy && make clean && make zlibwrapper && make clean && make cmaketest"
|
language: cpp
|
||||||
|
install:
|
||||||
|
- export CXX="g++-4.8" CC="gcc-4.8"
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
packages:
|
||||||
|
- gcc-4.8
|
||||||
|
- g++-4.8
|
||||||
|
env: PLATFORM="Ubuntu 12.04 container" CMD="make zlibwrapper && make clean && make -C tests test-zstd_nolegacy && make clean && make clean && make cmaketest && make clean && make -C contrib/pzstd pzstd && make -C contrib/pzstd googletest && make -C contrib/pzstd test && make -C contrib/pzstd clean"
|
||||||
- os: linux
|
- os: linux
|
||||||
sudo: false
|
sudo: false
|
||||||
env: PLATFORM="Ubuntu 12.04 container" CMD="make usan"
|
env: PLATFORM="Ubuntu 12.04 container" CMD="make usan"
|
||||||
@@ -17,14 +30,6 @@ matrix:
|
|||||||
sudo: false
|
sudo: false
|
||||||
env: PLATFORM="Ubuntu 12.04 container" CMD="make asan"
|
env: PLATFORM="Ubuntu 12.04 container" CMD="make asan"
|
||||||
# Standard Ubuntu 12.04 LTS Server Edition 64 bit
|
# Standard Ubuntu 12.04 LTS Server Edition 64 bit
|
||||||
- os: linux
|
|
||||||
sudo: required
|
|
||||||
env: PLATFORM="Ubuntu 12.04" CMD="make gpptest && make clean && make gnu90test && make clean && make c99test && make clean && make gnu99test && make clean && make clangtest"
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- libc6-dev-i386
|
|
||||||
- g++-multilib
|
|
||||||
- os: linux
|
- os: linux
|
||||||
sudo: required
|
sudo: required
|
||||||
env: PLATFORM="Ubuntu 12.04" CMD="make armtest"
|
env: PLATFORM="Ubuntu 12.04" CMD="make armtest"
|
||||||
@@ -37,14 +42,6 @@ matrix:
|
|||||||
- binfmt-support
|
- binfmt-support
|
||||||
- qemu
|
- qemu
|
||||||
- qemu-user-static
|
- qemu-user-static
|
||||||
- os: linux
|
|
||||||
sudo: required
|
|
||||||
env: PLATFORM="Ubuntu 12.04" CMD="make -C programs test32"
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- libc6-dev-i386
|
|
||||||
- gcc-multilib
|
|
||||||
- os: linux
|
- os: linux
|
||||||
sudo: required
|
sudo: required
|
||||||
env: PLATFORM="Ubuntu 12.04" CMD="make -C tests versionsTest"
|
env: PLATFORM="Ubuntu 12.04" CMD="make -C tests versionsTest"
|
||||||
@@ -53,21 +50,48 @@ matrix:
|
|||||||
env: PLATFORM="Ubuntu 12.04" CMD="make asan32"
|
env: PLATFORM="Ubuntu 12.04" CMD="make asan32"
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
packages:
|
packages:
|
||||||
- libc6-dev-i386
|
- libc6-dev-i386
|
||||||
- gcc-multilib
|
- gcc-multilib
|
||||||
- os: linux
|
|
||||||
sudo: required
|
|
||||||
env: PLATFORM="Ubuntu 12.04" CMD="make -C programs valgrindTest"
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- valgrind
|
|
||||||
# Ubuntu 14.04 LTS Server Edition 64 bit
|
# Ubuntu 14.04 LTS Server Edition 64 bit
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: trusty
|
||||||
sudo: required
|
sudo: required
|
||||||
env: PLATFORM="Ubuntu 14.04" CMD="make zlibwrapper && make clean && make gcc5test && make clean && make gcc6test && sudo apt-get install -y -q qemu-system-ppc binfmt-support qemu-user-static gcc-powerpc-linux-gnu && make clean && make ppctest"
|
env: PLATFORM="Ubuntu 14.04" CMD='make -C lib all && CFLAGS="-O1 -g" make -C zlibWrapper valgrindTest && make -C tests valgrindTest'
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- valgrind
|
||||||
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
|
sudo: required
|
||||||
|
install:
|
||||||
|
- export CXX="g++-4.8" CC="gcc-4.8"
|
||||||
|
env: PLATFORM="Ubuntu 14.04" CMD="make gpptest && make clean && make gnu90test && make clean && make c99test && make clean && make gnu99test && make clean && make clangtest && make clean && make -C contrib/pzstd pzstd32 && make -C contrib/pzstd googletest32 && make -C contrib/pzstd test32 && make -C contrib/pzstd clean"
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- libc6-dev-i386
|
||||||
|
- g++-multilib
|
||||||
|
- gcc-4.8
|
||||||
|
- gcc-4.8-multilib
|
||||||
|
- g++-4.8
|
||||||
|
- g++-4.8-multilib
|
||||||
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
|
sudo: required
|
||||||
|
env: PLATFORM="Ubuntu 14.04" CMD="make -C tests test32"
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- libc6-dev-i386
|
||||||
|
- gcc-multilib
|
||||||
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
|
sudo: required
|
||||||
|
env: PLATFORM="Ubuntu 14.04" CMD="make gcc5test && make clean && make gcc6test && sudo apt-get install -y -q qemu-system-ppc binfmt-support qemu-user-static gcc-powerpc-linux-gnu && make clean && make ppctest"
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
sources:
|
sources:
|
||||||
@@ -78,9 +102,6 @@ matrix:
|
|||||||
- gcc-5-multilib
|
- gcc-5-multilib
|
||||||
- gcc-6
|
- gcc-6
|
||||||
- gcc-6-multilib
|
- gcc-6-multilib
|
||||||
# OS X Mavericks
|
|
||||||
- os: osx
|
|
||||||
env: PLATFORM="OS X Mavericks" CMD="make gnu90test && make clean && make test && make clean && make travis-install"
|
|
||||||
exclude:
|
exclude:
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# Contributing to Zstandard
|
||||||
|
We want to make contributing to this project as easy and transparent as
|
||||||
|
possible.
|
||||||
|
|
||||||
|
## Our Development Process
|
||||||
|
New versions are being developed in the "dev" branch,
|
||||||
|
or in their own feature branch.
|
||||||
|
When they are deemed ready for a release, they are merged into "master".
|
||||||
|
|
||||||
|
As a consequences, all contributions must stage first through "dev"
|
||||||
|
or their own feature branch.
|
||||||
|
|
||||||
|
## Pull Requests
|
||||||
|
We actively welcome your pull requests.
|
||||||
|
|
||||||
|
1. Fork the repo and create your branch from `dev`.
|
||||||
|
2. If you've added code that should be tested, add tests.
|
||||||
|
3. If you've changed APIs, update the documentation.
|
||||||
|
4. Ensure the test suite passes.
|
||||||
|
5. Make sure your code lints.
|
||||||
|
6. If you haven't already, complete the Contributor License Agreement ("CLA").
|
||||||
|
|
||||||
|
## Contributor License Agreement ("CLA")
|
||||||
|
In order to accept your pull request, we need you to submit a CLA. You only need
|
||||||
|
to do this once to work on any of Facebook's open source projects.
|
||||||
|
|
||||||
|
Complete your CLA here: <https://code.facebook.com/cla>
|
||||||
|
|
||||||
|
## Issues
|
||||||
|
We use GitHub issues to track public bugs. Please ensure your description is
|
||||||
|
clear and has sufficient instructions to be able to reproduce the issue.
|
||||||
|
|
||||||
|
Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe
|
||||||
|
disclosure of security bugs. In those cases, please go through the process
|
||||||
|
outlined on that page and do not file a public issue.
|
||||||
|
|
||||||
|
## Coding Style
|
||||||
|
* 4 spaces for indentation rather than tabs
|
||||||
|
|
||||||
|
## License
|
||||||
|
By contributing to Zstandard, you agree that your contributions will be licensed
|
||||||
|
under the [LICENSE](LICENSE) file in the root directory of this source tree.
|
||||||
+13
-9
@@ -1,18 +1,22 @@
|
|||||||
ZSTD Library
|
|
||||||
Copyright (c) 2014-2015, Yann Collet
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
BSD License
|
BSD License
|
||||||
|
|
||||||
|
For Zstandard software
|
||||||
|
|
||||||
|
Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
are permitted provided that the following conditions are met:
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright notice, this
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
list of conditions and the following disclaimer.
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
list of conditions and the following disclaimer in the documentation and/or
|
this list of conditions and the following disclaimer in the documentation
|
||||||
other materials provided with the distribution.
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name Facebook nor the names of its contributors may be used to
|
||||||
|
endorse or promote products derived from this software without specific
|
||||||
|
prior written permission.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
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
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
|
||||||
|
|
||||||
|
The examples provided by Facebook are for non-commercial testing and evaluation
|
||||||
|
purposes only. Facebook reserves all rights not expressly granted.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
@@ -1,38 +1,17 @@
|
|||||||
# ################################################################
|
# ################################################################
|
||||||
# zstd - Makefile
|
# Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
# Copyright (C) Yann Collet 2014-2016
|
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# BSD license
|
# This source code is licensed under the BSD-style license found in the
|
||||||
#
|
# LICENSE file in the root directory of this source tree. An additional grant
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# of patent rights can be found in the PATENTS file in the same directory.
|
||||||
# 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 HOLDER 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/
|
|
||||||
# ################################################################
|
# ################################################################
|
||||||
|
|
||||||
PRGDIR = programs
|
PRGDIR = programs
|
||||||
ZSTDDIR = lib
|
ZSTDDIR = lib
|
||||||
|
BUILDIR = build
|
||||||
ZWRAPDIR = zlibWrapper
|
ZWRAPDIR = zlibWrapper
|
||||||
|
TESTDIR = tests
|
||||||
|
|
||||||
# Define nul output
|
# Define nul output
|
||||||
ifneq (,$(filter Windows%,$(OS)))
|
ifneq (,$(filter Windows%,$(OS)))
|
||||||
@@ -47,33 +26,32 @@ default: zstd
|
|||||||
|
|
||||||
all:
|
all:
|
||||||
$(MAKE) -C $(ZSTDDIR) $@
|
$(MAKE) -C $(ZSTDDIR) $@
|
||||||
$(MAKE) -C $(PRGDIR) $@
|
$(MAKE) -C $(PRGDIR) $@ zstd32
|
||||||
@rm -f lib/decompress/*.o
|
$(MAKE) -C $(TESTDIR) $@ all32
|
||||||
$(MAKE) -C $(PRGDIR) all32
|
|
||||||
|
|
||||||
zstd:
|
zstd:
|
||||||
$(MAKE) -C $(PRGDIR)
|
$(MAKE) -C $(PRGDIR)
|
||||||
cp $(PRGDIR)/zstd .
|
cp $(PRGDIR)/zstd .
|
||||||
|
|
||||||
zlibwrapper:
|
zlibwrapper:
|
||||||
$(MAKE) -C $(ZSTDDIR) all
|
$(MAKE) -C $(ZWRAPDIR) test
|
||||||
$(MAKE) -C $(ZWRAPDIR) all
|
|
||||||
|
|
||||||
test:
|
test:
|
||||||
$(MAKE) -C $(PRGDIR) $@
|
$(MAKE) -C $(TESTDIR) $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@$(MAKE) -C $(ZSTDDIR) $@ > $(VOID)
|
@$(MAKE) -C $(ZSTDDIR) $@ > $(VOID)
|
||||||
@$(MAKE) -C $(PRGDIR) $@ > $(VOID)
|
@$(MAKE) -C $(PRGDIR) $@ > $(VOID)
|
||||||
|
@$(MAKE) -C $(TESTDIR) $@ > $(VOID)
|
||||||
@$(MAKE) -C $(ZWRAPDIR) $@ > $(VOID)
|
@$(MAKE) -C $(ZWRAPDIR) $@ > $(VOID)
|
||||||
@rm -f zstd
|
@$(RM) zstd
|
||||||
@echo Cleaning completed
|
@echo Cleaning completed
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------
|
||||||
#make install is validated only for Linux, OSX, kFreeBSD, Hurd and some BSD targets
|
#make install is validated only for Linux, OSX, kFreeBSD, Hurd and some BSD targets
|
||||||
#----------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------
|
||||||
ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU FreeBSD DragonFly))
|
ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU FreeBSD DragonFly NetBSD))
|
||||||
HOST_OS = POSIX
|
HOST_OS = POSIX
|
||||||
install:
|
install:
|
||||||
$(MAKE) -C $(ZSTDDIR) $@
|
$(MAKE) -C $(ZSTDDIR) $@
|
||||||
@@ -99,19 +77,19 @@ gcc6test: clean
|
|||||||
|
|
||||||
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 -Wdocumentation"
|
||||||
|
|
||||||
armtest: clean
|
armtest: clean
|
||||||
$(MAKE) -C $(PRGDIR) datagen # use native, faster
|
$(MAKE) -C $(TESTDIR) datagen # use native, faster
|
||||||
$(MAKE) -C $(PRGDIR) test CC=arm-linux-gnueabi-gcc ZSTDRTTEST= MOREFLAGS="-Werror -static"
|
$(MAKE) -C $(TESTDIR) test CC=arm-linux-gnueabi-gcc ZSTDRTTEST= MOREFLAGS="-Werror -static"
|
||||||
|
|
||||||
ppctest: clean
|
ppctest: clean
|
||||||
$(MAKE) -C $(PRGDIR) datagen # use native, faster
|
$(MAKE) -C $(TESTDIR) datagen # use native, faster
|
||||||
$(MAKE) -C $(PRGDIR) test CC=powerpc-linux-gnu-gcc ZSTDRTTEST= MOREFLAGS="-Werror -Wno-attributes -static"
|
$(MAKE) -C $(TESTDIR) test CC=powerpc-linux-gnu-gcc ZSTDRTTEST= MOREFLAGS="-Werror -Wno-attributes -static"
|
||||||
|
|
||||||
ppc64test: clean
|
ppc64test: clean
|
||||||
$(MAKE) -C $(PRGDIR) datagen # use native, faster
|
$(MAKE) -C $(TESTDIR) datagen # use native, faster
|
||||||
$(MAKE) -C $(PRGDIR) test CC=powerpc-linux-gnu-gcc ZSTDRTTEST= MOREFLAGS="-m64 -static"
|
$(MAKE) -C $(TESTDIR) test CC=powerpc-linux-gnu-gcc ZSTDRTTEST= MOREFLAGS="-m64 -static"
|
||||||
|
|
||||||
usan: clean
|
usan: clean
|
||||||
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=undefined"
|
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=undefined"
|
||||||
@@ -123,7 +101,7 @@ msan: clean
|
|||||||
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=memory -fno-omit-frame-pointer" # datagen.c fails this test for no obvious reason
|
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=memory -fno-omit-frame-pointer" # datagen.c fails this test for no obvious reason
|
||||||
|
|
||||||
asan32: clean
|
asan32: clean
|
||||||
$(MAKE) -C $(PRGDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address"
|
$(MAKE) -C $(TESTDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address"
|
||||||
|
|
||||||
uasan: clean
|
uasan: clean
|
||||||
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address -fsanitize=undefined"
|
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address -fsanitize=undefined"
|
||||||
@@ -143,9 +121,9 @@ endif
|
|||||||
ifneq (,$(filter $(HOST_OS),MSYS POSIX))
|
ifneq (,$(filter $(HOST_OS),MSYS POSIX))
|
||||||
cmaketest:
|
cmaketest:
|
||||||
cmake --version
|
cmake --version
|
||||||
rm -rf projects/cmake/build
|
$(RM) -r $(BUILDIR)/cmake/build
|
||||||
mkdir projects/cmake/build
|
mkdir $(BUILDIR)/cmake/build
|
||||||
cd projects/cmake/build ; cmake -DPREFIX:STRING=~/install_test_dir $(CMAKE_PARAMS) .. ; $(MAKE) install ; $(MAKE) uninstall
|
cd $(BUILDIR)/cmake/build ; cmake -DPREFIX:STRING=~/install_test_dir $(CMAKE_PARAMS) .. ; $(MAKE) install ; $(MAKE) uninstall
|
||||||
|
|
||||||
c90test: clean
|
c90test: clean
|
||||||
CFLAGS="-std=c90" $(MAKE) all # will fail, due to // and long long
|
CFLAGS="-std=c90" $(MAKE) all # will fail, due to // and long long
|
||||||
@@ -163,13 +141,13 @@ c11test: clean
|
|||||||
CFLAGS="-std=c11" $(MAKE) all
|
CFLAGS="-std=c11" $(MAKE) all
|
||||||
|
|
||||||
bmix64test: clean
|
bmix64test: clean
|
||||||
CFLAGS="-O3 -mbmi -Werror" $(MAKE) -C $(PRGDIR) test
|
CFLAGS="-O3 -mbmi -Werror" $(MAKE) -C $(TESTDIR) test
|
||||||
|
|
||||||
bmix32test: clean
|
bmix32test: clean
|
||||||
CFLAGS="-O3 -mbmi -mx32 -Werror" $(MAKE) -C $(PRGDIR) test
|
CFLAGS="-O3 -mbmi -mx32 -Werror" $(MAKE) -C $(TESTDIR) test
|
||||||
|
|
||||||
bmi32test: clean
|
bmi32test: clean
|
||||||
CFLAGS="-O3 -mbmi -m32 -Werror" $(MAKE) -C $(PRGDIR) test
|
CFLAGS="-O3 -mbmi -m32 -Werror" $(MAKE) -C $(TESTDIR) test
|
||||||
|
|
||||||
staticAnalyze: clean
|
staticAnalyze: clean
|
||||||
CPPFLAGS=-g scan-build --status-bugs -v $(MAKE) all
|
CPPFLAGS=-g scan-build --status-bugs -v $(MAKE) all
|
||||||
|
|||||||
@@ -1,3 +1,26 @@
|
|||||||
|
v1.1.0
|
||||||
|
New : contrib/pzstd, parallel version of zstd, by Nick Terrell
|
||||||
|
added : NetBSD install target (#338)
|
||||||
|
Improved : speed for batches of small files
|
||||||
|
Improved : speed of zlib wrapper, by Przemyslaw Skibinski
|
||||||
|
Changed : libzstd on Windows supports legacy formats, by Christophe Chevalier
|
||||||
|
Fixed : CLI -d output to stdout by default when input is stdin (#322)
|
||||||
|
Fixed : CLI correctly detects console on Mac OS-X
|
||||||
|
Fixed : CLI supports recursive mode `-r` on Mac OS-X
|
||||||
|
Fixed : Legacy decoders use unified error codes, reported by benrg (#341), fixed by Przemyslaw Skibinski
|
||||||
|
Fixed : compatibility with OpenBSD, reported by Juan Francisco Cantero Hurtado (#319)
|
||||||
|
Fixed : compatibility with Hurd, by Przemyslaw Skibinski (#365)
|
||||||
|
Fixed : zstd-pgo, reported by octoploid (#329)
|
||||||
|
|
||||||
|
v1.0.0
|
||||||
|
Change Licensing, all project is now BSD, Copyright Facebook
|
||||||
|
Small decompression speed improvement
|
||||||
|
API : Streaming API supports legacy format
|
||||||
|
API : ZDICT_getDictID(), ZSTD_sizeof_{CCtx, DCtx, CStream, DStream}(), ZSTD_setDStreamParamter()
|
||||||
|
CLI supports legacy formats v0.4+
|
||||||
|
Fixed : compression fails on certain huge files, reported by Jesse McGrew
|
||||||
|
Enhanced documentation, by Przemyslaw Skibinski
|
||||||
|
|
||||||
v0.8.1
|
v0.8.1
|
||||||
New streaming API
|
New streaming API
|
||||||
Changed : --ultra now enables levels beyond 19
|
Changed : --ultra now enables levels beyond 19
|
||||||
@@ -20,6 +43,9 @@ Modified : minor compression level adaptations
|
|||||||
Updated : compression format specification to v0.2.0
|
Updated : compression format specification to v0.2.0
|
||||||
changed : zstd.h moved to /lib directory
|
changed : zstd.h moved to /lib directory
|
||||||
|
|
||||||
|
v0.7.5
|
||||||
|
Transition version, supporting decoding of v0.8.x
|
||||||
|
|
||||||
v0.7.4
|
v0.7.4
|
||||||
Added : homebrew for Mac, by Daniel Cade
|
Added : homebrew for Mac, by Daniel Cade
|
||||||
Added : more examples
|
Added : more examples
|
||||||
@@ -170,6 +196,6 @@ frame concatenation support
|
|||||||
v0.1.1
|
v0.1.1
|
||||||
fix compression bug
|
fix compression bug
|
||||||
detects write-flush errors
|
detects write-flush errors
|
||||||
git@github.com:Cyan4973/zstd.git
|
|
||||||
v0.1.0
|
v0.1.0
|
||||||
first release
|
first release
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
Additional Grant of Patent Rights Version 2
|
||||||
|
|
||||||
|
"Software" means the Zstandard software distributed by Facebook, Inc.
|
||||||
|
|
||||||
|
Facebook, Inc. ("Facebook") hereby grants to each recipient of the Software
|
||||||
|
("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable
|
||||||
|
(subject to the termination provision below) license under any Necessary
|
||||||
|
Claims, to make, have made, use, sell, offer to sell, import, and otherwise
|
||||||
|
transfer the Software. For avoidance of doubt, no license is granted under
|
||||||
|
Facebook’s rights in any patent claims that are infringed by (i) modifications
|
||||||
|
to the Software made by you or any third party or (ii) the Software in
|
||||||
|
combination with any software or other technology.
|
||||||
|
|
||||||
|
The license granted hereunder will terminate, automatically and without notice,
|
||||||
|
if you (or any of your subsidiaries, corporate affiliates or agents) initiate
|
||||||
|
directly or indirectly, or take a direct financial interest in, any Patent
|
||||||
|
Assertion: (i) against Facebook or any of its subsidiaries or corporate
|
||||||
|
affiliates, (ii) against any party if such Patent Assertion arises in whole or
|
||||||
|
in part from any software, technology, product or service of Facebook or any of
|
||||||
|
its subsidiaries or corporate affiliates, or (iii) against any party relating
|
||||||
|
to the Software. Notwithstanding the foregoing, if Facebook or any of its
|
||||||
|
subsidiaries or corporate affiliates files a lawsuit alleging patent
|
||||||
|
infringement against you in the first instance, and you respond by filing a
|
||||||
|
patent infringement counterclaim in that lawsuit against that party that is
|
||||||
|
unrelated to the Software, the license granted hereunder will not terminate
|
||||||
|
under section (i) of this paragraph due to such counterclaim.
|
||||||
|
|
||||||
|
A "Necessary Claim" is a claim of a patent owned by Facebook that is
|
||||||
|
necessarily infringed by the Software standing alone.
|
||||||
|
|
||||||
|
A "Patent Assertion" is any lawsuit or other action alleging direct, indirect,
|
||||||
|
or contributory infringement or inducement to infringe any patent, including a
|
||||||
|
cross-claim or counterclaim.
|
||||||
@@ -7,10 +7,10 @@ you can consult a list of known ports on [Zstandard homepage](http://www.zstd.ne
|
|||||||
|
|
||||||
|Branch |Status |
|
|Branch |Status |
|
||||||
|------------|---------|
|
|------------|---------|
|
||||||
|master | [](https://travis-ci.org/Cyan4973/zstd) |
|
|master | [](https://travis-ci.org/facebook/zstd) |
|
||||||
|dev | [](https://travis-ci.org/Cyan4973/zstd) |
|
|dev | [](https://travis-ci.org/facebook/zstd) |
|
||||||
|
|
||||||
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.4.0, with 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.4.0, 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
|
||||||
@@ -19,7 +19,7 @@ As a reference, several fast compression algorithms were tested and compared on
|
|||||||
|Name | Ratio | C.speed | D.speed |
|
|Name | Ratio | C.speed | D.speed |
|
||||||
|-----------------|-------|--------:|--------:|
|
|-----------------|-------|--------:|--------:|
|
||||||
| | | MB/s | MB/s |
|
| | | MB/s | MB/s |
|
||||||
|**zstd 0.8.0 -1**|**2.877**|**330**| **930** |
|
|**zstd 0.8.2 -1**|**2.877**|**330**| **940** |
|
||||||
| [zlib] 1.2.8 -1 | 2.730 | 95 | 360 |
|
| [zlib] 1.2.8 -1 | 2.730 | 95 | 360 |
|
||||||
| brotli 0.4 -0 | 2.708 | 320 | 375 |
|
| brotli 0.4 -0 | 2.708 | 320 | 375 |
|
||||||
| QuickLZ 1.5 | 2.237 | 510 | 605 |
|
| QuickLZ 1.5 | 2.237 | 510 | 605 |
|
||||||
@@ -32,37 +32,35 @@ As a reference, several fast compression algorithms were tested and compared on
|
|||||||
[LZ4]: http://www.lz4.org/
|
[LZ4]: http://www.lz4.org/
|
||||||
|
|
||||||
Zstd can also offer stronger compression ratios 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] or lzma.
|
Speed vs Compression trade-off is configurable by small increments. Decompression speed is preserved and remains roughly the same at all settings, a property shared by most LZ compression algorithms, such as [zlib] or lzma.
|
||||||
|
|
||||||
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].
|
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 but at slower speed, falling outside of the graph.
|
Several algorithms can produce higher compression ratios, but at slower speeds, 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) .
|
||||||
|
|
||||||
|
|
||||||
### The case for Small Data compression
|
### The case for Small Data compression
|
||||||
|
|
||||||
Previous charts provide results applicable to typical files and streams scenarios (several MB). Small data come with different perspectives. The smaller the amount of data to compress, the more difficult it is to achieve any significant compression.
|
Previous charts provide results applicable to typical file and stream scenarios (several MB). Small data comes with different perspectives. The smaller the amount of data to compress, the more difficult it is to achieve any significant compression.
|
||||||
|
|
||||||
This problem is common to any compression algorithm. The reason is, compression algorithms learn from past data how to compress future data. But at the beginning of a new file, there is no "past" to build upon.
|
This problem is common to many compression algorithms. The reason is, compression algorithms learn from past data how to compress future data. But at the beginning of a new file, there is no "past" to build upon.
|
||||||
|
|
||||||
To solve this situation, Zstd offers a __training mode__, which can be used to tune the algorithm for a selected type of data, by providing it with a few samples. The result of the training is stored in a file called "dictionary", which can be loaded before compression and decompression. Using this dictionary, the compression ratio achievable on small data improves dramatically :
|
To solve this situation, Zstd offers a __training mode__, which can be used to tune the algorithm for a selected type of data, by providing it with a few samples. The result of the training is stored in a file called "dictionary", which can be loaded before compression and decompression. Using this dictionary, the compression ratio achievable on small data improves dramatically:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
These compression gains are achieved while simultaneously providing faster compression and decompression speeds.
|
These compression gains are achieved while simultaneously providing faster compression and decompression speeds.
|
||||||
|
|
||||||
Dictionary work if there is some correlation in a family of small data (there is no _universal dictionary_).
|
Dictionary works if there is some correlation in a family of small data (there is no _universal dictionary_).
|
||||||
Hence, deploying one dictionary per type of data will provide the greater benefits. Dictionary gains are mostly effective in the first few KB. Then, the compression algorithm will rely more and more on previously decoded content to compress the rest of the file.
|
Hence, deploying one dictionary per type of data will provide the greatest benefits. Dictionary gains are mostly effective in the first few KB. Then, the compression algorithm will rely more and more on previously decoded content to compress the rest of the file.
|
||||||
|
|
||||||
#### Dictionary compression How To :
|
#### Dictionary compression How To :
|
||||||
|
|
||||||
##### _Using the Command Line Utility_ :
|
|
||||||
|
|
||||||
1) Create the dictionary
|
1) Create the dictionary
|
||||||
|
|
||||||
`zstd --train FullPathToTrainingSet/* -o dictionaryName`
|
`zstd --train FullPathToTrainingSet/* -o dictionaryName`
|
||||||
@@ -75,16 +73,50 @@ Hence, deploying one dictionary per type of data will provide the greater benefi
|
|||||||
|
|
||||||
`zstd --decompress FILE.zst -D dictionaryName`
|
`zstd --decompress FILE.zst -D dictionaryName`
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
Once you have the repository cloned, there are multiple ways provided to build Zstandard.
|
||||||
|
|
||||||
|
#### Makefile
|
||||||
|
|
||||||
|
If your system is compatible with a standard `make` (or `gmake`) binary generator,
|
||||||
|
you can simply run it at the root directory.
|
||||||
|
It will generate `zstd` within root directory.
|
||||||
|
|
||||||
|
Other available options include :
|
||||||
|
- `make install` : create and install zstd binary, library and man page
|
||||||
|
- `make test` : create and run `zstd` and test tools on local platform
|
||||||
|
|
||||||
|
#### cmake
|
||||||
|
|
||||||
|
A `cmake` project generator is provided within `build/cmake`.
|
||||||
|
It can generate Makefiles or other build scripts
|
||||||
|
to create `zstd` binary, and `libzstd` dynamic and static libraries.
|
||||||
|
|
||||||
|
#### Visual (Windows)
|
||||||
|
|
||||||
|
Going into `build` directory, you will find additional possibilities :
|
||||||
|
- Projects for Visual Studio 2005, 2008 and 2010
|
||||||
|
+ VS2010 project is compatible with VS2012, VS2013 and VS2015
|
||||||
|
- Automated build scripts for Visual compiler by @KrzysFR , in `build/VS_scripts`,
|
||||||
|
which will build `zstd` cli and `libzstd` library without any need to open Visual Studio solution.
|
||||||
|
|
||||||
|
|
||||||
### Status
|
### Status
|
||||||
|
|
||||||
Zstd compression format has reached "Final status". It means it is planned to become the official stable zstd format 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.
|
Zstandard is currently deployed within Facebook. It is used daily to compress and decompress very large amounts of data in multiple formats and use cases.
|
||||||
Zstd library also offers legacy decoder support. Any data compressed by any version >= `v0.1` is decodable now and in the future.
|
Zstandard is considered safe for production environments.
|
||||||
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
|
### License
|
||||||
|
|
||||||
The "dev" branch is the one where all contributions will be merged before reaching "master". If you plan to propose a patch, please commit into the "dev" branch or its own feature branch. Direct commit to "master" are not permitted.
|
Zstandard is [BSD-licensed](LICENSE). We also provide an [additional patent grant](PATENTS).
|
||||||
|
|
||||||
|
### Contributing
|
||||||
|
|
||||||
|
The "dev" branch is the one where all contributions will be merged before reaching "master".
|
||||||
|
If you plan to propose a patch, please commit into the "dev" branch or its own feature branch.
|
||||||
|
Direct commit to "master" are not permitted.
|
||||||
|
For more information, please read [CONTRIBUTING](CONTRIBUTING.md).
|
||||||
|
|
||||||
### Miscellaneous
|
### Miscellaneous
|
||||||
|
|
||||||
|
|||||||
+102
-60
@@ -1,30 +1,31 @@
|
|||||||
version: 1.0.{build}
|
version: 1.0.{build}
|
||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
- COMPILER: "visual"
|
|
||||||
CONFIGURATION: "Debug"
|
|
||||||
PLATFORM: "x64"
|
|
||||||
- COMPILER: "visual"
|
|
||||||
CONFIGURATION: "Debug"
|
|
||||||
PLATFORM: "Win32"
|
|
||||||
- COMPILER: "visual"
|
|
||||||
CONFIGURATION: "Release"
|
|
||||||
PLATFORM: "x64"
|
|
||||||
- COMPILER: "visual"
|
|
||||||
CONFIGURATION: "Release"
|
|
||||||
PLATFORM: "Win32"
|
|
||||||
- COMPILER: "gcc"
|
- COMPILER: "gcc"
|
||||||
MAKE_PARAMS: "test"
|
MAKE_PARAMS: "test"
|
||||||
PLATFORM: "mingw64"
|
PLATFORM: "mingw64"
|
||||||
- COMPILER: "gcc"
|
- COMPILER: "gcc"
|
||||||
MAKE_PARAMS: "test"
|
MAKE_PARAMS: "test"
|
||||||
PLATFORM: "mingw32"
|
PLATFORM: "mingw32"
|
||||||
|
- COMPILER: "visual"
|
||||||
|
CONFIGURATION: "Debug"
|
||||||
|
PLATFORM: "x64"
|
||||||
|
- COMPILER: "visual"
|
||||||
|
CONFIGURATION: "Debug"
|
||||||
|
PLATFORM: "Win32"
|
||||||
|
- COMPILER: "visual"
|
||||||
|
CONFIGURATION: "Release"
|
||||||
|
PLATFORM: "x64"
|
||||||
|
- COMPILER: "visual"
|
||||||
|
CONFIGURATION: "Release"
|
||||||
|
PLATFORM: "Win32"
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- ECHO Installing %COMPILER% %PLATFORM% %CONFIGURATION%
|
- ECHO Installing %COMPILER% %PLATFORM% %CONFIGURATION%
|
||||||
|
- MKDIR bin
|
||||||
- if [%COMPILER%]==[gcc] SET PATH_ORIGINAL=%PATH%
|
- if [%COMPILER%]==[gcc] SET PATH_ORIGINAL=%PATH%
|
||||||
- if [%COMPILER%]==[gcc] (
|
- 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 "CLANG_PARAMS=-C tests 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_MINGW32=c:\MinGW\bin;c:\MinGW\usr\bin" &&
|
||||||
SET "PATH_MINGW64=c:\msys64\mingw64\bin;c:\msys64\usr\bin" &&
|
SET "PATH_MINGW64=c:\msys64\mingw64\bin;c:\msys64\usr\bin" &&
|
||||||
COPY C:\MinGW\bin\mingw32-make.exe C:\MinGW\bin\make.exe &&
|
COPY C:\MinGW\bin\mingw32-make.exe C:\MinGW\bin\make.exe &&
|
||||||
@@ -35,8 +36,8 @@ install:
|
|||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- ECHO Building %COMPILER% %PLATFORM% %CONFIGURATION%
|
- ECHO Building %COMPILER% %PLATFORM% %CONFIGURATION%
|
||||||
- if [%PLATFORM%]==[mingw32] SET PATH=%PATH_MINGW32%;%PATH_ORIGINAL%
|
- if [%PLATFORM%]==[mingw32] SET PATH=%PATH_MINGW32%;%PATH_ORIGINAL%
|
||||||
- if [%PLATFORM%]==[mingw64] SET PATH=%PATH_MINGW64%;%PATH_ORIGINAL%
|
- if [%PLATFORM%]==[mingw64] SET PATH=%PATH_MINGW64%;%PATH_ORIGINAL%
|
||||||
- if [%PLATFORM%]==[mingw64] (
|
- if [%PLATFORM%]==[mingw64] (
|
||||||
make clean &&
|
make clean &&
|
||||||
ECHO *** &&
|
ECHO *** &&
|
||||||
@@ -44,8 +45,16 @@ build_script:
|
|||||||
ECHO *** &&
|
ECHO *** &&
|
||||||
ECHO make %CLANG_PARAMS% &&
|
ECHO make %CLANG_PARAMS% &&
|
||||||
make %CLANG_PARAMS% &&
|
make %CLANG_PARAMS% &&
|
||||||
COPY programs\fuzzer.exe projects\fuzzer_clang.exe &&
|
COPY tests\fuzzer.exe tests\fuzzer_clang.exe &&
|
||||||
make clean
|
make clean &&
|
||||||
|
ECHO *** &&
|
||||||
|
ECHO *** Building pzstd for %PLATFORM% &&
|
||||||
|
ECHO *** &&
|
||||||
|
ECHO make -C contrib\pzstd pzstd &&
|
||||||
|
make -C contrib\pzstd pzstd &&
|
||||||
|
make -C contrib\pzstd googletest-mingw64 &&
|
||||||
|
make -C contrib\pzstd test &&
|
||||||
|
make -C contrib\pzstd clean
|
||||||
)
|
)
|
||||||
- if [%COMPILER%]==[gcc] (
|
- if [%COMPILER%]==[gcc] (
|
||||||
ECHO *** &&
|
ECHO *** &&
|
||||||
@@ -54,76 +63,109 @@ build_script:
|
|||||||
make -v &&
|
make -v &&
|
||||||
cc -v &&
|
cc -v &&
|
||||||
ECHO make %MAKE_PARAMS% &&
|
ECHO make %MAKE_PARAMS% &&
|
||||||
make %MAKE_PARAMS% &&
|
make %MAKE_PARAMS%
|
||||||
make clean
|
|
||||||
)
|
)
|
||||||
|
- if [%COMPILER%]==[gcc] if [%PLATFORM%]==[mingw64] (
|
||||||
|
COPY programs\zstd.exe bin\zstd.exe &&
|
||||||
|
appveyor PushArtifact bin\zstd.exe
|
||||||
|
)
|
||||||
|
- if [%COMPILER%]==[gcc] if [%PLATFORM%]==[mingw32] (
|
||||||
|
COPY programs\zstd.exe bin\zstd32.exe &&
|
||||||
|
appveyor PushArtifact bin\zstd32.exe
|
||||||
|
)
|
||||||
|
- if [%COMPILER%]==[gcc] make clean
|
||||||
- if [%COMPILER%]==[visual] (
|
- if [%COMPILER%]==[visual] (
|
||||||
ECHO *** &&
|
ECHO *** &&
|
||||||
ECHO *** Building Visual Studio 2008 %PLATFORM%\%CONFIGURATION% in %APPVEYOR_BUILD_FOLDER% &&
|
ECHO *** Building Visual Studio 2008 %PLATFORM%\%CONFIGURATION% in %APPVEYOR_BUILD_FOLDER% &&
|
||||||
ECHO *** &&
|
ECHO *** &&
|
||||||
msbuild "projects\VS2008\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v90 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
msbuild "build\VS2008\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v90 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
||||||
DIR projects\VS2008\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
DIR build\VS2008\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
||||||
MD5sum projects/VS2008/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
MD5sum build/VS2008/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
||||||
COPY projects\VS2008\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe projects\fuzzer_VS2008_%PLATFORM%_%CONFIGURATION%.exe &&
|
COPY build\VS2008\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2008_%PLATFORM%_%CONFIGURATION%.exe &&
|
||||||
ECHO *** &&
|
ECHO *** &&
|
||||||
ECHO *** Building Visual Studio 2010 %PLATFORM%\%CONFIGURATION% &&
|
ECHO *** Building Visual Studio 2010 %PLATFORM%\%CONFIGURATION% &&
|
||||||
ECHO *** &&
|
ECHO *** &&
|
||||||
msbuild "projects\VS2010\zstd.sln" %ADDITIONALPARAM% /m /verbosity:minimal /property:PlatformToolset=v100 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\projects\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
msbuild "build\VS2010\zstd.sln" %ADDITIONALPARAM% /m /verbosity:minimal /property:PlatformToolset=v100 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
||||||
DIR projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
||||||
MD5sum projects/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
||||||
msbuild "projects\VS2010\zstd.sln" %ADDITIONALPARAM% /m /verbosity:minimal /property:PlatformToolset=v100 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
msbuild "build\VS2010\zstd.sln" %ADDITIONALPARAM% /m /verbosity:minimal /property:PlatformToolset=v100 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
||||||
DIR projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
||||||
MD5sum projects/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
||||||
COPY projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe projects\fuzzer_VS2010_%PLATFORM%_%CONFIGURATION%.exe &&
|
COPY build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2010_%PLATFORM%_%CONFIGURATION%.exe &&
|
||||||
ECHO *** &&
|
ECHO *** &&
|
||||||
ECHO *** Building Visual Studio 2012 %PLATFORM%\%CONFIGURATION% &&
|
ECHO *** Building Visual Studio 2012 %PLATFORM%\%CONFIGURATION% &&
|
||||||
ECHO *** &&
|
ECHO *** &&
|
||||||
msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\projects\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
||||||
DIR projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
||||||
MD5sum projects/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
||||||
msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
||||||
DIR projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
||||||
MD5sum projects/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
||||||
COPY projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe projects\fuzzer_VS2012_%PLATFORM%_%CONFIGURATION%.exe &&
|
COPY build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2012_%PLATFORM%_%CONFIGURATION%.exe &&
|
||||||
ECHO *** &&
|
ECHO *** &&
|
||||||
ECHO *** Building Visual Studio 2013 %PLATFORM%\%CONFIGURATION% &&
|
ECHO *** Building Visual Studio 2013 %PLATFORM%\%CONFIGURATION% &&
|
||||||
ECHO *** &&
|
ECHO *** &&
|
||||||
msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v120 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\projects\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v120 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
||||||
DIR projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
||||||
MD5sum projects/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
||||||
msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v120 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v120 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
||||||
DIR projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
||||||
MD5sum projects/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
||||||
COPY projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe projects\fuzzer_VS2013_%PLATFORM%_%CONFIGURATION%.exe &&
|
COPY build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2013_%PLATFORM%_%CONFIGURATION%.exe &&
|
||||||
ECHO *** &&
|
ECHO *** &&
|
||||||
ECHO *** Building Visual Studio 2015 %PLATFORM%\%CONFIGURATION% &&
|
ECHO *** Building Visual Studio 2015 %PLATFORM%\%CONFIGURATION% &&
|
||||||
ECHO *** &&
|
ECHO *** &&
|
||||||
msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\projects\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
||||||
DIR projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
||||||
MD5sum projects/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
||||||
msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
|
||||||
DIR projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe &&
|
||||||
MD5sum projects/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe &&
|
||||||
COPY projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe projects\fuzzer_VS2015_%PLATFORM%_%CONFIGURATION%.exe &&
|
COPY build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2015_%PLATFORM%_%CONFIGURATION%.exe &&
|
||||||
COPY projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe programs\
|
COPY build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe tests\
|
||||||
)
|
)
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- ECHO Testing %COMPILER% %PLATFORM% %CONFIGURATION%
|
- ECHO Testing %COMPILER% %PLATFORM% %CONFIGURATION%
|
||||||
- SET FUZZERTEST=-T1mn
|
- SET FUZZERTEST=-T1mn
|
||||||
- if [%COMPILER%]==[gcc] (
|
- if [%COMPILER%]==[gcc] (
|
||||||
if [%PLATFORM%]==[mingw64] projects\fuzzer_clang.exe %FUZZERTEST%
|
if [%PLATFORM%]==[mingw64] tests\fuzzer_clang.exe %FUZZERTEST%
|
||||||
)
|
)
|
||||||
- if [%COMPILER%]==[visual] if [%CONFIGURATION%]==[Release] (
|
- if [%COMPILER%]==[visual] if [%CONFIGURATION%]==[Release] (
|
||||||
CD programs &&
|
CD tests &&
|
||||||
SET ZSTD=./zstd.exe &&
|
SET ZSTD=./zstd.exe &&
|
||||||
sh -e playTests.sh --test-large-data &&
|
sh -e playTests.sh --test-large-data &&
|
||||||
fullbench.exe -i1 &&
|
fullbench.exe -i1 &&
|
||||||
fullbench.exe -i1 -P0 &&
|
fullbench.exe -i1 -P0 &&
|
||||||
CD .. &&
|
fuzzer_VS2008_%PLATFORM%_Release.exe %FUZZERTEST% &&
|
||||||
projects\fuzzer_VS2008_%PLATFORM%_Release.exe %FUZZERTEST% &&
|
fuzzer_VS2010_%PLATFORM%_Release.exe %FUZZERTEST% &&
|
||||||
projects\fuzzer_VS2010_%PLATFORM%_Release.exe %FUZZERTEST% &&
|
fuzzer_VS2012_%PLATFORM%_Release.exe %FUZZERTEST% &&
|
||||||
projects\fuzzer_VS2012_%PLATFORM%_Release.exe %FUZZERTEST% &&
|
fuzzer_VS2013_%PLATFORM%_Release.exe %FUZZERTEST% &&
|
||||||
projects\fuzzer_VS2013_%PLATFORM%_Release.exe %FUZZERTEST% &&
|
fuzzer_VS2015_%PLATFORM%_Release.exe %FUZZERTEST%
|
||||||
projects\fuzzer_VS2015_%PLATFORM%_Release.exe %FUZZERTEST%
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
- path: bin\zstd.exe
|
||||||
|
- path: bin\zstd32.exe
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
- provider: GitHub
|
||||||
|
auth_token:
|
||||||
|
secure: LgJo8emYc3sFnlNWkGl4/VYK3nk/8+RagcsqDlAi3xeqNGNutnKjcftjg84uJoT4
|
||||||
|
artifact: bin\zstd.exe
|
||||||
|
force_update: true
|
||||||
|
on:
|
||||||
|
branch: autobuild
|
||||||
|
COMPILER: gcc
|
||||||
|
PLATFORM: "mingw64"
|
||||||
|
appveyor_repo_tag: true
|
||||||
|
- provider: GitHub
|
||||||
|
auth_token:
|
||||||
|
secure: LgJo8emYc3sFnlNWkGl4/VYK3nk/8+RagcsqDlAi3xeqNGNutnKjcftjg84uJoT4
|
||||||
|
artifact: bin\zstd32.exe
|
||||||
|
force_update: true
|
||||||
|
on:
|
||||||
|
branch: autobuild
|
||||||
|
COMPILER: gcc
|
||||||
|
PLATFORM: "mingw32"
|
||||||
|
appveyor_repo_tag: true
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
*Copy
|
*Copy
|
||||||
|
|
||||||
# Visual C++
|
# Visual C++
|
||||||
build/
|
bin/
|
||||||
VS2005/
|
VS2005/
|
||||||
VS2008/
|
VS2008/
|
||||||
VS2010/
|
VS2010/
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
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
|
||||||
|
- `VS2005` - Visual Studio 2005 project
|
||||||
|
- `VS2008` - Visual Studio 2008 project
|
||||||
|
- `VS2010` - Visual Studio 2010 project (which also works well with Visual Studio 2012, 2013, 2015)
|
||||||
|
- `VS_scripts` - command line scripts prepared for Visual Studio compilation without IDE
|
||||||
|
|
||||||
|
|
||||||
|
#### How to compile zstd with Visual Studio
|
||||||
|
|
||||||
|
1. Install Visual Studio e.g. VS 2015 Community Edition (it's free).
|
||||||
|
2. Download the latest version of zstd from https://github.com/facebook/zstd/releases
|
||||||
|
3. Decompress ZIP archive.
|
||||||
|
4. Go to decompressed directory then to `projects` then `VS2010` and open `zstd.sln`
|
||||||
|
5. Visual Studio will ask about converting VS2010 project to VS2015 and you should agree.
|
||||||
|
6. Change `Debug` to `Release` and if you have 64-bit Windows change also `Win32` to `x64`.
|
||||||
|
7. Press F7 on keyboard or select `BUILD` from the menu bar and choose `Build Solution`.
|
||||||
|
8. If compilation will be fine a compiled executable will be in `projects\VS2010\bin\x64\Release\zstd.exe`
|
||||||
+5
-5
@@ -43,7 +43,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
@@ -119,7 +119,7 @@
|
|||||||
Optimization="2"
|
Optimization="2"
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
@@ -193,7 +193,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
@@ -270,7 +270,7 @@
|
|||||||
Optimization="2"
|
Optimization="2"
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
@@ -348,7 +348,7 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\programs\fullbench.c"
|
RelativePath="..\..\..\tests\fullbench.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\programs"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
@@ -119,7 +119,7 @@
|
|||||||
Optimization="2"
|
Optimization="2"
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\programs"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
@@ -193,7 +193,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\programs"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
@@ -270,7 +270,7 @@
|
|||||||
Optimization="2"
|
Optimization="2"
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\programs"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
@@ -348,7 +348,7 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\programs\fuzzer.c"
|
RelativePath="..\..\..\tests\fuzzer.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
@@ -43,8 +43,8 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
@@ -120,8 +120,8 @@
|
|||||||
Optimization="2"
|
Optimization="2"
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
@@ -195,8 +195,8 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
@@ -273,8 +273,8 @@
|
|||||||
Optimization="2"
|
Optimization="2"
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
@@ -355,10 +355,6 @@
|
|||||||
RelativePath="..\..\..\programs\fileio.c"
|
RelativePath="..\..\..\programs\fileio.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\..\programs\legacy\fileio_legacy.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\lib\compress\fse_compress.c"
|
RelativePath="..\..\..\lib\compress\fse_compress.c"
|
||||||
>
|
>
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(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"
|
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
@@ -120,7 +120,7 @@
|
|||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(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"
|
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
@@ -194,7 +194,7 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(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"
|
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
@@ -271,7 +271,7 @@
|
|||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(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"
|
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
@@ -379,6 +379,34 @@
|
|||||||
RelativePath="..\..\..\lib\decompress\zstd_decompress.c"
|
RelativePath="..\..\..\lib\decompress\zstd_decompress.c"
|
||||||
>
|
>
|
||||||
</File>
|
</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="..\..\..\lib\legacy\zstd_v07.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
@@ -481,6 +509,14 @@
|
|||||||
RelativePath="..\..\..\lib\legacy\zstd_v05.h"
|
RelativePath="..\..\..\lib\legacy\zstd_v05.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v06.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v07.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Resource Files"
|
Name="Resource Files"
|
||||||
+5
-5
@@ -44,7 +44,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\programs\legacy"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
@@ -120,7 +120,7 @@
|
|||||||
Optimization="2"
|
Optimization="2"
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\programs\legacy"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
@@ -194,7 +194,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\programs\legacy"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
@@ -271,7 +271,7 @@
|
|||||||
Optimization="2"
|
Optimization="2"
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\programs\legacy"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
@@ -349,7 +349,7 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\programs\fullbench.c"
|
RelativePath="..\..\..\tests\fullbench.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
@@ -120,7 +120,7 @@
|
|||||||
Optimization="2"
|
Optimization="2"
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
@@ -194,7 +194,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
@@ -271,7 +271,7 @@
|
|||||||
Optimization="2"
|
Optimization="2"
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
@@ -349,7 +349,7 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\programs\fuzzer.c"
|
RelativePath="..\..\..\tests\fuzzer.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
@@ -44,8 +44,8 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
@@ -121,8 +121,8 @@
|
|||||||
Optimization="2"
|
Optimization="2"
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
@@ -196,8 +196,8 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
@@ -274,8 +274,8 @@
|
|||||||
Optimization="2"
|
Optimization="2"
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
@@ -356,10 +356,6 @@
|
|||||||
RelativePath="..\..\..\programs\fileio.c"
|
RelativePath="..\..\..\programs\fileio.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\..\programs\legacy\fileio_legacy.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\lib\compress\fse_compress.c"
|
RelativePath="..\..\..\lib\compress\fse_compress.c"
|
||||||
>
|
>
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(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"
|
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
@@ -121,7 +121,7 @@
|
|||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(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"
|
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
@@ -195,7 +195,7 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(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"
|
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
@@ -272,7 +272,7 @@
|
|||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(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"
|
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
@@ -380,6 +380,34 @@
|
|||||||
RelativePath="..\..\..\lib\decompress\zstd_decompress.c"
|
RelativePath="..\..\..\lib\decompress\zstd_decompress.c"
|
||||||
>
|
>
|
||||||
</File>
|
</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="..\..\..\lib\legacy\zstd_v07.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
@@ -482,6 +510,14 @@
|
|||||||
RelativePath="..\..\..\lib\legacy\zstd_v05.h"
|
RelativePath="..\..\..\lib\legacy\zstd_v05.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v06.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\lib\legacy\zstd_v07.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Resource Files"
|
Name="Resource Files"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
@@ -66,24 +66,24 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
@@ -157,7 +157,7 @@
|
|||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\..\programs\datagen.c" />
|
<ClCompile Include="..\..\..\programs\datagen.c" />
|
||||||
<ClCompile Include="..\..\..\programs\datagencli.c" />
|
<ClCompile Include="..\..\..\tests\datagencli.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\programs\datagen.h" />
|
<ClInclude Include="..\..\..\programs\datagen.h" />
|
||||||
+6
-6
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
@@ -65,24 +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>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
<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>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(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>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
<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>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(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'">
|
||||||
@@ -168,7 +168,7 @@
|
|||||||
<ClCompile Include="..\..\..\lib\decompress\zbuff_decompress.c" />
|
<ClCompile Include="..\..\..\lib\decompress\zbuff_decompress.c" />
|
||||||
<ClCompile Include="..\..\..\lib\decompress\zstd_decompress.c" />
|
<ClCompile Include="..\..\..\lib\decompress\zstd_decompress.c" />
|
||||||
<ClCompile Include="..\..\..\programs\datagen.c" />
|
<ClCompile Include="..\..\..\programs\datagen.c" />
|
||||||
<ClCompile Include="..\..\..\programs\fullbench.c" />
|
<ClCompile Include="..\..\..\tests\fullbench.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\lib\common\fse.h" />
|
<ClInclude Include="..\..\..\lib\common\fse.h" />
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
@@ -66,24 +66,24 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(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>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(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>
|
||||||
@@ -168,7 +168,7 @@
|
|||||||
<ClCompile Include="..\..\..\lib\dictBuilder\divsufsort.c" />
|
<ClCompile Include="..\..\..\lib\dictBuilder\divsufsort.c" />
|
||||||
<ClCompile Include="..\..\..\lib\dictBuilder\zdict.c" />
|
<ClCompile Include="..\..\..\lib\dictBuilder\zdict.c" />
|
||||||
<ClCompile Include="..\..\..\programs\datagen.c" />
|
<ClCompile Include="..\..\..\programs\datagen.c" />
|
||||||
<ClCompile Include="..\..\..\programs\fuzzer.c" />
|
<ClCompile Include="..\..\..\tests\fuzzer.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\lib\common\fse.h" />
|
<ClInclude Include="..\..\..\lib\common\fse.h" />
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
REM http://stackoverflow.com/questions/708238/how-do-i-add-an-icon-to-a-mingw-gcc-compiled-executable
|
||||||
|
REM copy "c:\Program Files (x86)\Windows Kits\8.1\Include\um\verrsrc.h" .
|
||||||
|
windres -I ..\..\..\..\lib -O coff -I . -i ..\zstd.rc -o zstd.res
|
||||||
@@ -0,0 +1,172 @@
|
|||||||
|
#include <winapifamily.h>
|
||||||
|
|
||||||
|
/*****************************************************************************\
|
||||||
|
* *
|
||||||
|
* verrsrc.h - Version Resource definitions *
|
||||||
|
* *
|
||||||
|
* Include file declaring version resources in rc files *
|
||||||
|
* *
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved. *
|
||||||
|
* *
|
||||||
|
\*****************************************************************************/
|
||||||
|
|
||||||
|
#pragma region Application Family
|
||||||
|
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
||||||
|
|
||||||
|
/* ----- Symbols ----- */
|
||||||
|
#define VS_FILE_INFO RT_VERSION
|
||||||
|
#define VS_VERSION_INFO 1
|
||||||
|
#define VS_USER_DEFINED 100
|
||||||
|
|
||||||
|
/* ----- VS_VERSION.dwFileFlags ----- */
|
||||||
|
#ifndef _MAC
|
||||||
|
#define VS_FFI_SIGNATURE 0xFEEF04BDL
|
||||||
|
#else
|
||||||
|
#define VS_FFI_SIGNATURE 0xBD04EFFEL
|
||||||
|
#endif
|
||||||
|
#define VS_FFI_STRUCVERSION 0x00010000L
|
||||||
|
#define VS_FFI_FILEFLAGSMASK 0x0000003FL
|
||||||
|
|
||||||
|
/* ----- VS_VERSION.dwFileFlags ----- */
|
||||||
|
#define VS_FF_DEBUG 0x00000001L
|
||||||
|
#define VS_FF_PRERELEASE 0x00000002L
|
||||||
|
#define VS_FF_PATCHED 0x00000004L
|
||||||
|
#define VS_FF_PRIVATEBUILD 0x00000008L
|
||||||
|
#define VS_FF_INFOINFERRED 0x00000010L
|
||||||
|
#define VS_FF_SPECIALBUILD 0x00000020L
|
||||||
|
|
||||||
|
/* ----- VS_VERSION.dwFileOS ----- */
|
||||||
|
#define VOS_UNKNOWN 0x00000000L
|
||||||
|
#define VOS_DOS 0x00010000L
|
||||||
|
#define VOS_OS216 0x00020000L
|
||||||
|
#define VOS_OS232 0x00030000L
|
||||||
|
#define VOS_NT 0x00040000L
|
||||||
|
#define VOS_WINCE 0x00050000L
|
||||||
|
|
||||||
|
#define VOS__BASE 0x00000000L
|
||||||
|
#define VOS__WINDOWS16 0x00000001L
|
||||||
|
#define VOS__PM16 0x00000002L
|
||||||
|
#define VOS__PM32 0x00000003L
|
||||||
|
#define VOS__WINDOWS32 0x00000004L
|
||||||
|
|
||||||
|
#define VOS_DOS_WINDOWS16 0x00010001L
|
||||||
|
#define VOS_DOS_WINDOWS32 0x00010004L
|
||||||
|
#define VOS_OS216_PM16 0x00020002L
|
||||||
|
#define VOS_OS232_PM32 0x00030003L
|
||||||
|
#define VOS_NT_WINDOWS32 0x00040004L
|
||||||
|
|
||||||
|
/* ----- VS_VERSION.dwFileType ----- */
|
||||||
|
#define VFT_UNKNOWN 0x00000000L
|
||||||
|
#define VFT_APP 0x00000001L
|
||||||
|
#define VFT_DLL 0x00000002L
|
||||||
|
#define VFT_DRV 0x00000003L
|
||||||
|
#define VFT_FONT 0x00000004L
|
||||||
|
#define VFT_VXD 0x00000005L
|
||||||
|
#define VFT_STATIC_LIB 0x00000007L
|
||||||
|
|
||||||
|
/* ----- VS_VERSION.dwFileSubtype for VFT_WINDOWS_DRV ----- */
|
||||||
|
#define VFT2_UNKNOWN 0x00000000L
|
||||||
|
#define VFT2_DRV_PRINTER 0x00000001L
|
||||||
|
#define VFT2_DRV_KEYBOARD 0x00000002L
|
||||||
|
#define VFT2_DRV_LANGUAGE 0x00000003L
|
||||||
|
#define VFT2_DRV_DISPLAY 0x00000004L
|
||||||
|
#define VFT2_DRV_MOUSE 0x00000005L
|
||||||
|
#define VFT2_DRV_NETWORK 0x00000006L
|
||||||
|
#define VFT2_DRV_SYSTEM 0x00000007L
|
||||||
|
#define VFT2_DRV_INSTALLABLE 0x00000008L
|
||||||
|
#define VFT2_DRV_SOUND 0x00000009L
|
||||||
|
#define VFT2_DRV_COMM 0x0000000AL
|
||||||
|
#define VFT2_DRV_INPUTMETHOD 0x0000000BL
|
||||||
|
#define VFT2_DRV_VERSIONED_PRINTER 0x0000000CL
|
||||||
|
|
||||||
|
/* ----- VS_VERSION.dwFileSubtype for VFT_WINDOWS_FONT ----- */
|
||||||
|
#define VFT2_FONT_RASTER 0x00000001L
|
||||||
|
#define VFT2_FONT_VECTOR 0x00000002L
|
||||||
|
#define VFT2_FONT_TRUETYPE 0x00000003L
|
||||||
|
|
||||||
|
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Desktop Family
|
||||||
|
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
|
||||||
|
/* ----- VerFindFile() flags ----- */
|
||||||
|
#define VFFF_ISSHAREDFILE 0x0001
|
||||||
|
|
||||||
|
#define VFF_CURNEDEST 0x0001
|
||||||
|
#define VFF_FILEINUSE 0x0002
|
||||||
|
#define VFF_BUFFTOOSMALL 0x0004
|
||||||
|
|
||||||
|
/* ----- VerInstallFile() flags ----- */
|
||||||
|
#define VIFF_FORCEINSTALL 0x0001
|
||||||
|
#define VIFF_DONTDELETEOLD 0x0002
|
||||||
|
|
||||||
|
#define VIF_TEMPFILE 0x00000001L
|
||||||
|
#define VIF_MISMATCH 0x00000002L
|
||||||
|
#define VIF_SRCOLD 0x00000004L
|
||||||
|
|
||||||
|
#define VIF_DIFFLANG 0x00000008L
|
||||||
|
#define VIF_DIFFCODEPG 0x00000010L
|
||||||
|
#define VIF_DIFFTYPE 0x00000020L
|
||||||
|
|
||||||
|
#define VIF_WRITEPROT 0x00000040L
|
||||||
|
#define VIF_FILEINUSE 0x00000080L
|
||||||
|
#define VIF_OUTOFSPACE 0x00000100L
|
||||||
|
#define VIF_ACCESSVIOLATION 0x00000200L
|
||||||
|
#define VIF_SHARINGVIOLATION 0x00000400L
|
||||||
|
#define VIF_CANNOTCREATE 0x00000800L
|
||||||
|
#define VIF_CANNOTDELETE 0x00001000L
|
||||||
|
#define VIF_CANNOTRENAME 0x00002000L
|
||||||
|
#define VIF_CANNOTDELETECUR 0x00004000L
|
||||||
|
#define VIF_OUTOFMEMORY 0x00008000L
|
||||||
|
|
||||||
|
#define VIF_CANNOTREADSRC 0x00010000L
|
||||||
|
#define VIF_CANNOTREADDST 0x00020000L
|
||||||
|
|
||||||
|
#define VIF_BUFFTOOSMALL 0x00040000L
|
||||||
|
#define VIF_CANNOTLOADLZ32 0x00080000L
|
||||||
|
#define VIF_CANNOTLOADCABINET 0x00100000L
|
||||||
|
|
||||||
|
#ifndef RC_INVOKED /* RC doesn't need to see the rest of this */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
FILE_VER_GET_... flags are for use by
|
||||||
|
GetFileVersionInfoSizeEx
|
||||||
|
GetFileVersionInfoExW
|
||||||
|
*/
|
||||||
|
#define FILE_VER_GET_LOCALISED 0x01
|
||||||
|
#define FILE_VER_GET_NEUTRAL 0x02
|
||||||
|
#define FILE_VER_GET_PREFETCHED 0x04
|
||||||
|
|
||||||
|
/* ----- Types and structures ----- */
|
||||||
|
|
||||||
|
typedef struct tagVS_FIXEDFILEINFO
|
||||||
|
{
|
||||||
|
DWORD dwSignature; /* e.g. 0xfeef04bd */
|
||||||
|
DWORD dwStrucVersion; /* e.g. 0x00000042 = "0.42" */
|
||||||
|
DWORD dwFileVersionMS; /* e.g. 0x00030075 = "3.75" */
|
||||||
|
DWORD dwFileVersionLS; /* e.g. 0x00000031 = "0.31" */
|
||||||
|
DWORD dwProductVersionMS; /* e.g. 0x00030010 = "3.10" */
|
||||||
|
DWORD dwProductVersionLS; /* e.g. 0x00000031 = "0.31" */
|
||||||
|
DWORD dwFileFlagsMask; /* = 0x3F for version "0.42" */
|
||||||
|
DWORD dwFileFlags; /* e.g. VFF_DEBUG | VFF_PRERELEASE */
|
||||||
|
DWORD dwFileOS; /* e.g. VOS_DOS_WINDOWS16 */
|
||||||
|
DWORD dwFileType; /* e.g. VFT_DRIVER */
|
||||||
|
DWORD dwFileSubtype; /* e.g. VFT2_DRV_KEYBOARD */
|
||||||
|
DWORD dwFileDateMS; /* e.g. 0 */
|
||||||
|
DWORD dwFileDateLS; /* e.g. 0 */
|
||||||
|
} VS_FIXEDFILEINFO;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !RC_INVOKED */
|
||||||
|
|
||||||
|
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
@@ -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_VERSION_MAJOR,ZSTD_VERSION_MINOR,ZSTD_VERSION_RELEASE,0
|
||||||
|
PRODUCTVERSION ZSTD_VERSION_MAJOR,ZSTD_VERSION_MINOR,ZSTD_VERSION_RELEASE,0
|
||||||
|
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", "zstd.exe"
|
||||||
|
VALUE "LegalCopyright", "Copyright (C) 2013-2016, Yann Collet"
|
||||||
|
VALUE "OriginalFilename", "zstd.exe"
|
||||||
|
VALUE "ProductName", "Zstandard"
|
||||||
|
VALUE "ProductVersion", ZSTD_VERSION_STRING
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x0409, 1200
|
||||||
|
END
|
||||||
|
END
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -43,7 +43,6 @@
|
|||||||
<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\zstdcli.c" />
|
<ClCompile Include="..\..\..\programs\zstdcli.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -68,9 +67,11 @@
|
|||||||
<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\util.h" />
|
<ClInclude Include="..\..\..\programs\util.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="zstd.rc" />
|
||||||
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<ProjectGuid>{4E52A41A-F33B-4C7A-8C36-A1A6B4F4277C}</ProjectGuid>
|
<ProjectGuid>{4E52A41A-F33B-4C7A-8C36-A1A6B4F4277C}</ProjectGuid>
|
||||||
<Keyword>Win32Proj</Keyword>
|
<Keyword>Win32Proj</Keyword>
|
||||||
@@ -118,27 +119,27 @@
|
|||||||
<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>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
<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>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
<LibraryPath>$(LibraryPath);</LibraryPath>
|
<LibraryPath>$(LibraryPath);</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
<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>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath);</IncludePath>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
<LibraryPath>$(LibraryPath);</LibraryPath>
|
<LibraryPath>$(LibraryPath);</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -148,7 +149,7 @@
|
|||||||
</PrecompiledHeader>
|
</PrecompiledHeader>
|
||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -164,7 +165,7 @@
|
|||||||
</PrecompiledHeader>
|
</PrecompiledHeader>
|
||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -182,7 +183,7 @@
|
|||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<TreatWarningAsError>false</TreatWarningAsError>
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
@@ -203,7 +204,7 @@
|
|||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>false</TreatWarningAsError>
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
@@ -1,51 +1,51 @@
|
|||||||
// Microsoft Visual C++ generated resource script.
|
// Microsoft Visual C++ generated resource script.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "zstd.h" /* ZSTD_VERSION_STRING */
|
#include "zstd.h" /* ZSTD_VERSION_STRING */
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
#define APSTUDIO_READONLY_SYMBOLS
|
||||||
#include "verrsrc.h"
|
#include "verrsrc.h"
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
#undef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||||
LANGUAGE 9, 1
|
LANGUAGE 9, 1
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Version
|
// Version
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION ZSTD_LIB_VERSION
|
FILEVERSION ZSTD_VERSION_MAJOR,ZSTD_VERSION_MINOR,ZSTD_VERSION_RELEASE,0
|
||||||
PRODUCTVERSION ZSTD_LIB_VERSION
|
PRODUCTVERSION ZSTD_VERSION_MAJOR,ZSTD_VERSION_MINOR,ZSTD_VERSION_RELEASE,0
|
||||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS VS_FF_DEBUG
|
FILEFLAGS VS_FF_DEBUG
|
||||||
#else
|
#else
|
||||||
FILEFLAGS 0x0L
|
FILEFLAGS 0x0L
|
||||||
#endif
|
#endif
|
||||||
FILEOS VOS_NT_WINDOWS32
|
FILEOS VOS_NT_WINDOWS32
|
||||||
FILETYPE VFT_DLL
|
FILETYPE VFT_DLL
|
||||||
FILESUBTYPE VFT2_UNKNOWN
|
FILESUBTYPE VFT2_UNKNOWN
|
||||||
BEGIN
|
BEGIN
|
||||||
BLOCK "StringFileInfo"
|
BLOCK "StringFileInfo"
|
||||||
BEGIN
|
BEGIN
|
||||||
BLOCK "040904B0"
|
BLOCK "040904B0"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Yann Collet"
|
VALUE "CompanyName", "Yann Collet"
|
||||||
VALUE "FileDescription", "Fast and efficient compression algorithm"
|
VALUE "FileDescription", "Fast and efficient compression algorithm"
|
||||||
VALUE "FileVersion", ZSTD_VERSION_STRING
|
VALUE "FileVersion", ZSTD_VERSION_STRING
|
||||||
VALUE "InternalName", "zstdlib.dll"
|
VALUE "InternalName", "zstdlib.dll"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2013-2015, Yann Collet"
|
VALUE "LegalCopyright", "Copyright (C) 2013-2016, Yann Collet"
|
||||||
VALUE "OriginalFilename", "zstdlib.dll"
|
VALUE "OriginalFilename", "zstdlib.dll"
|
||||||
VALUE "ProductName", "Zstandard"
|
VALUE "ProductName", "Zstandard"
|
||||||
VALUE "ProductVersion", ZSTD_VERSION_STRING
|
VALUE "ProductVersion", ZSTD_VERSION_STRING
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "Translation", 0x0409, 1200
|
VALUE "Translation", 0x0409, 1200
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
@@ -32,6 +32,13 @@
|
|||||||
<ClCompile Include="..\..\..\lib\decompress\zstd_decompress.c" />
|
<ClCompile Include="..\..\..\lib\decompress\zstd_decompress.c" />
|
||||||
<ClCompile Include="..\..\..\lib\dictBuilder\divsufsort.c" />
|
<ClCompile Include="..\..\..\lib\dictBuilder\divsufsort.c" />
|
||||||
<ClCompile Include="..\..\..\lib\dictBuilder\zdict.c" />
|
<ClCompile Include="..\..\..\lib\dictBuilder\zdict.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v01.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v02.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v03.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v04.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v05.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v06.c" />
|
||||||
|
<ClCompile Include="..\..\..\lib\legacy\zstd_v07.c" />
|
||||||
<ClInclude Include="..\..\..\lib\common\bitstream.h" />
|
<ClInclude Include="..\..\..\lib\common\bitstream.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\error_private.h" />
|
<ClInclude Include="..\..\..\lib\common\error_private.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\error_public.h" />
|
<ClInclude Include="..\..\..\lib\common\error_public.h" />
|
||||||
@@ -40,10 +47,17 @@
|
|||||||
<ClInclude Include="..\..\..\lib\common\huf.h" />
|
<ClInclude Include="..\..\..\lib\common\huf.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\xxhash.h" />
|
<ClInclude Include="..\..\..\lib\common\xxhash.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zbuff.h" />
|
<ClInclude Include="..\..\..\lib\common\zbuff.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v01.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v02.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v03.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v04.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v05.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v06.h" />
|
||||||
|
<ClInclude Include="..\..\..\lib\legacy\zstd_v07.h" />
|
||||||
<ClInclude Include="..\..\..\lib\zstd.h" />
|
<ClInclude Include="..\..\..\lib\zstd.h" />
|
||||||
<ClInclude Include="..\..\..\lib\common\zstd_internal.h" />
|
<ClInclude Include="..\..\..\lib\common\zstd_internal.h" />
|
||||||
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h" />
|
<ClInclude Include="..\..\..\lib\compress\zstd_opt.h" />
|
||||||
<ClInclude Include="..\..\..\programs\util.h" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="zstdlib.rc" />
|
<ResourceCompile Include="zstdlib.rc" />
|
||||||
@@ -127,7 +141,7 @@
|
|||||||
</PrecompiledHeader>
|
</PrecompiledHeader>
|
||||||
<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_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>true</MinimalRebuild>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
@@ -147,7 +161,7 @@
|
|||||||
</PrecompiledHeader>
|
</PrecompiledHeader>
|
||||||
<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_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
@@ -167,7 +181,7 @@
|
|||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<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_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
@@ -189,7 +203,7 @@
|
|||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<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_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>false</TreatWarningAsError>
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
Command line scripts for Visual Studio compilation without IDE
|
||||||
|
==============================================================
|
||||||
|
|
||||||
Here are a few command lines for reference :
|
Here are a few command lines for reference :
|
||||||
|
|
||||||
### Build with Visual Studio 2013 for msvcr120.dll
|
### Build with Visual Studio 2013 for msvcr120.dll
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# ################################################################
|
||||||
|
# Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This source code is licensed under the BSD-style license found in the
|
||||||
|
# LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
# of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
# ################################################################
|
||||||
|
|
||||||
|
PROJECT(zstd)
|
||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.7)
|
||||||
|
|
||||||
|
OPTION(ZSTD_LEGACY_SUPPORT "LEGACY SUPPORT" OFF)
|
||||||
|
|
||||||
|
IF (ZSTD_LEGACY_SUPPORT)
|
||||||
|
MESSAGE(STATUS "ZSTD_LEGACY_SUPPORT defined!")
|
||||||
|
ADD_DEFINITIONS(-DZSTD_LEGACY_SUPPORT=1)
|
||||||
|
ELSE (ZSTD_LEGACY_SUPPORT)
|
||||||
|
MESSAGE(STATUS "ZSTD_LEGACY_SUPPORT not defined!")
|
||||||
|
ADD_DEFINITIONS(-DZSTD_LEGACY_SUPPORT=0)
|
||||||
|
ENDIF (ZSTD_LEGACY_SUPPORT)
|
||||||
|
|
||||||
|
ADD_SUBDIRECTORY(lib)
|
||||||
|
ADD_SUBDIRECTORY(programs)
|
||||||
|
ADD_SUBDIRECTORY(tests)
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
# Add extra compilation flags
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
INCLUDE(CMakeModules/AddExtraCompilationFlags.cmake)
|
||||||
|
ADD_EXTRA_COMPILATION_FLAGS()
|
||||||
|
|
||||||
|
ADD_CUSTOM_TARGET(clean-all
|
||||||
|
COMMAND ${CMAKE_BUILD_TOOL} clean
|
||||||
|
COMMAND rm -rf ${CMAKE_BINARY_DIR}/
|
||||||
|
)
|
||||||
@@ -108,7 +108,7 @@ IF (ZSTD_LEGACY_SUPPORT)
|
|||||||
ENDIF (ZSTD_LEGACY_SUPPORT)
|
ENDIF (ZSTD_LEGACY_SUPPORT)
|
||||||
|
|
||||||
IF (MSVC)
|
IF (MSVC)
|
||||||
SET(MSVC_RESOURCE_DIR ${ROOT_DIR}/projects/VS2010/zstdlib)
|
SET(MSVC_RESOURCE_DIR ${ROOT_DIR}/build/VS2010/zstdlib)
|
||||||
SET(PlatformDependResources ${MSVC_RESOURCE_DIR}/zstdlib.rc)
|
SET(PlatformDependResources ${MSVC_RESOURCE_DIR}/zstdlib.rc)
|
||||||
ENDIF (MSVC)
|
ENDIF (MSVC)
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# produced by make
|
||||||
|
zstd
|
||||||
|
zstd-frugal
|
||||||
@@ -45,29 +45,13 @@ INCLUDE_DIRECTORIES(${PROGRAMS_DIR} ${LIBRARY_DIR} ${LIBRARY_DIR}/common ${LIBRA
|
|||||||
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} ${LIBRARY_DIR}/legacy)
|
INCLUDE_DIRECTORIES(${PROGRAMS_LEGACY_DIR} ${LIBRARY_DIR}/legacy)
|
||||||
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}/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)
|
||||||
TARGET_LINK_LIBRARIES(zstd libzstd_static)
|
TARGET_LINK_LIBRARIES(zstd libzstd_static)
|
||||||
|
|
||||||
ADD_EXECUTABLE(fullbench ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/fullbench.c)
|
|
||||||
TARGET_LINK_LIBRARIES(fullbench libzstd_static)
|
|
||||||
|
|
||||||
ADD_EXECUTABLE(fuzzer ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/fuzzer.c)
|
|
||||||
TARGET_LINK_LIBRARIES(fuzzer libzstd_static)
|
|
||||||
|
|
||||||
IF (UNIX)
|
IF (UNIX)
|
||||||
ADD_EXECUTABLE(zstd-frugal ${PROGRAMS_DIR}/zstdcli.c ${PROGRAMS_DIR}/fileio.c)
|
ADD_EXECUTABLE(zstd-frugal ${PROGRAMS_DIR}/zstdcli.c ${PROGRAMS_DIR}/fileio.c)
|
||||||
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}/zbufftest.c)
|
|
||||||
TARGET_LINK_LIBRARIES(zbufftest libzstd_static)
|
|
||||||
|
|
||||||
ADD_EXECUTABLE(paramgrill ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/paramgrill.c)
|
|
||||||
TARGET_LINK_LIBRARIES(paramgrill libzstd_static m) #m is math library
|
|
||||||
|
|
||||||
ADD_EXECUTABLE(datagen ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/datagencli.c)
|
|
||||||
TARGET_LINK_LIBRARIES(datagen libzstd_static)
|
|
||||||
ENDIF (UNIX)
|
ENDIF (UNIX)
|
||||||
@@ -4,5 +4,4 @@ fullbench
|
|||||||
fuzzer
|
fuzzer
|
||||||
paramgrill
|
paramgrill
|
||||||
zbufftest
|
zbufftest
|
||||||
zstd
|
|
||||||
zstd-frugal
|
|
||||||
@@ -2,19 +2,19 @@
|
|||||||
# zstd - Makefile
|
# zstd - Makefile
|
||||||
# Copyright (C) Yann Collet 2014-2016
|
# Copyright (C) Yann Collet 2014-2016
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# BSD license
|
# BSD license
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# Redistribution and use in source and binary forms, with or without modification,
|
||||||
# are permitted provided that the following conditions are met:
|
# are permitted provided that the following conditions are met:
|
||||||
#
|
#
|
||||||
# * Redistributions of source code must retain the above copyright notice, this
|
# * Redistributions of source code must retain the above copyright notice, this
|
||||||
# list of conditions and the following disclaimer.
|
# list of conditions and the following disclaimer.
|
||||||
#
|
#
|
||||||
# * Redistributions in binary form must reproduce the above copyright notice, this
|
# * Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
# list of conditions and the following disclaimer in the documentation and/or
|
# list of conditions and the following disclaimer in the documentation and/or
|
||||||
# other materials provided with the distribution.
|
# other materials provided with the distribution.
|
||||||
#
|
#
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
# 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
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
@@ -25,35 +25,37 @@
|
|||||||
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
# 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
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#
|
#
|
||||||
# You can contact the author at :
|
# You can contact the author at :
|
||||||
# - zstd source repository : https://github.com/Cyan4973/zstd
|
# - zstd homepage : http://www.zstd.net/
|
||||||
# - Public forum : https://groups.google.com/forum/#!forum/lz4c
|
|
||||||
# ################################################################
|
# ################################################################
|
||||||
|
|
||||||
PROJECT(zstd)
|
PROJECT(tests)
|
||||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.7)
|
|
||||||
|
|
||||||
OPTION(ZSTD_LEGACY_SUPPORT "LEGACY SUPPORT" OFF)
|
SET(CMAKE_INCLUDE_CURRENT_DIR TRUE)
|
||||||
|
|
||||||
IF (ZSTD_LEGACY_SUPPORT)
|
# Define project root directory
|
||||||
MESSAGE(STATUS "ZSTD_LEGACY_SUPPORT defined!")
|
SET(ROOT_DIR ../../..)
|
||||||
ADD_DEFINITIONS(-DZSTD_LEGACY_SUPPORT=1)
|
|
||||||
ELSE (ZSTD_LEGACY_SUPPORT)
|
|
||||||
MESSAGE(STATUS "ZSTD_LEGACY_SUPPORT not defined!")
|
|
||||||
ADD_DEFINITIONS(-DZSTD_LEGACY_SUPPORT=0)
|
|
||||||
ENDIF (ZSTD_LEGACY_SUPPORT)
|
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(lib)
|
# Define programs directory, where sources and header files are located
|
||||||
ADD_SUBDIRECTORY(programs)
|
SET(LIBRARY_DIR ${ROOT_DIR}/lib)
|
||||||
|
SET(PROGRAMS_DIR ${ROOT_DIR}/programs)
|
||||||
|
SET(TESTS_DIR ${ROOT_DIR}/tests)
|
||||||
|
INCLUDE_DIRECTORIES(${TESTS_DIR} ${PROGRAMS_DIR} ${LIBRARY_DIR} ${LIBRARY_DIR}/common ${LIBRARY_DIR}/dictBuilder)
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
ADD_EXECUTABLE(fullbench ${PROGRAMS_DIR}/datagen.c ${TESTS_DIR}/fullbench.c)
|
||||||
# Add extra compilation flags
|
TARGET_LINK_LIBRARIES(fullbench libzstd_static)
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
INCLUDE(CMakeModules/AddExtraCompilationFlags.cmake)
|
|
||||||
ADD_EXTRA_COMPILATION_FLAGS()
|
|
||||||
|
|
||||||
ADD_CUSTOM_TARGET(clean-all
|
ADD_EXECUTABLE(fuzzer ${PROGRAMS_DIR}/datagen.c ${TESTS_DIR}/fuzzer.c)
|
||||||
COMMAND ${CMAKE_BUILD_TOOL} clean
|
TARGET_LINK_LIBRARIES(fuzzer libzstd_static)
|
||||||
COMMAND rm -rf ${CMAKE_BINARY_DIR}/
|
|
||||||
)
|
IF (UNIX)
|
||||||
|
ADD_EXECUTABLE(zbufftest ${PROGRAMS_DIR}/datagen.c ${TESTS_DIR}/zbufftest.c)
|
||||||
|
TARGET_LINK_LIBRARIES(zbufftest libzstd_static)
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(paramgrill ${PROGRAMS_DIR}/datagen.c ${TESTS_DIR}/paramgrill.c)
|
||||||
|
TARGET_LINK_LIBRARIES(paramgrill libzstd_static m) #m is math library
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(datagen ${PROGRAMS_DIR}/datagen.c ${TESTS_DIR}/datagencli.c)
|
||||||
|
TARGET_LINK_LIBRARIES(datagen libzstd_static)
|
||||||
|
ENDIF (UNIX)
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# compilation result
|
||||||
|
pzstd
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <cassert>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace pzstd {
|
||||||
|
|
||||||
|
// Coordinates graceful shutdown of the pzstd pipeline
|
||||||
|
class ErrorHolder {
|
||||||
|
std::atomic<bool> error_;
|
||||||
|
std::string message_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ErrorHolder() : error_(false) {}
|
||||||
|
|
||||||
|
bool hasError() noexcept {
|
||||||
|
return error_.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setError(std::string message) noexcept {
|
||||||
|
// Given multiple possibly concurrent calls, exactly one will ever succeed.
|
||||||
|
bool expected = false;
|
||||||
|
if (error_.compare_exchange_strong(expected, true)) {
|
||||||
|
message_ = std::move(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check(bool predicate, std::string message) noexcept {
|
||||||
|
if (!predicate) {
|
||||||
|
setError(std::move(message));
|
||||||
|
}
|
||||||
|
return !hasError();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getError() noexcept {
|
||||||
|
error_.store(false);
|
||||||
|
return std::move(message_);
|
||||||
|
}
|
||||||
|
|
||||||
|
~ErrorHolder() {
|
||||||
|
assert(!hasError());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
# ##########################################################################
|
||||||
|
# Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This source code is licensed under the BSD-style license found in the
|
||||||
|
# LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
# of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
# ##########################################################################
|
||||||
|
|
||||||
|
ZSTDDIR = ../../lib
|
||||||
|
PROGDIR = ../../programs
|
||||||
|
|
||||||
|
CPPFLAGS = -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(PROGDIR) -I.
|
||||||
|
CXXFLAGS ?= -O3
|
||||||
|
CXXFLAGS += -std=c++11
|
||||||
|
CXXFLAGS += $(MOREFLAGS)
|
||||||
|
FLAGS = $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS)
|
||||||
|
|
||||||
|
|
||||||
|
ZSTDCOMMON_FILES := $(ZSTDDIR)/common/*.c
|
||||||
|
ZSTDCOMP_FILES := $(ZSTDDIR)/compress/zstd_compress.c $(ZSTDDIR)/compress/fse_compress.c $(ZSTDDIR)/compress/huf_compress.c
|
||||||
|
ZSTDDECOMP_FILES := $(ZSTDDIR)/decompress/huf_decompress.c
|
||||||
|
ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES)
|
||||||
|
|
||||||
|
|
||||||
|
# Define *.exe as extension for Windows systems
|
||||||
|
ifneq (,$(filter Windows%,$(OS)))
|
||||||
|
EXT =.exe
|
||||||
|
else
|
||||||
|
EXT =
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: default all test clean test32 googletest googletest32
|
||||||
|
|
||||||
|
default: pzstd
|
||||||
|
|
||||||
|
all: pzstd
|
||||||
|
|
||||||
|
|
||||||
|
libzstd.a: $(ZSTD_FILES)
|
||||||
|
$(MAKE) -C $(ZSTDDIR) libzstd
|
||||||
|
@cp $(ZSTDDIR)/libzstd.a .
|
||||||
|
|
||||||
|
Pzstd.o: Pzstd.h Pzstd.cpp ErrorHolder.h utils/*.h
|
||||||
|
$(CXX) $(FLAGS) -c Pzstd.cpp -o $@
|
||||||
|
|
||||||
|
SkippableFrame.o: SkippableFrame.h SkippableFrame.cpp utils/*.h
|
||||||
|
$(CXX) $(FLAGS) -c SkippableFrame.cpp -o $@
|
||||||
|
|
||||||
|
Options.o: Options.h Options.cpp
|
||||||
|
$(CXX) $(FLAGS) -c Options.cpp -o $@
|
||||||
|
|
||||||
|
main.o: main.cpp *.h utils/*.h
|
||||||
|
$(CXX) $(FLAGS) -c main.cpp -o $@
|
||||||
|
|
||||||
|
pzstd: Pzstd.o SkippableFrame.o Options.o main.o libzstd.a
|
||||||
|
$(CXX) $(FLAGS) $^ -o $@$(EXT) -lpthread
|
||||||
|
|
||||||
|
libzstd32.a: $(ZSTD_FILES)
|
||||||
|
$(MAKE) -C $(ZSTDDIR) libzstd MOREFLAGS="-m32"
|
||||||
|
@cp $(ZSTDDIR)/libzstd.a libzstd32.a
|
||||||
|
|
||||||
|
Pzstd32.o: Pzstd.h Pzstd.cpp ErrorHolder.h utils/*.h
|
||||||
|
$(CXX) -m32 $(FLAGS) -c Pzstd.cpp -o $@
|
||||||
|
|
||||||
|
SkippableFrame32.o: SkippableFrame.h SkippableFrame.cpp utils/*.h
|
||||||
|
$(CXX) -m32 $(FLAGS) -c SkippableFrame.cpp -o $@
|
||||||
|
|
||||||
|
Options32.o: Options.h Options.cpp
|
||||||
|
$(CXX) -m32 $(FLAGS) -c Options.cpp -o $@
|
||||||
|
|
||||||
|
main32.o: main.cpp *.h utils/*.h
|
||||||
|
$(CXX) -m32 $(FLAGS) -c main.cpp -o $@
|
||||||
|
|
||||||
|
pzstd32: Pzstd32.o SkippableFrame32.o Options32.o main32.o libzstd32.a
|
||||||
|
$(CXX) -m32 $(FLAGS) $^ -o $@$(EXT) -lpthread
|
||||||
|
|
||||||
|
googletest:
|
||||||
|
@$(RM) -rf googletest
|
||||||
|
@git clone https://github.com/google/googletest
|
||||||
|
@mkdir -p googletest/build
|
||||||
|
@cd googletest/build && cmake .. && make
|
||||||
|
|
||||||
|
googletest32:
|
||||||
|
@$(RM) -rf googletest
|
||||||
|
@git clone https://github.com/google/googletest
|
||||||
|
@mkdir -p googletest/build
|
||||||
|
@cd googletest/build && cmake .. -DCMAKE_CXX_FLAGS=-m32 && make
|
||||||
|
|
||||||
|
googletest-mingw64:
|
||||||
|
$(RM) -rf googletest
|
||||||
|
git clone https://github.com/google/googletest
|
||||||
|
mkdir -p googletest/build
|
||||||
|
cd googletest/build && cmake -G "MSYS Makefiles" .. && $(MAKE)
|
||||||
|
|
||||||
|
test:
|
||||||
|
$(MAKE) libzstd.a
|
||||||
|
$(MAKE) pzstd MOREFLAGS="-Wall -Wextra -pedantic -Werror"
|
||||||
|
$(MAKE) -C utils/test clean
|
||||||
|
$(MAKE) -C utils/test test MOREFLAGS="-Wall -Wextra -pedantic -Werror"
|
||||||
|
$(MAKE) -C test clean
|
||||||
|
$(MAKE) -C test test MOREFLAGS="-Wall -Wextra -pedantic -Werror"
|
||||||
|
|
||||||
|
test32:
|
||||||
|
$(MAKE) libzstd.a MOREFLAGS="-m32"
|
||||||
|
$(MAKE) pzstd MOREFLAGS="-m32 -Wall -Wextra -pedantic -Werror"
|
||||||
|
$(MAKE) -C utils/test clean
|
||||||
|
$(MAKE) -C utils/test test MOREFLAGS="-m32 -Wall -Wextra -pedantic -Werror"
|
||||||
|
$(MAKE) -C test clean
|
||||||
|
$(MAKE) -C test test MOREFLAGS="-m32 -Wall -Wextra -pedantic -Werror"
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(MAKE) -C $(ZSTDDIR) clean
|
||||||
|
$(MAKE) -C utils/test clean
|
||||||
|
$(MAKE) -C test clean
|
||||||
|
@$(RM) -rf libzstd.a *.o pzstd$(EXT) pzstd32$(EXT)
|
||||||
|
@echo Cleaning completed
|
||||||
@@ -0,0 +1,426 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#include "Options.h"
|
||||||
|
#include "utils/ScopeGuard.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iterator>
|
||||||
|
#include <thread>
|
||||||
|
#include <util.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || \
|
||||||
|
defined(__CYGWIN__)
|
||||||
|
#include <io.h> /* _isatty */
|
||||||
|
#define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream))
|
||||||
|
#else
|
||||||
|
#if defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
|
||||||
|
defined(_POSIX_SOURCE) || \
|
||||||
|
(defined(__APPLE__) && \
|
||||||
|
defined( \
|
||||||
|
__MACH__)) /* https://sourceforge.net/p/predef/wiki/OperatingSystems/ \
|
||||||
|
*/
|
||||||
|
#include <unistd.h> /* isatty */
|
||||||
|
#define IS_CONSOLE(stdStream) isatty(fileno(stdStream))
|
||||||
|
#else
|
||||||
|
#define IS_CONSOLE(stdStream) 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace pzstd {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
unsigned defaultNumThreads() {
|
||||||
|
#ifdef PZSTD_NUM_THREADS
|
||||||
|
return PZSTD_NUM_THREADS;
|
||||||
|
#else
|
||||||
|
return std::thread::hardware_concurrency();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned parseUnsigned(const char **arg) {
|
||||||
|
unsigned result = 0;
|
||||||
|
while (**arg >= '0' && **arg <= '9') {
|
||||||
|
result *= 10;
|
||||||
|
result += **arg - '0';
|
||||||
|
++(*arg);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *getArgument(const char *options, const char **argv, int &i,
|
||||||
|
int argc) {
|
||||||
|
if (options[1] != 0) {
|
||||||
|
return options + 1;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
if (i == argc) {
|
||||||
|
std::fprintf(stderr, "Option -%c requires an argument, but none provided\n",
|
||||||
|
*options);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return argv[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string kZstdExtension = ".zst";
|
||||||
|
constexpr char kStdIn[] = "-";
|
||||||
|
constexpr char kStdOut[] = "-";
|
||||||
|
constexpr unsigned kDefaultCompressionLevel = 3;
|
||||||
|
constexpr unsigned kMaxNonUltraCompressionLevel = 19;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
const char nullOutput[] = "nul";
|
||||||
|
#else
|
||||||
|
const char nullOutput[] = "/dev/null";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void notSupported(const char *option) {
|
||||||
|
std::fprintf(stderr, "Operation not supported: %s\n", option);
|
||||||
|
}
|
||||||
|
|
||||||
|
void usage() {
|
||||||
|
std::fprintf(stderr, "Usage:\n");
|
||||||
|
std::fprintf(stderr, " pzstd [args] [FILE(s)]\n");
|
||||||
|
std::fprintf(stderr, "Parallel ZSTD options:\n");
|
||||||
|
std::fprintf(stderr, " -p, --processes # : number of threads to use for (de)compression (default:%d)\n", defaultNumThreads());
|
||||||
|
|
||||||
|
std::fprintf(stderr, "ZSTD options:\n");
|
||||||
|
std::fprintf(stderr, " -# : # compression level (1-%d, default:%d)\n", kMaxNonUltraCompressionLevel, kDefaultCompressionLevel);
|
||||||
|
std::fprintf(stderr, " -d, --decompress : decompression\n");
|
||||||
|
std::fprintf(stderr, " -o file : result stored into `file` (only if 1 input file)\n");
|
||||||
|
std::fprintf(stderr, " -f, --force : overwrite output without prompting\n");
|
||||||
|
std::fprintf(stderr, " --rm : remove source file(s) after successful (de)compression\n");
|
||||||
|
std::fprintf(stderr, " -k, --keep : preserve source file(s) (default)\n");
|
||||||
|
std::fprintf(stderr, " -h, --help : display help and exit\n");
|
||||||
|
std::fprintf(stderr, " -V, --version : display version number and exit\n");
|
||||||
|
std::fprintf(stderr, " -v, --verbose : verbose mode; specify multiple times to increase log level (default:2)\n");
|
||||||
|
std::fprintf(stderr, " -q, --quiet : suppress warnings; specify twice to suppress errors too\n");
|
||||||
|
std::fprintf(stderr, " -c, --stdout : force write to standard output, even if it is the console\n");
|
||||||
|
#ifdef UTIL_HAS_CREATEFILELIST
|
||||||
|
std::fprintf(stderr, " -r : operate recursively on directories\n");
|
||||||
|
#endif
|
||||||
|
std::fprintf(stderr, " --ultra : enable levels beyond %i, up to %i (requires more memory)\n", kMaxNonUltraCompressionLevel, ZSTD_maxCLevel());
|
||||||
|
std::fprintf(stderr, " -C, --check : integrity check (default)\n");
|
||||||
|
std::fprintf(stderr, " --no-check : no integrity check\n");
|
||||||
|
std::fprintf(stderr, " -t, --test : test compressed file integrity\n");
|
||||||
|
std::fprintf(stderr, " -- : all arguments after \"--\" are treated as files\n");
|
||||||
|
}
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
Options::Options()
|
||||||
|
: numThreads(defaultNumThreads()), maxWindowLog(23),
|
||||||
|
compressionLevel(kDefaultCompressionLevel), decompress(false),
|
||||||
|
overwrite(false), keepSource(true), writeMode(WriteMode::Auto),
|
||||||
|
checksum(true), verbosity(2) {}
|
||||||
|
|
||||||
|
Options::Status Options::parse(int argc, const char **argv) {
|
||||||
|
bool test = false;
|
||||||
|
bool recursive = false;
|
||||||
|
bool ultra = false;
|
||||||
|
bool forceStdout = false;
|
||||||
|
// Local copy of input files, which are pointers into argv.
|
||||||
|
std::vector<const char *> localInputFiles;
|
||||||
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
const char *arg = argv[i];
|
||||||
|
// Protect against empty arguments
|
||||||
|
if (arg[0] == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Everything after "--" is an input file
|
||||||
|
if (!std::strcmp(arg, "--")) {
|
||||||
|
++i;
|
||||||
|
std::copy(argv + i, argv + argc, std::back_inserter(localInputFiles));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Long arguments that don't have a short option
|
||||||
|
{
|
||||||
|
bool isLongOption = true;
|
||||||
|
if (!std::strcmp(arg, "--rm")) {
|
||||||
|
keepSource = false;
|
||||||
|
} else if (!std::strcmp(arg, "--ultra")) {
|
||||||
|
ultra = true;
|
||||||
|
maxWindowLog = 0;
|
||||||
|
} else if (!std::strcmp(arg, "--no-check")) {
|
||||||
|
checksum = false;
|
||||||
|
} else if (!std::strcmp(arg, "--sparse")) {
|
||||||
|
writeMode = WriteMode::Sparse;
|
||||||
|
notSupported("Sparse mode");
|
||||||
|
return Status::Failure;
|
||||||
|
} else if (!std::strcmp(arg, "--no-sparse")) {
|
||||||
|
writeMode = WriteMode::Regular;
|
||||||
|
notSupported("Sparse mode");
|
||||||
|
return Status::Failure;
|
||||||
|
} else if (!std::strcmp(arg, "--dictID")) {
|
||||||
|
notSupported(arg);
|
||||||
|
return Status::Failure;
|
||||||
|
} else if (!std::strcmp(arg, "--no-dictID")) {
|
||||||
|
notSupported(arg);
|
||||||
|
return Status::Failure;
|
||||||
|
} else {
|
||||||
|
isLongOption = false;
|
||||||
|
}
|
||||||
|
if (isLongOption) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Arguments with a short option simply set their short option.
|
||||||
|
const char *options = nullptr;
|
||||||
|
if (!std::strcmp(arg, "--processes")) {
|
||||||
|
options = "p";
|
||||||
|
} else if (!std::strcmp(arg, "--version")) {
|
||||||
|
options = "V";
|
||||||
|
} else if (!std::strcmp(arg, "--help")) {
|
||||||
|
options = "h";
|
||||||
|
} else if (!std::strcmp(arg, "--decompress")) {
|
||||||
|
options = "d";
|
||||||
|
} else if (!std::strcmp(arg, "--force")) {
|
||||||
|
options = "f";
|
||||||
|
} else if (!std::strcmp(arg, "--stdout")) {
|
||||||
|
options = "c";
|
||||||
|
} else if (!std::strcmp(arg, "--keep")) {
|
||||||
|
options = "k";
|
||||||
|
} else if (!std::strcmp(arg, "--verbose")) {
|
||||||
|
options = "v";
|
||||||
|
} else if (!std::strcmp(arg, "--quiet")) {
|
||||||
|
options = "q";
|
||||||
|
} else if (!std::strcmp(arg, "--check")) {
|
||||||
|
options = "C";
|
||||||
|
} else if (!std::strcmp(arg, "--test")) {
|
||||||
|
options = "t";
|
||||||
|
} else if (arg[0] == '-' && arg[1] != 0) {
|
||||||
|
options = arg + 1;
|
||||||
|
} else {
|
||||||
|
localInputFiles.emplace_back(arg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
assert(options != nullptr);
|
||||||
|
|
||||||
|
bool finished = false;
|
||||||
|
while (!finished && *options != 0) {
|
||||||
|
// Parse the compression level
|
||||||
|
if (*options >= '0' && *options <= '9') {
|
||||||
|
compressionLevel = parseUnsigned(&options);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*options) {
|
||||||
|
case 'h':
|
||||||
|
case 'H':
|
||||||
|
usage();
|
||||||
|
return Status::Message;
|
||||||
|
case 'V':
|
||||||
|
std::fprintf(stderr, "PZSTD version: %s.\n", ZSTD_VERSION_STRING);
|
||||||
|
return Status::Message;
|
||||||
|
case 'p': {
|
||||||
|
finished = true;
|
||||||
|
const char *optionArgument = getArgument(options, argv, i, argc);
|
||||||
|
if (optionArgument == nullptr) {
|
||||||
|
return Status::Failure;
|
||||||
|
}
|
||||||
|
if (*optionArgument < '0' || *optionArgument > '9') {
|
||||||
|
std::fprintf(stderr, "Option -p expects a number, but %s provided\n",
|
||||||
|
optionArgument);
|
||||||
|
return Status::Failure;
|
||||||
|
}
|
||||||
|
numThreads = parseUnsigned(&optionArgument);
|
||||||
|
if (*optionArgument != 0) {
|
||||||
|
std::fprintf(stderr,
|
||||||
|
"Option -p expects a number, but %u%s provided\n",
|
||||||
|
numThreads, optionArgument);
|
||||||
|
return Status::Failure;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'o': {
|
||||||
|
finished = true;
|
||||||
|
const char *optionArgument = getArgument(options, argv, i, argc);
|
||||||
|
if (optionArgument == nullptr) {
|
||||||
|
return Status::Failure;
|
||||||
|
}
|
||||||
|
outputFile = optionArgument;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'C':
|
||||||
|
checksum = true;
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
keepSource = true;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
decompress = true;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
overwrite = true;
|
||||||
|
forceStdout = true;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
test = true;
|
||||||
|
decompress = true;
|
||||||
|
break;
|
||||||
|
#ifdef UTIL_HAS_CREATEFILELIST
|
||||||
|
case 'r':
|
||||||
|
recursive = true;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case 'c':
|
||||||
|
outputFile = kStdOut;
|
||||||
|
forceStdout = true;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
++verbosity;
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
--verbosity;
|
||||||
|
// Ignore them for now
|
||||||
|
break;
|
||||||
|
// Unsupported options from Zstd
|
||||||
|
case 'D':
|
||||||
|
case 's':
|
||||||
|
notSupported("Zstd dictionaries.");
|
||||||
|
return Status::Failure;
|
||||||
|
case 'b':
|
||||||
|
case 'e':
|
||||||
|
case 'i':
|
||||||
|
case 'B':
|
||||||
|
notSupported("Zstd benchmarking options.");
|
||||||
|
return Status::Failure;
|
||||||
|
default:
|
||||||
|
std::fprintf(stderr, "Invalid argument: %s\n", arg);
|
||||||
|
return Status::Failure;
|
||||||
|
}
|
||||||
|
if (!finished) {
|
||||||
|
++options;
|
||||||
|
}
|
||||||
|
} // while (*options != 0);
|
||||||
|
} // for (int i = 1; i < argc; ++i);
|
||||||
|
|
||||||
|
// Input file defaults to standard input if not provided.
|
||||||
|
if (localInputFiles.empty()) {
|
||||||
|
localInputFiles.emplace_back(kStdIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check validity of input files
|
||||||
|
if (localInputFiles.size() > 1) {
|
||||||
|
const auto it = std::find(localInputFiles.begin(), localInputFiles.end(),
|
||||||
|
std::string{kStdIn});
|
||||||
|
if (it != localInputFiles.end()) {
|
||||||
|
std::fprintf(
|
||||||
|
stderr,
|
||||||
|
"Cannot specify standard input when handling multiple files\n");
|
||||||
|
return Status::Failure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (localInputFiles.size() > 1 || recursive) {
|
||||||
|
if (!outputFile.empty() && outputFile != nullOutput) {
|
||||||
|
std::fprintf(
|
||||||
|
stderr,
|
||||||
|
"Cannot specify an output file when handling multiple inputs\n");
|
||||||
|
return Status::Failure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translate input files/directories into files to (de)compress
|
||||||
|
if (recursive) {
|
||||||
|
char *scratchBuffer = nullptr;
|
||||||
|
unsigned numFiles = 0;
|
||||||
|
const char **files =
|
||||||
|
UTIL_createFileList(localInputFiles.data(), localInputFiles.size(),
|
||||||
|
&scratchBuffer, &numFiles);
|
||||||
|
if (files == nullptr) {
|
||||||
|
std::fprintf(stderr, "Error traversing directories\n");
|
||||||
|
return Status::Failure;
|
||||||
|
}
|
||||||
|
auto guard =
|
||||||
|
makeScopeGuard([&] { UTIL_freeFileList(files, scratchBuffer); });
|
||||||
|
if (numFiles == 0) {
|
||||||
|
std::fprintf(stderr, "No files found\n");
|
||||||
|
return Status::Failure;
|
||||||
|
}
|
||||||
|
inputFiles.resize(numFiles);
|
||||||
|
std::copy(files, files + numFiles, inputFiles.begin());
|
||||||
|
} else {
|
||||||
|
inputFiles.resize(localInputFiles.size());
|
||||||
|
std::copy(localInputFiles.begin(), localInputFiles.end(),
|
||||||
|
inputFiles.begin());
|
||||||
|
}
|
||||||
|
localInputFiles.clear();
|
||||||
|
assert(!inputFiles.empty());
|
||||||
|
|
||||||
|
// If reading from standard input, default to standard output
|
||||||
|
if (inputFiles[0] == kStdIn && outputFile.empty()) {
|
||||||
|
assert(inputFiles.size() == 1);
|
||||||
|
outputFile = "-";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inputFiles[0] == kStdIn && IS_CONSOLE(stdin)) {
|
||||||
|
assert(inputFiles.size() == 1);
|
||||||
|
std::fprintf(stderr, "Cannot read input from interactive console\n");
|
||||||
|
return Status::Failure;
|
||||||
|
}
|
||||||
|
if (outputFile == "-" && IS_CONSOLE(stdout) && !(forceStdout && decompress)) {
|
||||||
|
std::fprintf(stderr, "Will not write to console stdout unless -c or -f is "
|
||||||
|
"specified and decompressing\n");
|
||||||
|
return Status::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check compression level
|
||||||
|
{
|
||||||
|
unsigned maxCLevel =
|
||||||
|
ultra ? ZSTD_maxCLevel() : kMaxNonUltraCompressionLevel;
|
||||||
|
if (compressionLevel > maxCLevel || compressionLevel == 0) {
|
||||||
|
std::fprintf(stderr, "Invalid compression level %u.\n", compressionLevel);
|
||||||
|
return Status::Failure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that numThreads is set
|
||||||
|
if (numThreads == 0) {
|
||||||
|
std::fprintf(stderr, "Invalid arguments: # of threads not specified "
|
||||||
|
"and unable to determine hardware concurrency.\n");
|
||||||
|
return Status::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modify verbosity
|
||||||
|
// If we are piping input and output, turn off interaction
|
||||||
|
if (inputFiles[0] == kStdIn && outputFile == kStdOut && verbosity == 2) {
|
||||||
|
verbosity = 1;
|
||||||
|
}
|
||||||
|
// If we are in multi-file mode, turn off interaction
|
||||||
|
if (inputFiles.size() > 1 && verbosity == 2) {
|
||||||
|
verbosity = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set options for test mode
|
||||||
|
if (test) {
|
||||||
|
outputFile = nullOutput;
|
||||||
|
keepSource = true;
|
||||||
|
}
|
||||||
|
return Status::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Options::getOutputFile(const std::string &inputFile) const {
|
||||||
|
if (!outputFile.empty()) {
|
||||||
|
return outputFile;
|
||||||
|
}
|
||||||
|
// Attempt to add/remove zstd extension from the input file
|
||||||
|
if (decompress) {
|
||||||
|
int stemSize = inputFile.size() - kZstdExtension.size();
|
||||||
|
if (stemSize > 0 && inputFile.substr(stemSize) == kZstdExtension) {
|
||||||
|
return inputFile.substr(0, stemSize);
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return inputFile + kZstdExtension;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define ZSTD_STATIC_LINKING_ONLY
|
||||||
|
#include "zstd.h"
|
||||||
|
#undef ZSTD_STATIC_LINKING_ONLY
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace pzstd {
|
||||||
|
|
||||||
|
struct Options {
|
||||||
|
enum class WriteMode { Regular, Auto, Sparse };
|
||||||
|
|
||||||
|
unsigned numThreads;
|
||||||
|
unsigned maxWindowLog;
|
||||||
|
unsigned compressionLevel;
|
||||||
|
bool decompress;
|
||||||
|
std::vector<std::string> inputFiles;
|
||||||
|
std::string outputFile;
|
||||||
|
bool overwrite;
|
||||||
|
bool keepSource;
|
||||||
|
WriteMode writeMode;
|
||||||
|
bool checksum;
|
||||||
|
int verbosity;
|
||||||
|
|
||||||
|
enum class Status {
|
||||||
|
Success, // Successfully parsed options
|
||||||
|
Failure, // Failure to parse options
|
||||||
|
Message // Options specified to print a message (e.g. "-h")
|
||||||
|
};
|
||||||
|
|
||||||
|
Options();
|
||||||
|
Options(unsigned numThreads, unsigned maxWindowLog, unsigned compressionLevel,
|
||||||
|
bool decompress, std::vector<std::string> inputFiles,
|
||||||
|
std::string outputFile, bool overwrite, bool keepSource,
|
||||||
|
WriteMode writeMode, bool checksum, int verbosity)
|
||||||
|
: numThreads(numThreads), maxWindowLog(maxWindowLog),
|
||||||
|
compressionLevel(compressionLevel), decompress(decompress),
|
||||||
|
inputFiles(std::move(inputFiles)), outputFile(std::move(outputFile)),
|
||||||
|
overwrite(overwrite), keepSource(keepSource), writeMode(writeMode),
|
||||||
|
checksum(checksum), verbosity(verbosity) {}
|
||||||
|
|
||||||
|
Status parse(int argc, const char **argv);
|
||||||
|
|
||||||
|
ZSTD_parameters determineParameters() const {
|
||||||
|
ZSTD_parameters params = ZSTD_getParams(compressionLevel, 0, 0);
|
||||||
|
params.fParams.contentSizeFlag = 1;
|
||||||
|
params.fParams.checksumFlag = checksum;
|
||||||
|
if (maxWindowLog != 0 && params.cParams.windowLog > maxWindowLog) {
|
||||||
|
params.cParams.windowLog = maxWindowLog;
|
||||||
|
params.cParams = ZSTD_adjustCParams(params.cParams, 0, 0);
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getOutputFile(const std::string &inputFile) const;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,641 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#include "Pzstd.h"
|
||||||
|
#include "SkippableFrame.h"
|
||||||
|
#include "utils/FileSystem.h"
|
||||||
|
#include "utils/Range.h"
|
||||||
|
#include "utils/ScopeGuard.h"
|
||||||
|
#include "utils/ThreadPool.h"
|
||||||
|
#include "utils/WorkQueue.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
# include <fcntl.h> /* _O_BINARY */
|
||||||
|
# include <io.h> /* _setmode, _isatty */
|
||||||
|
# define SET_BINARY_MODE(file) { if (_setmode(_fileno(file), _O_BINARY) == -1) perror("Cannot set _O_BINARY"); }
|
||||||
|
#else
|
||||||
|
# include <unistd.h> /* isatty */
|
||||||
|
# define SET_BINARY_MODE(file)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace pzstd {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
#ifdef _WIN32
|
||||||
|
const std::string nullOutput = "nul";
|
||||||
|
#else
|
||||||
|
const std::string nullOutput = "/dev/null";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
using std::size_t;
|
||||||
|
|
||||||
|
static std::uintmax_t fileSizeOrZero(const std::string &file) {
|
||||||
|
if (file == "-") {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
std::error_code ec;
|
||||||
|
auto size = file_size(file, ec);
|
||||||
|
if (ec) {
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::uint64_t handleOneInput(const Options &options,
|
||||||
|
const std::string &inputFile,
|
||||||
|
FILE* inputFd,
|
||||||
|
const std::string &outputFile,
|
||||||
|
FILE* outputFd,
|
||||||
|
ErrorHolder &errorHolder) {
|
||||||
|
auto inputSize = fileSizeOrZero(inputFile);
|
||||||
|
// WorkQueue outlives ThreadPool so in the case of error we are certain
|
||||||
|
// we don't accidently try to call push() on it after it is destroyed.
|
||||||
|
WorkQueue<std::shared_ptr<BufferWorkQueue>> outs{options.numThreads + 1};
|
||||||
|
std::uint64_t bytesRead;
|
||||||
|
std::uint64_t bytesWritten;
|
||||||
|
{
|
||||||
|
// Initialize the thread pool with numThreads + 1
|
||||||
|
// We add one because the read thread spends most of its time waiting.
|
||||||
|
// This also sets the minimum number of threads to 2, so the algorithm
|
||||||
|
// doesn't deadlock.
|
||||||
|
ThreadPool executor(options.numThreads + 1);
|
||||||
|
if (!options.decompress) {
|
||||||
|
// Add a job that reads the input and starts all the compression jobs
|
||||||
|
executor.add(
|
||||||
|
[&errorHolder, &outs, &executor, inputFd, inputSize, &options,
|
||||||
|
&bytesRead] {
|
||||||
|
bytesRead = asyncCompressChunks(
|
||||||
|
errorHolder,
|
||||||
|
outs,
|
||||||
|
executor,
|
||||||
|
inputFd,
|
||||||
|
inputSize,
|
||||||
|
options.numThreads,
|
||||||
|
options.determineParameters());
|
||||||
|
});
|
||||||
|
// Start writing
|
||||||
|
bytesWritten = writeFile(errorHolder, outs, outputFd, options.decompress,
|
||||||
|
options.verbosity);
|
||||||
|
} else {
|
||||||
|
// Add a job that reads the input and starts all the decompression jobs
|
||||||
|
executor.add([&errorHolder, &outs, &executor, inputFd, &bytesRead] {
|
||||||
|
bytesRead = asyncDecompressFrames(errorHolder, outs, executor, inputFd);
|
||||||
|
});
|
||||||
|
// Start writing
|
||||||
|
bytesWritten = writeFile(errorHolder, outs, outputFd, options.decompress,
|
||||||
|
options.verbosity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (options.verbosity > 1 && !errorHolder.hasError()) {
|
||||||
|
std::string inputFileName = inputFile == "-" ? "stdin" : inputFile;
|
||||||
|
std::string outputFileName = outputFile == "-" ? "stdout" : outputFile;
|
||||||
|
if (!options.decompress) {
|
||||||
|
double ratio = static_cast<double>(bytesWritten) /
|
||||||
|
static_cast<double>(bytesRead + !bytesRead);
|
||||||
|
std::fprintf(stderr, "%-20s :%6.2f%% (%6llu => %6llu bytes, %s)\n",
|
||||||
|
inputFileName.c_str(), ratio * 100, bytesRead, bytesWritten,
|
||||||
|
outputFileName.c_str());
|
||||||
|
} else {
|
||||||
|
std::fprintf(stderr, "%-20s: %llu bytes \n",
|
||||||
|
inputFileName.c_str(),bytesWritten);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bytesWritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FILE *openInputFile(const std::string &inputFile,
|
||||||
|
ErrorHolder &errorHolder) {
|
||||||
|
if (inputFile == "-") {
|
||||||
|
SET_BINARY_MODE(stdin);
|
||||||
|
return stdin;
|
||||||
|
}
|
||||||
|
// Check if input file is a directory
|
||||||
|
{
|
||||||
|
std::error_code ec;
|
||||||
|
if (is_directory(inputFile, ec)) {
|
||||||
|
errorHolder.setError("Output file is a directory -- ignored");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto inputFd = std::fopen(inputFile.c_str(), "rb");
|
||||||
|
if (!errorHolder.check(inputFd != nullptr, "Failed to open input file")) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return inputFd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FILE *openOutputFile(const Options &options,
|
||||||
|
const std::string &outputFile,
|
||||||
|
ErrorHolder &errorHolder) {
|
||||||
|
if (outputFile == "-") {
|
||||||
|
SET_BINARY_MODE(stdout);
|
||||||
|
return stdout;
|
||||||
|
}
|
||||||
|
// Check if the output file exists and then open it
|
||||||
|
if (!options.overwrite && outputFile != nullOutput) {
|
||||||
|
auto outputFd = std::fopen(outputFile.c_str(), "rb");
|
||||||
|
if (outputFd != nullptr) {
|
||||||
|
std::fclose(outputFd);
|
||||||
|
if (options.verbosity <= 1) {
|
||||||
|
errorHolder.setError("Output file exists");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
std::fprintf(
|
||||||
|
stderr,
|
||||||
|
"pzstd: %s already exists; do you wish to overwrite (y/n) ? ",
|
||||||
|
outputFile.c_str());
|
||||||
|
int c = getchar();
|
||||||
|
if (c != 'y' && c != 'Y') {
|
||||||
|
errorHolder.setError("Not overwritten");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto outputFd = std::fopen(outputFile.c_str(), "wb");
|
||||||
|
if (!errorHolder.check(
|
||||||
|
outputFd != nullptr, "Failed to open output file")) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return outputFd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pzstdMain(const Options &options) {
|
||||||
|
int returnCode = 0;
|
||||||
|
for (const auto& input : options.inputFiles) {
|
||||||
|
// Setup the error holder
|
||||||
|
ErrorHolder errorHolder;
|
||||||
|
auto printErrorGuard = makeScopeGuard([&] {
|
||||||
|
if (errorHolder.hasError()) {
|
||||||
|
returnCode = 1;
|
||||||
|
if (options.verbosity > 0) {
|
||||||
|
std::fprintf(stderr, "pzstd: %s: %s.\n", input.c_str(),
|
||||||
|
errorHolder.getError().c_str());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Open the input file
|
||||||
|
auto inputFd = openInputFile(input, errorHolder);
|
||||||
|
if (inputFd == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto closeInputGuard = makeScopeGuard([&] { std::fclose(inputFd); });
|
||||||
|
// Open the output file
|
||||||
|
auto outputFile = options.getOutputFile(input);
|
||||||
|
if (!errorHolder.check(outputFile != "",
|
||||||
|
"Input file does not have extension .zst")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto outputFd = openOutputFile(options, outputFile, errorHolder);
|
||||||
|
if (outputFd == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto closeOutputGuard = makeScopeGuard([&] { std::fclose(outputFd); });
|
||||||
|
// (de)compress the file
|
||||||
|
handleOneInput(options, input, inputFd, outputFile, outputFd, errorHolder);
|
||||||
|
if (errorHolder.hasError()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Delete the input file if necessary
|
||||||
|
if (!options.keepSource) {
|
||||||
|
// Be sure that we are done and have written everything before we delete
|
||||||
|
if (!errorHolder.check(std::fclose(inputFd) == 0,
|
||||||
|
"Failed to close input file")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
closeInputGuard.dismiss();
|
||||||
|
if (!errorHolder.check(std::fclose(outputFd) == 0,
|
||||||
|
"Failed to close output file")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
closeOutputGuard.dismiss();
|
||||||
|
if (std::remove(input.c_str()) != 0) {
|
||||||
|
errorHolder.setError("Failed to remove input file");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Returns 1 if any of the files failed to (de)compress.
|
||||||
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a `ZSTD_inBuffer` that points to the data in `buffer`.
|
||||||
|
static ZSTD_inBuffer makeZstdInBuffer(const Buffer& buffer) {
|
||||||
|
return ZSTD_inBuffer{buffer.data(), buffer.size(), 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Advance `buffer` and `inBuffer` by the amount of data read, as indicated by
|
||||||
|
* `inBuffer.pos`.
|
||||||
|
*/
|
||||||
|
void advance(Buffer& buffer, ZSTD_inBuffer& inBuffer) {
|
||||||
|
auto pos = inBuffer.pos;
|
||||||
|
inBuffer.src = static_cast<const unsigned char*>(inBuffer.src) + pos;
|
||||||
|
inBuffer.size -= pos;
|
||||||
|
inBuffer.pos = 0;
|
||||||
|
return buffer.advance(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a `ZSTD_outBuffer` that points to the data in `buffer`.
|
||||||
|
static ZSTD_outBuffer makeZstdOutBuffer(Buffer& buffer) {
|
||||||
|
return ZSTD_outBuffer{buffer.data(), buffer.size(), 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split `buffer` and advance `outBuffer` by the amount of data written, as
|
||||||
|
* indicated by `outBuffer.pos`.
|
||||||
|
*/
|
||||||
|
Buffer split(Buffer& buffer, ZSTD_outBuffer& outBuffer) {
|
||||||
|
auto pos = outBuffer.pos;
|
||||||
|
outBuffer.dst = static_cast<unsigned char*>(outBuffer.dst) + pos;
|
||||||
|
outBuffer.size -= pos;
|
||||||
|
outBuffer.pos = 0;
|
||||||
|
return buffer.splitAt(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stream chunks of input from `in`, compress it, and stream it out to `out`.
|
||||||
|
*
|
||||||
|
* @param errorHolder Used to report errors and check if an error occured
|
||||||
|
* @param in Queue that we `pop()` input buffers from
|
||||||
|
* @param out Queue that we `push()` compressed output buffers to
|
||||||
|
* @param maxInputSize An upper bound on the size of the input
|
||||||
|
* @param parameters The zstd parameters to use for compression
|
||||||
|
*/
|
||||||
|
static void compress(
|
||||||
|
ErrorHolder& errorHolder,
|
||||||
|
std::shared_ptr<BufferWorkQueue> in,
|
||||||
|
std::shared_ptr<BufferWorkQueue> out,
|
||||||
|
size_t maxInputSize,
|
||||||
|
ZSTD_parameters parameters) {
|
||||||
|
auto guard = makeScopeGuard([&] { out->finish(); });
|
||||||
|
// Initialize the CCtx
|
||||||
|
std::unique_ptr<ZSTD_CStream, size_t (*)(ZSTD_CStream*)> ctx(
|
||||||
|
ZSTD_createCStream(), ZSTD_freeCStream);
|
||||||
|
if (!errorHolder.check(ctx != nullptr, "Failed to allocate ZSTD_CStream")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto err = ZSTD_initCStream_advanced(ctx.get(), nullptr, 0, parameters, 0);
|
||||||
|
if (!errorHolder.check(!ZSTD_isError(err), ZSTD_getErrorName(err))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate space for the result
|
||||||
|
auto outBuffer = Buffer(ZSTD_compressBound(maxInputSize));
|
||||||
|
auto zstdOutBuffer = makeZstdOutBuffer(outBuffer);
|
||||||
|
{
|
||||||
|
Buffer inBuffer;
|
||||||
|
// Read a buffer in from the input queue
|
||||||
|
while (in->pop(inBuffer) && !errorHolder.hasError()) {
|
||||||
|
auto zstdInBuffer = makeZstdInBuffer(inBuffer);
|
||||||
|
// Compress the whole buffer and send it to the output queue
|
||||||
|
while (!inBuffer.empty() && !errorHolder.hasError()) {
|
||||||
|
if (!errorHolder.check(
|
||||||
|
!outBuffer.empty(), "ZSTD_compressBound() was too small")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Compress
|
||||||
|
auto err =
|
||||||
|
ZSTD_compressStream(ctx.get(), &zstdOutBuffer, &zstdInBuffer);
|
||||||
|
if (!errorHolder.check(!ZSTD_isError(err), ZSTD_getErrorName(err))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Split the compressed data off outBuffer and pass to the output queue
|
||||||
|
out->push(split(outBuffer, zstdOutBuffer));
|
||||||
|
// Forget about the data we already compressed
|
||||||
|
advance(inBuffer, zstdInBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Write the epilog
|
||||||
|
size_t bytesLeft;
|
||||||
|
do {
|
||||||
|
if (!errorHolder.check(
|
||||||
|
!outBuffer.empty(), "ZSTD_compressBound() was too small")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bytesLeft = ZSTD_endStream(ctx.get(), &zstdOutBuffer);
|
||||||
|
if (!errorHolder.check(
|
||||||
|
!ZSTD_isError(bytesLeft), ZSTD_getErrorName(bytesLeft))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
out->push(split(outBuffer, zstdOutBuffer));
|
||||||
|
} while (bytesLeft != 0 && !errorHolder.hasError());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates how large each independently compressed frame should be.
|
||||||
|
*
|
||||||
|
* @param size The size of the source if known, 0 otherwise
|
||||||
|
* @param numThreads The number of threads available to run compression jobs on
|
||||||
|
* @param params The zstd parameters to be used for compression
|
||||||
|
*/
|
||||||
|
static size_t calculateStep(
|
||||||
|
std::uintmax_t size,
|
||||||
|
size_t numThreads,
|
||||||
|
const ZSTD_parameters ¶ms) {
|
||||||
|
size_t step = size_t{1} << (params.cParams.windowLog + 2);
|
||||||
|
// If file size is known, see if a smaller step will spread work more evenly
|
||||||
|
if (size != 0) {
|
||||||
|
const std::uintmax_t newStep = size / numThreads;
|
||||||
|
if (newStep != 0 && newStep <= std::numeric_limits<size_t>::max()) {
|
||||||
|
step = std::min(step, static_cast<size_t>(newStep));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return step;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
enum class FileStatus { Continue, Done, Error };
|
||||||
|
/// Determines the status of the file descriptor `fd`.
|
||||||
|
FileStatus fileStatus(FILE* fd) {
|
||||||
|
if (std::feof(fd)) {
|
||||||
|
return FileStatus::Done;
|
||||||
|
} else if (std::ferror(fd)) {
|
||||||
|
return FileStatus::Error;
|
||||||
|
}
|
||||||
|
return FileStatus::Continue;
|
||||||
|
}
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads `size` data in chunks of `chunkSize` and puts it into `queue`.
|
||||||
|
* Will read less if an error or EOF occurs.
|
||||||
|
* Returns the status of the file after all of the reads have occurred.
|
||||||
|
*/
|
||||||
|
static FileStatus
|
||||||
|
readData(BufferWorkQueue& queue, size_t chunkSize, size_t size, FILE* fd,
|
||||||
|
std::uint64_t *totalBytesRead) {
|
||||||
|
Buffer buffer(size);
|
||||||
|
while (!buffer.empty()) {
|
||||||
|
auto bytesRead =
|
||||||
|
std::fread(buffer.data(), 1, std::min(chunkSize, buffer.size()), fd);
|
||||||
|
*totalBytesRead += bytesRead;
|
||||||
|
queue.push(buffer.splitAt(bytesRead));
|
||||||
|
auto status = fileStatus(fd);
|
||||||
|
if (status != FileStatus::Continue) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FileStatus::Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint64_t asyncCompressChunks(
|
||||||
|
ErrorHolder& errorHolder,
|
||||||
|
WorkQueue<std::shared_ptr<BufferWorkQueue>>& chunks,
|
||||||
|
ThreadPool& executor,
|
||||||
|
FILE* fd,
|
||||||
|
std::uintmax_t size,
|
||||||
|
size_t numThreads,
|
||||||
|
ZSTD_parameters params) {
|
||||||
|
auto chunksGuard = makeScopeGuard([&] { chunks.finish(); });
|
||||||
|
std::uint64_t bytesRead = 0;
|
||||||
|
|
||||||
|
// Break the input up into chunks of size `step` and compress each chunk
|
||||||
|
// independently.
|
||||||
|
size_t step = calculateStep(size, numThreads, params);
|
||||||
|
auto status = FileStatus::Continue;
|
||||||
|
while (status == FileStatus::Continue && !errorHolder.hasError()) {
|
||||||
|
// Make a new input queue that we will put the chunk's input data into.
|
||||||
|
auto in = std::make_shared<BufferWorkQueue>();
|
||||||
|
auto inGuard = makeScopeGuard([&] { in->finish(); });
|
||||||
|
// Make a new output queue that compress will put the compressed data into.
|
||||||
|
auto out = std::make_shared<BufferWorkQueue>();
|
||||||
|
// Start compression in the thread pool
|
||||||
|
executor.add([&errorHolder, in, out, step, params] {
|
||||||
|
return compress(
|
||||||
|
errorHolder, std::move(in), std::move(out), step, params);
|
||||||
|
});
|
||||||
|
// Pass the output queue to the writer thread.
|
||||||
|
chunks.push(std::move(out));
|
||||||
|
// Fill the input queue for the compression job we just started
|
||||||
|
status = readData(*in, ZSTD_CStreamInSize(), step, fd, &bytesRead);
|
||||||
|
}
|
||||||
|
errorHolder.check(status != FileStatus::Error, "Error reading input");
|
||||||
|
return bytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decompress a frame, whose data is streamed into `in`, and stream the output
|
||||||
|
* to `out`.
|
||||||
|
*
|
||||||
|
* @param errorHolder Used to report errors and check if an error occured
|
||||||
|
* @param in Queue that we `pop()` input buffers from. It contains
|
||||||
|
* exactly one compressed frame.
|
||||||
|
* @param out Queue that we `push()` decompressed output buffers to
|
||||||
|
*/
|
||||||
|
static void decompress(
|
||||||
|
ErrorHolder& errorHolder,
|
||||||
|
std::shared_ptr<BufferWorkQueue> in,
|
||||||
|
std::shared_ptr<BufferWorkQueue> out) {
|
||||||
|
auto guard = makeScopeGuard([&] { out->finish(); });
|
||||||
|
// Initialize the DCtx
|
||||||
|
std::unique_ptr<ZSTD_DStream, size_t (*)(ZSTD_DStream*)> ctx(
|
||||||
|
ZSTD_createDStream(), ZSTD_freeDStream);
|
||||||
|
if (!errorHolder.check(ctx != nullptr, "Failed to allocate ZSTD_DStream")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto err = ZSTD_initDStream(ctx.get());
|
||||||
|
if (!errorHolder.check(!ZSTD_isError(err), ZSTD_getErrorName(err))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t outSize = ZSTD_DStreamOutSize();
|
||||||
|
Buffer inBuffer;
|
||||||
|
size_t returnCode = 0;
|
||||||
|
// Read a buffer in from the input queue
|
||||||
|
while (in->pop(inBuffer) && !errorHolder.hasError()) {
|
||||||
|
auto zstdInBuffer = makeZstdInBuffer(inBuffer);
|
||||||
|
// Decompress the whole buffer and send it to the output queue
|
||||||
|
while (!inBuffer.empty() && !errorHolder.hasError()) {
|
||||||
|
// Allocate a buffer with at least outSize bytes.
|
||||||
|
Buffer outBuffer(outSize);
|
||||||
|
auto zstdOutBuffer = makeZstdOutBuffer(outBuffer);
|
||||||
|
// Decompress
|
||||||
|
returnCode =
|
||||||
|
ZSTD_decompressStream(ctx.get(), &zstdOutBuffer, &zstdInBuffer);
|
||||||
|
if (!errorHolder.check(
|
||||||
|
!ZSTD_isError(returnCode), ZSTD_getErrorName(returnCode))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Pass the buffer with the decompressed data to the output queue
|
||||||
|
out->push(split(outBuffer, zstdOutBuffer));
|
||||||
|
// Advance past the input we already read
|
||||||
|
advance(inBuffer, zstdInBuffer);
|
||||||
|
if (returnCode == 0) {
|
||||||
|
// The frame is over, prepare to (maybe) start a new frame
|
||||||
|
ZSTD_initDStream(ctx.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!errorHolder.check(returnCode <= 1, "Incomplete block")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// We've given ZSTD_decompressStream all of our data, but there may still
|
||||||
|
// be data to read.
|
||||||
|
while (returnCode == 1) {
|
||||||
|
// Allocate a buffer with at least outSize bytes.
|
||||||
|
Buffer outBuffer(outSize);
|
||||||
|
auto zstdOutBuffer = makeZstdOutBuffer(outBuffer);
|
||||||
|
// Pass in no input.
|
||||||
|
ZSTD_inBuffer zstdInBuffer{nullptr, 0, 0};
|
||||||
|
// Decompress
|
||||||
|
returnCode =
|
||||||
|
ZSTD_decompressStream(ctx.get(), &zstdOutBuffer, &zstdInBuffer);
|
||||||
|
if (!errorHolder.check(
|
||||||
|
!ZSTD_isError(returnCode), ZSTD_getErrorName(returnCode))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Pass the buffer with the decompressed data to the output queue
|
||||||
|
out->push(split(outBuffer, zstdOutBuffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint64_t asyncDecompressFrames(
|
||||||
|
ErrorHolder& errorHolder,
|
||||||
|
WorkQueue<std::shared_ptr<BufferWorkQueue>>& frames,
|
||||||
|
ThreadPool& executor,
|
||||||
|
FILE* fd) {
|
||||||
|
auto framesGuard = makeScopeGuard([&] { frames.finish(); });
|
||||||
|
std::uint64_t totalBytesRead = 0;
|
||||||
|
|
||||||
|
// Split the source up into its component frames.
|
||||||
|
// If we find our recognized skippable frame we know the next frames size
|
||||||
|
// which means that we can decompress each standard frame in independently.
|
||||||
|
// Otherwise, we will decompress using only one decompression task.
|
||||||
|
const size_t chunkSize = ZSTD_DStreamInSize();
|
||||||
|
auto status = FileStatus::Continue;
|
||||||
|
while (status == FileStatus::Continue && !errorHolder.hasError()) {
|
||||||
|
// Make a new input queue that we will put the frames's bytes into.
|
||||||
|
auto in = std::make_shared<BufferWorkQueue>();
|
||||||
|
auto inGuard = makeScopeGuard([&] { in->finish(); });
|
||||||
|
// Make a output queue that decompress will put the decompressed data into
|
||||||
|
auto out = std::make_shared<BufferWorkQueue>();
|
||||||
|
|
||||||
|
size_t frameSize;
|
||||||
|
{
|
||||||
|
// Calculate the size of the next frame.
|
||||||
|
// frameSize is 0 if the frame info can't be decoded.
|
||||||
|
Buffer buffer(SkippableFrame::kSize);
|
||||||
|
auto bytesRead = std::fread(buffer.data(), 1, buffer.size(), fd);
|
||||||
|
totalBytesRead += bytesRead;
|
||||||
|
status = fileStatus(fd);
|
||||||
|
if (bytesRead == 0 && status != FileStatus::Continue) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buffer.subtract(buffer.size() - bytesRead);
|
||||||
|
frameSize = SkippableFrame::tryRead(buffer.range());
|
||||||
|
in->push(std::move(buffer));
|
||||||
|
}
|
||||||
|
if (frameSize == 0) {
|
||||||
|
// We hit a non SkippableFrame, so this will be the last job.
|
||||||
|
// Make sure that we don't use too much memory
|
||||||
|
in->setMaxSize(64);
|
||||||
|
out->setMaxSize(64);
|
||||||
|
}
|
||||||
|
// Start decompression in the thread pool
|
||||||
|
executor.add([&errorHolder, in, out] {
|
||||||
|
return decompress(errorHolder, std::move(in), std::move(out));
|
||||||
|
});
|
||||||
|
// Pass the output queue to the writer thread
|
||||||
|
frames.push(std::move(out));
|
||||||
|
if (frameSize == 0) {
|
||||||
|
// We hit a non SkippableFrame ==> not compressed by pzstd or corrupted
|
||||||
|
// Pass the rest of the source to this decompression task
|
||||||
|
while (status == FileStatus::Continue && !errorHolder.hasError()) {
|
||||||
|
status = readData(*in, chunkSize, chunkSize, fd, &totalBytesRead);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Fill the input queue for the decompression job we just started
|
||||||
|
status = readData(*in, chunkSize, frameSize, fd, &totalBytesRead);
|
||||||
|
}
|
||||||
|
errorHolder.check(status != FileStatus::Error, "Error reading input");
|
||||||
|
return totalBytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write `data` to `fd`, returns true iff success.
|
||||||
|
static bool writeData(ByteRange data, FILE* fd) {
|
||||||
|
while (!data.empty()) {
|
||||||
|
data.advance(std::fwrite(data.begin(), 1, data.size(), fd));
|
||||||
|
if (std::ferror(fd)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateWritten(int verbosity, std::uint64_t bytesWritten) {
|
||||||
|
if (verbosity <= 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
using Clock = std::chrono::system_clock;
|
||||||
|
static Clock::time_point then;
|
||||||
|
constexpr std::chrono::milliseconds refreshRate{150};
|
||||||
|
|
||||||
|
auto now = Clock::now();
|
||||||
|
if (now - then > refreshRate) {
|
||||||
|
then = now;
|
||||||
|
std::fprintf(stderr, "\rWritten: %u MB ",
|
||||||
|
static_cast<std::uint32_t>(bytesWritten >> 20));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint64_t writeFile(
|
||||||
|
ErrorHolder& errorHolder,
|
||||||
|
WorkQueue<std::shared_ptr<BufferWorkQueue>>& outs,
|
||||||
|
FILE* outputFd,
|
||||||
|
bool decompress,
|
||||||
|
int verbosity) {
|
||||||
|
auto lineClearGuard = makeScopeGuard([verbosity] {
|
||||||
|
if (verbosity > 1) {
|
||||||
|
std::fprintf(stderr, "\r%79s\r", "");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
std::uint64_t bytesWritten = 0;
|
||||||
|
std::shared_ptr<BufferWorkQueue> out;
|
||||||
|
// Grab the output queue for each decompression job (in order).
|
||||||
|
while (outs.pop(out) && !errorHolder.hasError()) {
|
||||||
|
if (!decompress) {
|
||||||
|
// If we are compressing and want to write skippable frames we can't
|
||||||
|
// start writing before compression is done because we need to know the
|
||||||
|
// compressed size.
|
||||||
|
// Wait for the compressed size to be available and write skippable frame
|
||||||
|
SkippableFrame frame(out->size());
|
||||||
|
if (!writeData(frame.data(), outputFd)) {
|
||||||
|
errorHolder.setError("Failed to write output");
|
||||||
|
return bytesWritten;
|
||||||
|
}
|
||||||
|
bytesWritten += frame.kSize;
|
||||||
|
}
|
||||||
|
// For each chunk of the frame: Pop it from the queue and write it
|
||||||
|
Buffer buffer;
|
||||||
|
while (out->pop(buffer) && !errorHolder.hasError()) {
|
||||||
|
if (!writeData(buffer.range(), outputFd)) {
|
||||||
|
errorHolder.setError("Failed to write output");
|
||||||
|
return bytesWritten;
|
||||||
|
}
|
||||||
|
bytesWritten += buffer.size();
|
||||||
|
updateWritten(verbosity, bytesWritten);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bytesWritten;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ErrorHolder.h"
|
||||||
|
#include "Options.h"
|
||||||
|
#include "utils/Buffer.h"
|
||||||
|
#include "utils/Range.h"
|
||||||
|
#include "utils/ThreadPool.h"
|
||||||
|
#include "utils/WorkQueue.h"
|
||||||
|
#define ZSTD_STATIC_LINKING_ONLY
|
||||||
|
#include "zstd.h"
|
||||||
|
#undef ZSTD_STATIC_LINKING_ONLY
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace pzstd {
|
||||||
|
/**
|
||||||
|
* Runs pzstd with `options` and returns the number of bytes written.
|
||||||
|
* An error occurred if `errorHandler.hasError()`.
|
||||||
|
*
|
||||||
|
* @param options The pzstd options to use for (de)compression
|
||||||
|
* @returns 0 upon success and non-zero on failure.
|
||||||
|
*/
|
||||||
|
int pzstdMain(const Options& options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Streams input from `fd`, breaks input up into chunks, and compresses each
|
||||||
|
* chunk independently. Output of each chunk gets streamed to a queue, and
|
||||||
|
* the output queues get put into `chunks` in order.
|
||||||
|
*
|
||||||
|
* @param errorHolder Used to report errors and coordinate early shutdown
|
||||||
|
* @param chunks Each compression jobs output queue gets `pushed()` here
|
||||||
|
* as soon as it is available
|
||||||
|
* @param executor The thread pool to run compression jobs in
|
||||||
|
* @param fd The input file descriptor
|
||||||
|
* @param size The size of the input file if known, 0 otherwise
|
||||||
|
* @param numThreads The number of threads in the thread pool
|
||||||
|
* @param parameters The zstd parameters to use for compression
|
||||||
|
* @returns The number of bytes read from the file
|
||||||
|
*/
|
||||||
|
std::uint64_t asyncCompressChunks(
|
||||||
|
ErrorHolder& errorHolder,
|
||||||
|
WorkQueue<std::shared_ptr<BufferWorkQueue>>& chunks,
|
||||||
|
ThreadPool& executor,
|
||||||
|
FILE* fd,
|
||||||
|
std::uintmax_t size,
|
||||||
|
std::size_t numThreads,
|
||||||
|
ZSTD_parameters parameters);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Streams input from `fd`. If pzstd headers are available it breaks the input
|
||||||
|
* up into independent frames. It sends each frame to an independent
|
||||||
|
* decompression job. Output of each frame gets streamed to a queue, and
|
||||||
|
* the output queues get put into `frames` in order.
|
||||||
|
*
|
||||||
|
* @param errorHolder Used to report errors and coordinate early shutdown
|
||||||
|
* @param frames Each decompression jobs output queue gets `pushed()` here
|
||||||
|
* as soon as it is available
|
||||||
|
* @param executor The thread pool to run compression jobs in
|
||||||
|
* @param fd The input file descriptor
|
||||||
|
* @returns The number of bytes read from the file
|
||||||
|
*/
|
||||||
|
std::uint64_t asyncDecompressFrames(
|
||||||
|
ErrorHolder& errorHolder,
|
||||||
|
WorkQueue<std::shared_ptr<BufferWorkQueue>>& frames,
|
||||||
|
ThreadPool& executor,
|
||||||
|
FILE* fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Streams input in from each queue in `outs` in order, and writes the data to
|
||||||
|
* `outputFd`.
|
||||||
|
*
|
||||||
|
* @param errorHolder Used to report errors and coordinate early exit
|
||||||
|
* @param outs A queue of output queues, one for each
|
||||||
|
* (de)compression job.
|
||||||
|
* @param outputFd The file descriptor to write to
|
||||||
|
* @param decompress Are we decompressing?
|
||||||
|
* @param verbosity The verbosity level to log at
|
||||||
|
* @returns The number of bytes written
|
||||||
|
*/
|
||||||
|
std::uint64_t writeFile(
|
||||||
|
ErrorHolder& errorHolder,
|
||||||
|
WorkQueue<std::shared_ptr<BufferWorkQueue>>& outs,
|
||||||
|
FILE* outputFd,
|
||||||
|
bool decompress,
|
||||||
|
int verbosity);
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
# Parallel Zstandard (PZstandard)
|
||||||
|
|
||||||
|
Parallel Zstandard is a Pigz-like tool for Zstandard.
|
||||||
|
It provides Zstandard format compatible compression and decompression that is able to utilize multiple cores.
|
||||||
|
It breaks the input up into equal sized chunks and compresses each chunk independently into a Zstandard frame.
|
||||||
|
It then concatenates the frames together to produce the final compressed output.
|
||||||
|
Pzstandard will write a 12 byte header for each frame that is a skippable frame in the Zstandard format, which tells PZstandard the size of the next compressed frame.
|
||||||
|
PZstandard supports parallel decompression of files compressed with PZstandard.
|
||||||
|
When decompressing files compressed with Zstandard, PZstandard does IO in one thread, and decompression in another.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
PZstandard supports the same command line interface as Zstandard, but also provies the `-p` option to specify the number of threads.
|
||||||
|
Dictionary mode is not currently supported.
|
||||||
|
|
||||||
|
Basic usage
|
||||||
|
|
||||||
|
pzstd input-file -o output-file -p num-threads -# # Compression
|
||||||
|
pzstd -d input-file -o output-file -p num-threads # Decompression
|
||||||
|
|
||||||
|
PZstandard also supports piping and fifo pipes
|
||||||
|
|
||||||
|
cat input-file | pzstd -p num-threads -# -c > /dev/null
|
||||||
|
|
||||||
|
For more options
|
||||||
|
|
||||||
|
pzstd --help
|
||||||
|
|
||||||
|
PZstandard tries to pick a smart default number of threads if not specified (displayed in `pzstd --help`).
|
||||||
|
If this number is not suitable, during compilation you can define `PZSTD_NUM_THREADS` to the number of threads you prefer.
|
||||||
|
|
||||||
|
## Benchmarks
|
||||||
|
|
||||||
|
As a reference, PZstandard and Pigz were compared on an Intel Core i7 @ 3.1 GHz, each using 4 threads, with the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia).
|
||||||
|
|
||||||
|
Compression Speed vs Ratio with 4 Threads | Decompression Speed with 4 Threads
|
||||||
|
------------------------------------------|-----------------------------------
|
||||||
|
 | 
|
||||||
|
|
||||||
|
The test procedure was to run each of the following commands 2 times for each compression level, and take the minimum time.
|
||||||
|
|
||||||
|
time pzstd -# -p 4 -c silesia.tar > silesia.tar.zst
|
||||||
|
time pzstd -d -p 4 -c silesia.tar.zst > /dev/null
|
||||||
|
|
||||||
|
time pigz -# -p 4 -k -c silesia.tar > silesia.tar.gz
|
||||||
|
time pigz -d -p 4 -k -c silesia.tar.gz > /dev/null
|
||||||
|
|
||||||
|
PZstandard was tested using compression levels 1-19, and Pigz was tested using compression levels 1-9.
|
||||||
|
Pigz cannot do parallel decompression, it simply does each of reading, decompression, and writing on separate threads.
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
Tests require that you have [gtest](https://github.com/google/googletest) installed.
|
||||||
|
Modify `GTEST_INC` and `GTEST_LIB` in `test/Makefile` and `utils/test/Makefile` to work for your install of gtest.
|
||||||
|
Then run `make test` in the `contrib/pzstd` directory.
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#include "SkippableFrame.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include "utils/Range.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
using namespace pzstd;
|
||||||
|
|
||||||
|
SkippableFrame::SkippableFrame(std::uint32_t size) : frameSize_(size) {
|
||||||
|
MEM_writeLE32(data_.data(), kSkippableFrameMagicNumber);
|
||||||
|
MEM_writeLE32(data_.data() + 4, kFrameContentsSize);
|
||||||
|
MEM_writeLE32(data_.data() + 8, frameSize_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ std::size_t SkippableFrame::tryRead(ByteRange bytes) {
|
||||||
|
if (bytes.size() < SkippableFrame::kSize ||
|
||||||
|
MEM_readLE32(bytes.begin()) != kSkippableFrameMagicNumber ||
|
||||||
|
MEM_readLE32(bytes.begin() + 4) != kFrameContentsSize) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return MEM_readLE32(bytes.begin() + 8);
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "utils/Range.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
namespace pzstd {
|
||||||
|
/**
|
||||||
|
* We put a skippable frame before each frame.
|
||||||
|
* It contains a skippable frame magic number, the size of the skippable frame,
|
||||||
|
* and the size of the next frame.
|
||||||
|
* Each skippable frame is exactly 12 bytes in little endian format.
|
||||||
|
* The first 8 bytes are for compatibility with the ZSTD format.
|
||||||
|
* If we have N threads, the output will look like
|
||||||
|
*
|
||||||
|
* [0x184D2A50|4|size1] [frame1 of size size1]
|
||||||
|
* [0x184D2A50|4|size2] [frame2 of size size2]
|
||||||
|
* ...
|
||||||
|
* [0x184D2A50|4|sizeN] [frameN of size sizeN]
|
||||||
|
*
|
||||||
|
* Each sizeX is 4 bytes.
|
||||||
|
*
|
||||||
|
* These skippable frames should allow us to skip through the compressed file
|
||||||
|
* and only load at most N pages.
|
||||||
|
*/
|
||||||
|
class SkippableFrame {
|
||||||
|
public:
|
||||||
|
static constexpr std::size_t kSize = 12;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::uint32_t frameSize_;
|
||||||
|
std::array<std::uint8_t, kSize> data_;
|
||||||
|
static constexpr std::uint32_t kSkippableFrameMagicNumber = 0x184D2A50;
|
||||||
|
// Could be improved if the size fits in less bytes
|
||||||
|
static constexpr std::uint32_t kFrameContentsSize = kSize - 8;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Write the skippable frame to data_ in LE format.
|
||||||
|
explicit SkippableFrame(std::uint32_t size);
|
||||||
|
|
||||||
|
// Read the skippable frame from bytes in LE format.
|
||||||
|
static std::size_t tryRead(ByteRange bytes);
|
||||||
|
|
||||||
|
ByteRange data() const {
|
||||||
|
return {data_.data(), data_.size()};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size of the next frame.
|
||||||
|
std::size_t frameSize() const {
|
||||||
|
return frameSize_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
@@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#include "ErrorHolder.h"
|
||||||
|
#include "Options.h"
|
||||||
|
#include "Pzstd.h"
|
||||||
|
#include "utils/FileSystem.h"
|
||||||
|
#include "utils/Range.h"
|
||||||
|
#include "utils/ScopeGuard.h"
|
||||||
|
#include "utils/ThreadPool.h"
|
||||||
|
#include "utils/WorkQueue.h"
|
||||||
|
|
||||||
|
using namespace pzstd;
|
||||||
|
|
||||||
|
int main(int argc, const char** argv) {
|
||||||
|
Options options;
|
||||||
|
switch (options.parse(argc, argv)) {
|
||||||
|
case Options::Status::Failure:
|
||||||
|
return 1;
|
||||||
|
case Options::Status::Message:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pzstdMain(options);
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# ##########################################################################
|
||||||
|
# Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This source code is licensed under the BSD-style license found in the
|
||||||
|
# LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
# of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
# ##########################################################################
|
||||||
|
|
||||||
|
# Define *.exe as extension for Windows systems
|
||||||
|
ifneq (,$(filter Windows%,$(OS)))
|
||||||
|
EXT =.exe
|
||||||
|
else
|
||||||
|
EXT =
|
||||||
|
endif
|
||||||
|
|
||||||
|
PZSTDDIR = ..
|
||||||
|
PROGDIR = ../../../programs
|
||||||
|
ZSTDDIR = ../../../lib
|
||||||
|
|
||||||
|
# Set GTEST_INC and GTEST_LIB to work with your install of gtest
|
||||||
|
GTEST_INC ?= -isystem $(PZSTDDIR)/googletest/googletest/include
|
||||||
|
GTEST_LIB ?= -L $(PZSTDDIR)/googletest/build/googlemock/gtest
|
||||||
|
GTEST_FLAGS = $(GTEST_INC) $(GTEST_LIB)
|
||||||
|
CPPFLAGS = -I$(PZSTDDIR) -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(PROGDIR) -I.
|
||||||
|
|
||||||
|
CXXFLAGS ?= -O3
|
||||||
|
CXXFLAGS += -std=c++11 -Wno-deprecated-declarations
|
||||||
|
CXXFLAGS += $(MOREFLAGS)
|
||||||
|
FLAGS = $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS)
|
||||||
|
|
||||||
|
datagen.o: $(PROGDIR)/datagen.*
|
||||||
|
$(CC) $(CPPFLAGS) -O3 $(MOREFLAGS) $(LDFLAGS) -Wno-long-long -Wno-variadic-macros $(PROGDIR)/datagen.c -c -o $@
|
||||||
|
|
||||||
|
%: %.cpp *.h datagen.o
|
||||||
|
$(CXX) $(FLAGS) $@.cpp datagen.o $(PZSTDDIR)/Pzstd.o $(PZSTDDIR)/SkippableFrame.o $(PZSTDDIR)/Options.o $(PZSTDDIR)/libzstd.a -o $@$(EXT) $(GTEST_FLAGS) -lgtest -lgtest_main -lpthread
|
||||||
|
|
||||||
|
.PHONY: test clean
|
||||||
|
|
||||||
|
test: OptionsTest PzstdTest
|
||||||
|
@./OptionsTest$(EXT)
|
||||||
|
@./PzstdTest$(EXT)
|
||||||
|
|
||||||
|
roundtrip: RoundTripTest
|
||||||
|
@./RoundTripTest$(EXT)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f datagen.o OptionsTest PzstdTest RoundTripTest
|
||||||
@@ -0,0 +1,542 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#include "Options.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
using namespace pzstd;
|
||||||
|
|
||||||
|
namespace pzstd {
|
||||||
|
bool operator==(const Options &lhs, const Options &rhs) {
|
||||||
|
return lhs.numThreads == rhs.numThreads &&
|
||||||
|
lhs.maxWindowLog == rhs.maxWindowLog &&
|
||||||
|
lhs.compressionLevel == rhs.compressionLevel &&
|
||||||
|
lhs.decompress == rhs.decompress && lhs.inputFiles == rhs.inputFiles &&
|
||||||
|
lhs.outputFile == rhs.outputFile && lhs.overwrite == rhs.overwrite &&
|
||||||
|
lhs.keepSource == rhs.keepSource && lhs.writeMode == rhs.writeMode &&
|
||||||
|
lhs.checksum == rhs.checksum && lhs.verbosity == rhs.verbosity;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const Options &opt) {
|
||||||
|
out << "{";
|
||||||
|
{
|
||||||
|
out << "\n\t"
|
||||||
|
<< "numThreads: " << opt.numThreads;
|
||||||
|
out << ",\n\t"
|
||||||
|
<< "maxWindowLog: " << opt.maxWindowLog;
|
||||||
|
out << ",\n\t"
|
||||||
|
<< "compressionLevel: " << opt.compressionLevel;
|
||||||
|
out << ",\n\t"
|
||||||
|
<< "decompress: " << opt.decompress;
|
||||||
|
out << ",\n\t"
|
||||||
|
<< "inputFiles: {";
|
||||||
|
{
|
||||||
|
bool first = true;
|
||||||
|
for (const auto &file : opt.inputFiles) {
|
||||||
|
if (!first) {
|
||||||
|
out << ",";
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
out << "\n\t\t" << file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out << "\n\t}";
|
||||||
|
out << ",\n\t"
|
||||||
|
<< "outputFile: " << opt.outputFile;
|
||||||
|
out << ",\n\t"
|
||||||
|
<< "overwrite: " << opt.overwrite;
|
||||||
|
out << ",\n\t"
|
||||||
|
<< "keepSource: " << opt.keepSource;
|
||||||
|
out << ",\n\t"
|
||||||
|
<< "writeMode: " << static_cast<int>(opt.writeMode);
|
||||||
|
out << ",\n\t"
|
||||||
|
<< "checksum: " << opt.checksum;
|
||||||
|
out << ",\n\t"
|
||||||
|
<< "verbosity: " << opt.verbosity;
|
||||||
|
}
|
||||||
|
out << "\n}";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
#ifdef _WIN32
|
||||||
|
const char nullOutput[] = "nul";
|
||||||
|
#else
|
||||||
|
const char nullOutput[] = "/dev/null";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
constexpr auto autoMode = Options::WriteMode::Auto;
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
#define EXPECT_SUCCESS(...) EXPECT_EQ(Options::Status::Success, __VA_ARGS__)
|
||||||
|
#define EXPECT_FAILURE(...) EXPECT_EQ(Options::Status::Failure, __VA_ARGS__)
|
||||||
|
#define EXPECT_MESSAGE(...) EXPECT_EQ(Options::Status::Message, __VA_ARGS__)
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
std::array<const char *, sizeof...(Args) + 1> makeArray(Args... args) {
|
||||||
|
return {{nullptr, args...}};
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Options, ValidInputs) {
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("--processes", "5", "-o", "x", "y", "-f");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
Options expected = {5, 23, 3, false, {"y"}, "x",
|
||||||
|
true, true, autoMode, true, 2};
|
||||||
|
EXPECT_EQ(expected, options);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("-p", "1", "input", "-19");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
Options expected = {1, 23, 19, false, {"input"}, "",
|
||||||
|
false, true, autoMode, true, 2};
|
||||||
|
EXPECT_EQ(expected, options);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args =
|
||||||
|
makeArray("--ultra", "-22", "-p", "1", "-o", "x", "-d", "x.zst", "-f");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
Options expected = {1, 0, 22, true, {"x.zst"}, "x",
|
||||||
|
true, true, autoMode, true, 2};
|
||||||
|
EXPECT_EQ(expected, options);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("--processes", "100", "hello.zst", "--decompress",
|
||||||
|
"--force");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
Options expected = {100, 23, 3, true, {"hello.zst"}, "", true,
|
||||||
|
true, autoMode, true, 2};
|
||||||
|
EXPECT_EQ(expected, options);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "-dp", "1", "-c");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
Options expected = {1, 23, 3, true, {"x"}, "-",
|
||||||
|
false, true, autoMode, true, 2};
|
||||||
|
EXPECT_EQ(expected, options);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "-dp", "1", "--stdout");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
Options expected = {1, 23, 3, true, {"x"}, "-",
|
||||||
|
false, true, autoMode, true, 2};
|
||||||
|
EXPECT_EQ(expected, options);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("-p", "1", "x", "-5", "-fo", "-", "--ultra", "-d");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
Options expected = {1, 0, 5, true, {"x"}, "-",
|
||||||
|
true, true, autoMode, true, 2};
|
||||||
|
EXPECT_EQ(expected, options);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("silesia.tar", "-o", "silesia.tar.pzstd", "-p", "2");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
Options expected = {2,
|
||||||
|
23,
|
||||||
|
3,
|
||||||
|
false,
|
||||||
|
{"silesia.tar"},
|
||||||
|
"silesia.tar.pzstd",
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
autoMode,
|
||||||
|
true,
|
||||||
|
2};
|
||||||
|
EXPECT_EQ(expected, options);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "-p", "1");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "-p", "1");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Options, GetOutputFile) {
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ("x.zst", options.getOutputFile(options.inputFiles[0]));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("-o-");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ("-", options.getOutputFile(options.inputFiles[0]));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "y", "-o", nullOutput);
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(nullOutput, options.getOutputFile(options.inputFiles[0]));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x.zst", "-do", nullOutput);
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(nullOutput, options.getOutputFile(options.inputFiles[0]));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x.zst", "-d");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ("x", options.getOutputFile(options.inputFiles[0]));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("xzst", "-d");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ("", options.getOutputFile(options.inputFiles[0]));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("xzst", "-doxx");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ("xx", options.getOutputFile(options.inputFiles[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Options, MultipleFiles) {
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "y", "z");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
Options expected;
|
||||||
|
expected.inputFiles = {"x", "y", "z"};
|
||||||
|
expected.verbosity = 1;
|
||||||
|
EXPECT_EQ(expected, options);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "y", "z", "-o", nullOutput);
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
Options expected;
|
||||||
|
expected.inputFiles = {"x", "y", "z"};
|
||||||
|
expected.outputFile = nullOutput;
|
||||||
|
expected.verbosity = 1;
|
||||||
|
EXPECT_EQ(expected, options);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "y", "-o-");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "y", "-o", "file");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("-qqvd12qp4", "-f", "x", "--", "--rm", "-c");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
Options expected = {4, 23, 12, true, {"x", "--rm", "-c"},
|
||||||
|
"", true, true, autoMode, true,
|
||||||
|
0};
|
||||||
|
EXPECT_EQ(expected, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Options, NumThreads) {
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "-dfo", "-");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "-p", "0", "-fo", "-");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("-f", "-p", "-o", "-");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Options, BadCompressionLevel) {
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "-20");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "--ultra", "-23");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "--1"); // negative 1?
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Options, InvalidOption) {
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "-x");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Options, BadOutputFile) {
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("notzst", "-d", "-p", "1");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ("", options.getOutputFile(options.inputFiles.front()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Options, BadOptionsWithArguments) {
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "-pf");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "-p", "10f");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "-p");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "-o");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "-o");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Options, KeepSource) {
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "--rm", "-k");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(true, options.keepSource);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "--rm", "--keep");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(true, options.keepSource);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(true, options.keepSource);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "--rm");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(false, options.keepSource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Options, Verbosity) {
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(2, options.verbosity);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("--quiet", "-qq", "x");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(-1, options.verbosity);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "y");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(1, options.verbosity);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("--", "x", "y");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(1, options.verbosity);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("-qv", "x", "y");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(1, options.verbosity);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("-v", "x", "y");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(3, options.verbosity);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("-v", "x");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(3, options.verbosity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Options, TestMode) {
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "-t");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(true, options.keepSource);
|
||||||
|
EXPECT_EQ(true, options.decompress);
|
||||||
|
EXPECT_EQ(nullOutput, options.outputFile);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "--test", "--rm", "-ohello");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(true, options.keepSource);
|
||||||
|
EXPECT_EQ(true, options.decompress);
|
||||||
|
EXPECT_EQ(nullOutput, options.outputFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Options, Checksum) {
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x.zst", "--no-check", "-Cd");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(true, options.checksum);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(true, options.checksum);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "--no-check", "--check");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(true, options.checksum);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "--no-check");
|
||||||
|
EXPECT_SUCCESS(options.parse(args.size(), args.data()));
|
||||||
|
EXPECT_EQ(false, options.checksum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Options, InputFiles) {
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("-cd");
|
||||||
|
options.parse(args.size(), args.data());
|
||||||
|
EXPECT_EQ(1, options.inputFiles.size());
|
||||||
|
EXPECT_EQ("-", options.inputFiles[0]);
|
||||||
|
EXPECT_EQ("-", options.outputFile);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray();
|
||||||
|
options.parse(args.size(), args.data());
|
||||||
|
EXPECT_EQ(1, options.inputFiles.size());
|
||||||
|
EXPECT_EQ("-", options.inputFiles[0]);
|
||||||
|
EXPECT_EQ("-", options.outputFile);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("-d");
|
||||||
|
options.parse(args.size(), args.data());
|
||||||
|
EXPECT_EQ(1, options.inputFiles.size());
|
||||||
|
EXPECT_EQ("-", options.inputFiles[0]);
|
||||||
|
EXPECT_EQ("-", options.outputFile);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("x", "-");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Options, InvalidOptions) {
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("-ibasdf");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("- ");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("-n15");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("-0", "x");
|
||||||
|
EXPECT_FAILURE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Options, Extras) {
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("-h");
|
||||||
|
EXPECT_MESSAGE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("-H");
|
||||||
|
EXPECT_MESSAGE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("-V");
|
||||||
|
EXPECT_MESSAGE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("--help");
|
||||||
|
EXPECT_MESSAGE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Options options;
|
||||||
|
auto args = makeArray("--version");
|
||||||
|
EXPECT_MESSAGE(options.parse(args.size(), args.data()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#include "Pzstd.h"
|
||||||
|
extern "C" {
|
||||||
|
#include "datagen.h"
|
||||||
|
}
|
||||||
|
#include "test/RoundTrip.h"
|
||||||
|
#include "utils/ScopeGuard.h"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace pzstd;
|
||||||
|
|
||||||
|
TEST(Pzstd, SmallSizes) {
|
||||||
|
unsigned seed = std::random_device{}();
|
||||||
|
std::fprintf(stderr, "Pzstd.SmallSizes seed: %u\n", seed);
|
||||||
|
std::mt19937 gen(seed);
|
||||||
|
|
||||||
|
for (unsigned len = 1; len < 256; ++len) {
|
||||||
|
if (len % 16 == 0) {
|
||||||
|
std::fprintf(stderr, "%u / 16\n", len / 16);
|
||||||
|
}
|
||||||
|
std::string inputFile = std::tmpnam(nullptr);
|
||||||
|
auto guard = makeScopeGuard([&] { std::remove(inputFile.c_str()); });
|
||||||
|
{
|
||||||
|
static uint8_t buf[256];
|
||||||
|
RDG_genBuffer(buf, len, 0.5, 0.0, gen());
|
||||||
|
auto fd = std::fopen(inputFile.c_str(), "wb");
|
||||||
|
auto written = std::fwrite(buf, 1, len, fd);
|
||||||
|
std::fclose(fd);
|
||||||
|
ASSERT_EQ(written, len);
|
||||||
|
}
|
||||||
|
for (unsigned headers = 0; headers <= 1; ++headers) {
|
||||||
|
for (unsigned numThreads = 1; numThreads <= 2; ++numThreads) {
|
||||||
|
for (unsigned level = 1; level <= 4; level *= 4) {
|
||||||
|
auto errorGuard = makeScopeGuard([&] {
|
||||||
|
std::fprintf(stderr, "pzstd headers: %u\n", headers);
|
||||||
|
std::fprintf(stderr, "# threads: %u\n", numThreads);
|
||||||
|
std::fprintf(stderr, "compression level: %u\n", level);
|
||||||
|
});
|
||||||
|
Options options;
|
||||||
|
options.overwrite = true;
|
||||||
|
options.inputFiles = {inputFile};
|
||||||
|
options.numThreads = numThreads;
|
||||||
|
options.compressionLevel = level;
|
||||||
|
options.verbosity = 1;
|
||||||
|
ASSERT_TRUE(roundTrip(options));
|
||||||
|
errorGuard.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Pzstd, LargeSizes) {
|
||||||
|
unsigned seed = std::random_device{}();
|
||||||
|
std::fprintf(stderr, "Pzstd.LargeSizes seed: %u\n", seed);
|
||||||
|
std::mt19937 gen(seed);
|
||||||
|
|
||||||
|
for (unsigned len = 1 << 20; len <= (1 << 24); len *= 2) {
|
||||||
|
std::string inputFile = std::tmpnam(nullptr);
|
||||||
|
auto guard = makeScopeGuard([&] { std::remove(inputFile.c_str()); });
|
||||||
|
{
|
||||||
|
std::unique_ptr<uint8_t[]> buf(new uint8_t[len]);
|
||||||
|
RDG_genBuffer(buf.get(), len, 0.5, 0.0, gen());
|
||||||
|
auto fd = std::fopen(inputFile.c_str(), "wb");
|
||||||
|
auto written = std::fwrite(buf.get(), 1, len, fd);
|
||||||
|
std::fclose(fd);
|
||||||
|
ASSERT_EQ(written, len);
|
||||||
|
}
|
||||||
|
for (unsigned headers = 0; headers <= 1; ++headers) {
|
||||||
|
for (unsigned numThreads = 1; numThreads <= 16; numThreads *= 4) {
|
||||||
|
for (unsigned level = 1; level <= 4; level *= 2) {
|
||||||
|
auto errorGuard = makeScopeGuard([&] {
|
||||||
|
std::fprintf(stderr, "pzstd headers: %u\n", headers);
|
||||||
|
std::fprintf(stderr, "# threads: %u\n", numThreads);
|
||||||
|
std::fprintf(stderr, "compression level: %u\n", level);
|
||||||
|
});
|
||||||
|
Options options;
|
||||||
|
options.overwrite = true;
|
||||||
|
options.inputFiles = {inputFile};
|
||||||
|
options.numThreads = std::min(numThreads, options.numThreads);
|
||||||
|
options.compressionLevel = level;
|
||||||
|
options.verbosity = 1;
|
||||||
|
ASSERT_TRUE(roundTrip(options));
|
||||||
|
errorGuard.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Pzstd, ExtremelyLargeSize) {
|
||||||
|
unsigned seed = std::random_device{}();
|
||||||
|
std::fprintf(stderr, "Pzstd.ExtremelyLargeSize seed: %u\n", seed);
|
||||||
|
std::mt19937 gen(seed);
|
||||||
|
|
||||||
|
std::string inputFile = std::tmpnam(nullptr);
|
||||||
|
auto guard = makeScopeGuard([&] { std::remove(inputFile.c_str()); });
|
||||||
|
|
||||||
|
{
|
||||||
|
// Write 4GB + 64 MB
|
||||||
|
constexpr size_t kLength = 1 << 26;
|
||||||
|
std::unique_ptr<uint8_t[]> buf(new uint8_t[kLength]);
|
||||||
|
auto fd = std::fopen(inputFile.c_str(), "wb");
|
||||||
|
auto closeGuard = makeScopeGuard([&] { std::fclose(fd); });
|
||||||
|
for (size_t i = 0; i < (1 << 6) + 1; ++i) {
|
||||||
|
RDG_genBuffer(buf.get(), kLength, 0.5, 0.0, gen());
|
||||||
|
auto written = std::fwrite(buf.get(), 1, kLength, fd);
|
||||||
|
if (written != kLength) {
|
||||||
|
std::fprintf(stderr, "Failed to write file, skipping test\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Options options;
|
||||||
|
options.overwrite = true;
|
||||||
|
options.inputFiles = {inputFile};
|
||||||
|
options.compressionLevel = 1;
|
||||||
|
if (options.numThreads == 0) {
|
||||||
|
options.numThreads = 1;
|
||||||
|
}
|
||||||
|
ASSERT_TRUE(roundTrip(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Pzstd, ExtremelyCompressible) {
|
||||||
|
std::string inputFile = std::tmpnam(nullptr);
|
||||||
|
auto guard = makeScopeGuard([&] { std::remove(inputFile.c_str()); });
|
||||||
|
{
|
||||||
|
std::unique_ptr<uint8_t[]> buf(new uint8_t[10000]);
|
||||||
|
std::memset(buf.get(), 'a', 10000);
|
||||||
|
auto fd = std::fopen(inputFile.c_str(), "wb");
|
||||||
|
auto written = std::fwrite(buf.get(), 1, 10000, fd);
|
||||||
|
std::fclose(fd);
|
||||||
|
ASSERT_EQ(written, 10000);
|
||||||
|
}
|
||||||
|
Options options;
|
||||||
|
options.overwrite = true;
|
||||||
|
options.inputFiles = {inputFile};
|
||||||
|
options.numThreads = 1;
|
||||||
|
options.compressionLevel = 1;
|
||||||
|
ASSERT_TRUE(roundTrip(options));
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Options.h"
|
||||||
|
#include "Pzstd.h"
|
||||||
|
#include "utils/ScopeGuard.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <string>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace pzstd {
|
||||||
|
|
||||||
|
inline bool check(std::string source, std::string decompressed) {
|
||||||
|
std::unique_ptr<std::uint8_t[]> sBuf(new std::uint8_t[1024]);
|
||||||
|
std::unique_ptr<std::uint8_t[]> dBuf(new std::uint8_t[1024]);
|
||||||
|
|
||||||
|
auto sFd = std::fopen(source.c_str(), "rb");
|
||||||
|
auto dFd = std::fopen(decompressed.c_str(), "rb");
|
||||||
|
auto guard = makeScopeGuard([&] {
|
||||||
|
std::fclose(sFd);
|
||||||
|
std::fclose(dFd);
|
||||||
|
});
|
||||||
|
|
||||||
|
size_t sRead, dRead;
|
||||||
|
|
||||||
|
do {
|
||||||
|
sRead = std::fread(sBuf.get(), 1, 1024, sFd);
|
||||||
|
dRead = std::fread(dBuf.get(), 1, 1024, dFd);
|
||||||
|
if (std::ferror(sFd) || std::ferror(dFd)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (sRead != dRead) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sRead; ++i) {
|
||||||
|
if (sBuf.get()[i] != dBuf.get()[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (sRead == 1024);
|
||||||
|
if (!std::feof(sFd) || !std::feof(dFd)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool roundTrip(Options& options) {
|
||||||
|
if (options.inputFiles.size() != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string source = options.inputFiles.front();
|
||||||
|
std::string compressedFile = std::tmpnam(nullptr);
|
||||||
|
std::string decompressedFile = std::tmpnam(nullptr);
|
||||||
|
auto guard = makeScopeGuard([&] {
|
||||||
|
std::remove(compressedFile.c_str());
|
||||||
|
std::remove(decompressedFile.c_str());
|
||||||
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
options.outputFile = compressedFile;
|
||||||
|
options.decompress = false;
|
||||||
|
if (pzstdMain(options) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
options.decompress = true;
|
||||||
|
options.inputFiles.front() = compressedFile;
|
||||||
|
options.outputFile = decompressedFile;
|
||||||
|
if (pzstdMain(options) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return check(source, decompressedFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
extern "C" {
|
||||||
|
#include "datagen.h"
|
||||||
|
}
|
||||||
|
#include "Options.h"
|
||||||
|
#include "test/RoundTrip.h"
|
||||||
|
#include "utils/ScopeGuard.h"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <memory>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace pzstd;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
string
|
||||||
|
writeData(size_t size, double matchProba, double litProba, unsigned seed) {
|
||||||
|
std::unique_ptr<uint8_t[]> buf(new uint8_t[size]);
|
||||||
|
RDG_genBuffer(buf.get(), size, matchProba, litProba, seed);
|
||||||
|
string file = tmpnam(nullptr);
|
||||||
|
auto fd = std::fopen(file.c_str(), "wb");
|
||||||
|
auto guard = makeScopeGuard([&] { std::fclose(fd); });
|
||||||
|
auto bytesWritten = std::fwrite(buf.get(), 1, size, fd);
|
||||||
|
if (bytesWritten != size) {
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Generator>
|
||||||
|
string generateInputFile(Generator& gen) {
|
||||||
|
// Use inputs ranging from 1 Byte to 2^16 Bytes
|
||||||
|
std::uniform_int_distribution<size_t> size{1, 1 << 16};
|
||||||
|
std::uniform_real_distribution<> prob{0, 1};
|
||||||
|
return writeData(size(gen), prob(gen), prob(gen), gen());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Generator>
|
||||||
|
Options generateOptions(Generator& gen, const string& inputFile) {
|
||||||
|
Options options;
|
||||||
|
options.inputFiles = {inputFile};
|
||||||
|
options.overwrite = true;
|
||||||
|
|
||||||
|
std::uniform_int_distribution<unsigned> numThreads{1, 32};
|
||||||
|
std::uniform_int_distribution<unsigned> compressionLevel{1, 10};
|
||||||
|
|
||||||
|
options.numThreads = numThreads(gen);
|
||||||
|
options.compressionLevel = compressionLevel(gen);
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::mt19937 gen(std::random_device{}());
|
||||||
|
|
||||||
|
auto newlineGuard = makeScopeGuard([] { std::fprintf(stderr, "\n"); });
|
||||||
|
for (unsigned i = 0; i < 10000; ++i) {
|
||||||
|
if (i % 100 == 0) {
|
||||||
|
std::fprintf(stderr, "Progress: %u%%\r", i / 100);
|
||||||
|
}
|
||||||
|
auto inputFile = generateInputFile(gen);
|
||||||
|
auto inputGuard = makeScopeGuard([&] { std::remove(inputFile.c_str()); });
|
||||||
|
for (unsigned i = 0; i < 10; ++i) {
|
||||||
|
auto options = generateOptions(gen, inputFile);
|
||||||
|
if (!roundTrip(options)) {
|
||||||
|
std::fprintf(stderr, "numThreads: %u\n", options.numThreads);
|
||||||
|
std::fprintf(stderr, "level: %u\n", options.compressionLevel);
|
||||||
|
std::fprintf(stderr, "decompress? %u\n", (unsigned)options.decompress);
|
||||||
|
std::fprintf(stderr, "file: %s\n", inputFile.c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "utils/Range.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace pzstd {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `Buffer` has a pointer to a shared buffer, and a range of the buffer that
|
||||||
|
* it owns.
|
||||||
|
* The idea is that you can allocate one buffer, and write chunks into it
|
||||||
|
* and break off those chunks.
|
||||||
|
* The underlying buffer is reference counted, and will be destroyed when all
|
||||||
|
* `Buffer`s that reference it are destroyed.
|
||||||
|
*/
|
||||||
|
class Buffer {
|
||||||
|
std::shared_ptr<unsigned char> buffer_;
|
||||||
|
MutableByteRange range_;
|
||||||
|
|
||||||
|
static void delete_buffer(unsigned char* buffer) {
|
||||||
|
delete[] buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Construct an empty buffer that owns no data.
|
||||||
|
explicit Buffer() {}
|
||||||
|
|
||||||
|
/// Construct a `Buffer` that owns a new underlying buffer of size `size`.
|
||||||
|
explicit Buffer(std::size_t size)
|
||||||
|
: buffer_(new unsigned char[size], delete_buffer),
|
||||||
|
range_(buffer_.get(), buffer_.get() + size) {}
|
||||||
|
|
||||||
|
explicit Buffer(std::shared_ptr<unsigned char> buffer, MutableByteRange data)
|
||||||
|
: buffer_(buffer), range_(data) {}
|
||||||
|
|
||||||
|
Buffer(Buffer&&) = default;
|
||||||
|
Buffer& operator=(Buffer&&) & = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Splits the data into two pieces: [begin, begin + n), [begin + n, end).
|
||||||
|
* Their data both points into the same underlying buffer.
|
||||||
|
* Modifies the original `Buffer` to point to only [begin + n, end).
|
||||||
|
*
|
||||||
|
* @param n The offset to split at.
|
||||||
|
* @returns A buffer that owns the data [begin, begin + n).
|
||||||
|
*/
|
||||||
|
Buffer splitAt(std::size_t n) {
|
||||||
|
auto firstPiece = range_.subpiece(0, n);
|
||||||
|
range_.advance(n);
|
||||||
|
return Buffer(buffer_, firstPiece);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Modifies the buffer to point to the range [begin + n, end).
|
||||||
|
void advance(std::size_t n) {
|
||||||
|
range_.advance(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Modifies the buffer to point to the range [begin, end - n).
|
||||||
|
void subtract(std::size_t n) {
|
||||||
|
range_.subtract(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a read only `Range` pointing to the `Buffer`s data.
|
||||||
|
ByteRange range() const {
|
||||||
|
return range_;
|
||||||
|
}
|
||||||
|
/// Returns a mutable `Range` pointing to the `Buffer`s data.
|
||||||
|
MutableByteRange range() {
|
||||||
|
return range_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned char* data() const {
|
||||||
|
return range_.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* data() {
|
||||||
|
return range_.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t size() const {
|
||||||
|
return range_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const {
|
||||||
|
return range_.empty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "utils/Range.h"
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <cerrno>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <system_error>
|
||||||
|
|
||||||
|
// A small subset of `std::filesystem`.
|
||||||
|
// `std::filesystem` should be a drop in replacement.
|
||||||
|
// See http://en.cppreference.com/w/cpp/filesystem for documentation.
|
||||||
|
|
||||||
|
namespace pzstd {
|
||||||
|
|
||||||
|
// using file_status = ... causes gcc to emit a false positive warning
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
typedef struct ::_stat64 file_status;
|
||||||
|
#else
|
||||||
|
typedef struct ::stat file_status;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// http://en.cppreference.com/w/cpp/filesystem/status
|
||||||
|
inline file_status status(StringPiece path, std::error_code& ec) noexcept {
|
||||||
|
file_status status;
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
const auto error = ::_stat64(path.data(), &status);
|
||||||
|
#else
|
||||||
|
const auto error = ::stat(path.data(), &status);
|
||||||
|
#endif
|
||||||
|
if (error) {
|
||||||
|
ec.assign(errno, std::generic_category());
|
||||||
|
} else {
|
||||||
|
ec.clear();
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// http://en.cppreference.com/w/cpp/filesystem/is_regular_file
|
||||||
|
inline bool is_regular_file(file_status status) noexcept {
|
||||||
|
#if defined(S_ISREG)
|
||||||
|
return S_ISREG(status.st_mode);
|
||||||
|
#elif !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
|
||||||
|
return (status.st_mode & S_IFMT) == S_IFREG;
|
||||||
|
#else
|
||||||
|
static_assert(false, "No POSIX stat() support.");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// http://en.cppreference.com/w/cpp/filesystem/is_regular_file
|
||||||
|
inline bool is_regular_file(StringPiece path, std::error_code& ec) noexcept {
|
||||||
|
return is_regular_file(status(path, ec));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// http://en.cppreference.com/w/cpp/filesystem/is_directory
|
||||||
|
inline bool is_directory(file_status status) noexcept {
|
||||||
|
#if defined(S_ISDIR)
|
||||||
|
return S_ISDIR(status.st_mode);
|
||||||
|
#elif !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
|
||||||
|
return (status.st_mode & S_IFMT) == S_IFDIR;
|
||||||
|
#else
|
||||||
|
static_assert(false, "NO POSIX stat() support.");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// http://en.cppreference.com/w/cpp/filesystem/is_directory
|
||||||
|
inline bool is_directory(StringPiece path, std::error_code& ec) noexcept {
|
||||||
|
return is_directory(status(path, ec));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// http://en.cppreference.com/w/cpp/filesystem/file_size
|
||||||
|
inline std::uintmax_t file_size(
|
||||||
|
StringPiece path,
|
||||||
|
std::error_code& ec) noexcept {
|
||||||
|
auto stat = status(path, ec);
|
||||||
|
if (ec) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!is_regular_file(stat)) {
|
||||||
|
ec.assign(ENOTSUP, std::generic_category());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ec.clear();
|
||||||
|
return stat.st_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiler hints to indicate the fast path of an "if" branch: whether
|
||||||
|
* the if condition is likely to be true or false.
|
||||||
|
*
|
||||||
|
* @author Tudor Bosman (tudorb@fb.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#undef LIKELY
|
||||||
|
#undef UNLIKELY
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && __GNUC__ >= 4
|
||||||
|
#define LIKELY(x) (__builtin_expect((x), 1))
|
||||||
|
#define UNLIKELY(x) (__builtin_expect((x), 0))
|
||||||
|
#else
|
||||||
|
#define LIKELY(x) (x)
|
||||||
|
#define UNLIKELY(x) (x)
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A subset of `folly/Range.h`.
|
||||||
|
* All code copied verbatiam modulo formatting
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "utils/Likely.h"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstring>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace pzstd {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
/*
|
||||||
|
*Use IsCharPointer<T>::type to enable const char* or char*.
|
||||||
|
*Use IsCharPointer<T>::const_type to enable only const char*.
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
struct IsCharPointer {};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct IsCharPointer<char*> {
|
||||||
|
typedef int type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct IsCharPointer<const char*> {
|
||||||
|
typedef int const_type;
|
||||||
|
typedef int type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename Iter>
|
||||||
|
class Range {
|
||||||
|
Iter b_;
|
||||||
|
Iter e_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using size_type = std::size_t;
|
||||||
|
using iterator = Iter;
|
||||||
|
using const_iterator = Iter;
|
||||||
|
using value_type = typename std::remove_reference<
|
||||||
|
typename std::iterator_traits<Iter>::reference>::type;
|
||||||
|
using reference = typename std::iterator_traits<Iter>::reference;
|
||||||
|
|
||||||
|
constexpr Range() : b_(), e_() {}
|
||||||
|
constexpr Range(Iter begin, Iter end) : b_(begin), e_(end) {}
|
||||||
|
|
||||||
|
constexpr Range(Iter begin, size_type size) : b_(begin), e_(begin + size) {}
|
||||||
|
|
||||||
|
template <class T = Iter, typename detail::IsCharPointer<T>::type = 0>
|
||||||
|
/* implicit */ Range(Iter str) : b_(str), e_(str + std::strlen(str)) {}
|
||||||
|
|
||||||
|
template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
|
||||||
|
/* implicit */ Range(const std::string& str)
|
||||||
|
: b_(str.data()), e_(b_ + str.size()) {}
|
||||||
|
|
||||||
|
// Allow implicit conversion from Range<From> to Range<To> if From is
|
||||||
|
// implicitly convertible to To.
|
||||||
|
template <
|
||||||
|
class OtherIter,
|
||||||
|
typename std::enable_if<
|
||||||
|
(!std::is_same<Iter, OtherIter>::value &&
|
||||||
|
std::is_convertible<OtherIter, Iter>::value),
|
||||||
|
int>::type = 0>
|
||||||
|
constexpr /* implicit */ Range(const Range<OtherIter>& other)
|
||||||
|
: b_(other.begin()), e_(other.end()) {}
|
||||||
|
|
||||||
|
Range(const Range&) = default;
|
||||||
|
Range(Range&&) = default;
|
||||||
|
|
||||||
|
Range& operator=(const Range&) & = default;
|
||||||
|
Range& operator=(Range&&) & = default;
|
||||||
|
|
||||||
|
constexpr size_type size() const {
|
||||||
|
return e_ - b_;
|
||||||
|
}
|
||||||
|
bool empty() const {
|
||||||
|
return b_ == e_;
|
||||||
|
}
|
||||||
|
Iter data() const {
|
||||||
|
return b_;
|
||||||
|
}
|
||||||
|
Iter begin() const {
|
||||||
|
return b_;
|
||||||
|
}
|
||||||
|
Iter end() const {
|
||||||
|
return e_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void advance(size_type n) {
|
||||||
|
if (UNLIKELY(n > size())) {
|
||||||
|
throw std::out_of_range("index out of range");
|
||||||
|
}
|
||||||
|
b_ += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void subtract(size_type n) {
|
||||||
|
if (UNLIKELY(n > size())) {
|
||||||
|
throw std::out_of_range("index out of range");
|
||||||
|
}
|
||||||
|
e_ -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
Range subpiece(size_type first, size_type length = std::string::npos) const {
|
||||||
|
if (UNLIKELY(first > size())) {
|
||||||
|
throw std::out_of_range("index out of range");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Range(b_ + first, std::min(length, size() - first));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using ByteRange = Range<const unsigned char*>;
|
||||||
|
using MutableByteRange = Range<unsigned char*>;
|
||||||
|
using StringPiece = Range<const char*>;
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace pzstd {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dismissable scope guard.
|
||||||
|
* `Function` must be callable and take no parameters.
|
||||||
|
* Unless `dissmiss()` is called, the callable is executed upon destruction of
|
||||||
|
* `ScopeGuard`.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* auto guard = makeScopeGuard([&] { cleanup(); });
|
||||||
|
*/
|
||||||
|
template <typename Function>
|
||||||
|
class ScopeGuard {
|
||||||
|
Function function;
|
||||||
|
bool dismissed;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ScopeGuard(Function&& function)
|
||||||
|
: function(std::move(function)), dismissed(false) {}
|
||||||
|
|
||||||
|
void dismiss() {
|
||||||
|
dismissed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ScopeGuard() noexcept {
|
||||||
|
if (!dismissed) {
|
||||||
|
function();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Creates a scope guard from `function`.
|
||||||
|
template <typename Function>
|
||||||
|
ScopeGuard<Function> makeScopeGuard(Function&& function) {
|
||||||
|
return ScopeGuard<Function>(std::forward<Function>(function));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "utils/WorkQueue.h"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <functional>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace pzstd {
|
||||||
|
/// A simple thread pool that pulls tasks off its queue in FIFO order.
|
||||||
|
class ThreadPool {
|
||||||
|
std::vector<std::thread> threads_;
|
||||||
|
|
||||||
|
WorkQueue<std::function<void()>> tasks_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructs a thread pool with `numThreads` threads.
|
||||||
|
explicit ThreadPool(std::size_t numThreads) {
|
||||||
|
threads_.reserve(numThreads);
|
||||||
|
for (std::size_t i = 0; i < numThreads; ++i) {
|
||||||
|
threads_.emplace_back([&] {
|
||||||
|
std::function<void()> task;
|
||||||
|
while (tasks_.pop(task)) {
|
||||||
|
task();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finishes all tasks currently in the queue.
|
||||||
|
~ThreadPool() {
|
||||||
|
tasks_.finish();
|
||||||
|
for (auto& thread : threads_) {
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds `task` to the queue of tasks to execute. Since `task` is a
|
||||||
|
* `std::function<>`, it cannot be a move only type. So any lambda passed must
|
||||||
|
* not capture move only types (like `std::unique_ptr`).
|
||||||
|
*
|
||||||
|
* @param task The task to execute.
|
||||||
|
*/
|
||||||
|
void add(std::function<void()> task) {
|
||||||
|
tasks_.push(std::move(task));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "utils/Buffer.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <functional>
|
||||||
|
#include <mutex>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
namespace pzstd {
|
||||||
|
|
||||||
|
/// Unbounded thread-safe work queue.
|
||||||
|
template <typename T>
|
||||||
|
class WorkQueue {
|
||||||
|
// Protects all member variable access
|
||||||
|
std::mutex mutex_;
|
||||||
|
std::condition_variable readerCv_;
|
||||||
|
std::condition_variable writerCv_;
|
||||||
|
|
||||||
|
std::queue<T> queue_;
|
||||||
|
bool done_;
|
||||||
|
std::size_t maxSize_;
|
||||||
|
|
||||||
|
// Must have lock to call this function
|
||||||
|
bool full() const {
|
||||||
|
if (maxSize_ == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return queue_.size() >= maxSize_;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs an empty work queue with an optional max size.
|
||||||
|
* If `maxSize == 0` the queue size is unbounded.
|
||||||
|
*
|
||||||
|
* @param maxSize The maximum allowed size of the work queue.
|
||||||
|
*/
|
||||||
|
WorkQueue(std::size_t maxSize = 0) : done_(false), maxSize_(maxSize) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push an item onto the work queue. Notify a single thread that work is
|
||||||
|
* available. If `finish()` has been called, do nothing and return false.
|
||||||
|
*
|
||||||
|
* @param item Item to push onto the queue.
|
||||||
|
* @returns True upon success, false if `finish()` has been called. An
|
||||||
|
* item was pushed iff `push()` returns true.
|
||||||
|
*/
|
||||||
|
bool push(T item) {
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(mutex_);
|
||||||
|
while (full() && !done_) {
|
||||||
|
writerCv_.wait(lock);
|
||||||
|
}
|
||||||
|
if (done_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
queue_.push(std::move(item));
|
||||||
|
}
|
||||||
|
readerCv_.notify_one();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to pop an item off the work queue. It will block until data is
|
||||||
|
* available or `finish()` has been called.
|
||||||
|
*
|
||||||
|
* @param[out] item If `pop` returns `true`, it contains the popped item.
|
||||||
|
* If `pop` returns `false`, it is unmodified.
|
||||||
|
* @returns True upon success. False if the queue is empty and
|
||||||
|
* `finish()` has been called.
|
||||||
|
*/
|
||||||
|
bool pop(T& item) {
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(mutex_);
|
||||||
|
while (queue_.empty() && !done_) {
|
||||||
|
readerCv_.wait(lock);
|
||||||
|
}
|
||||||
|
if (queue_.empty()) {
|
||||||
|
assert(done_);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
item = std::move(queue_.front());
|
||||||
|
queue_.pop();
|
||||||
|
}
|
||||||
|
writerCv_.notify_one();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the maximum queue size. If `maxSize == 0` then it is unbounded.
|
||||||
|
*
|
||||||
|
* @param maxSize The new maximum queue size.
|
||||||
|
*/
|
||||||
|
void setMaxSize(std::size_t maxSize) {
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
maxSize_ = maxSize;
|
||||||
|
}
|
||||||
|
writerCv_.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Promise that `push()` won't be called again, so once the queue is empty
|
||||||
|
* there will never any more work.
|
||||||
|
*/
|
||||||
|
void finish() {
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
assert(!done_);
|
||||||
|
done_ = true;
|
||||||
|
}
|
||||||
|
readerCv_.notify_all();
|
||||||
|
writerCv_.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Blocks until `finish()` has been called (but the queue may not be empty).
|
||||||
|
void waitUntilFinished() {
|
||||||
|
std::unique_lock<std::mutex> lock(mutex_);
|
||||||
|
while (!done_) {
|
||||||
|
readerCv_.wait(lock);
|
||||||
|
// If we were woken by a push, we need to wake a thread waiting on pop().
|
||||||
|
if (!done_) {
|
||||||
|
lock.unlock();
|
||||||
|
readerCv_.notify_one();
|
||||||
|
lock.lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Work queue for `Buffer`s that knows the total number of bytes in the queue.
|
||||||
|
class BufferWorkQueue {
|
||||||
|
WorkQueue<Buffer> queue_;
|
||||||
|
std::atomic<std::size_t> size_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BufferWorkQueue(std::size_t maxSize = 0) : queue_(maxSize), size_(0) {}
|
||||||
|
|
||||||
|
void push(Buffer buffer) {
|
||||||
|
size_.fetch_add(buffer.size());
|
||||||
|
queue_.push(std::move(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pop(Buffer& buffer) {
|
||||||
|
bool result = queue_.pop(buffer);
|
||||||
|
if (result) {
|
||||||
|
size_.fetch_sub(buffer.size());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMaxSize(std::size_t maxSize) {
|
||||||
|
queue_.setMaxSize(maxSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void finish() {
|
||||||
|
queue_.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocks until `finish()` has been called.
|
||||||
|
*
|
||||||
|
* @returns The total number of bytes of all the `Buffer`s currently in the
|
||||||
|
* queue.
|
||||||
|
*/
|
||||||
|
std::size_t size() {
|
||||||
|
queue_.waitUntilFinished();
|
||||||
|
return size_.load();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#include "utils/Buffer.h"
|
||||||
|
#include "utils/Range.h"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
using namespace pzstd;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void deleter(const unsigned char* buf) {
|
||||||
|
delete[] buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Buffer, Constructors) {
|
||||||
|
Buffer empty;
|
||||||
|
EXPECT_TRUE(empty.empty());
|
||||||
|
EXPECT_EQ(0, empty.size());
|
||||||
|
|
||||||
|
Buffer sized(5);
|
||||||
|
EXPECT_FALSE(sized.empty());
|
||||||
|
EXPECT_EQ(5, sized.size());
|
||||||
|
|
||||||
|
Buffer moved(std::move(sized));
|
||||||
|
EXPECT_FALSE(sized.empty());
|
||||||
|
EXPECT_EQ(5, sized.size());
|
||||||
|
|
||||||
|
Buffer assigned;
|
||||||
|
assigned = std::move(moved);
|
||||||
|
EXPECT_FALSE(sized.empty());
|
||||||
|
EXPECT_EQ(5, sized.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Buffer, BufferManagement) {
|
||||||
|
std::shared_ptr<unsigned char> buf(new unsigned char[10], deleter);
|
||||||
|
{
|
||||||
|
Buffer acquired(buf, MutableByteRange(buf.get(), buf.get() + 10));
|
||||||
|
EXPECT_EQ(2, buf.use_count());
|
||||||
|
Buffer moved(std::move(acquired));
|
||||||
|
EXPECT_EQ(2, buf.use_count());
|
||||||
|
Buffer assigned;
|
||||||
|
assigned = std::move(moved);
|
||||||
|
EXPECT_EQ(2, buf.use_count());
|
||||||
|
|
||||||
|
Buffer split = assigned.splitAt(5);
|
||||||
|
EXPECT_EQ(3, buf.use_count());
|
||||||
|
|
||||||
|
split.advance(1);
|
||||||
|
assigned.subtract(1);
|
||||||
|
EXPECT_EQ(3, buf.use_count());
|
||||||
|
}
|
||||||
|
EXPECT_EQ(1, buf.use_count());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Buffer, Modifiers) {
|
||||||
|
Buffer buf(10);
|
||||||
|
{
|
||||||
|
unsigned char i = 0;
|
||||||
|
for (auto& byte : buf.range()) {
|
||||||
|
byte = i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto prefix = buf.splitAt(2);
|
||||||
|
|
||||||
|
ASSERT_EQ(2, prefix.size());
|
||||||
|
EXPECT_EQ(0, *prefix.data());
|
||||||
|
|
||||||
|
ASSERT_EQ(8, buf.size());
|
||||||
|
EXPECT_EQ(2, *buf.data());
|
||||||
|
|
||||||
|
buf.advance(2);
|
||||||
|
EXPECT_EQ(4, *buf.data());
|
||||||
|
|
||||||
|
EXPECT_EQ(9, *(buf.range().end() - 1));
|
||||||
|
|
||||||
|
buf.subtract(2);
|
||||||
|
EXPECT_EQ(7, *(buf.range().end() - 1));
|
||||||
|
|
||||||
|
EXPECT_EQ(4, buf.size());
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# ##########################################################################
|
||||||
|
# Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This source code is licensed under the BSD-style license found in the
|
||||||
|
# LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
# of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
# ##########################################################################
|
||||||
|
|
||||||
|
# Define *.exe as extension for Windows systems
|
||||||
|
ifneq (,$(filter Windows%,$(OS)))
|
||||||
|
EXT =.exe
|
||||||
|
else
|
||||||
|
EXT =
|
||||||
|
endif
|
||||||
|
|
||||||
|
PZSTDDIR = ../..
|
||||||
|
|
||||||
|
# Set GTEST_INC and GTEST_LIB to work with your install of gtest
|
||||||
|
GTEST_INC ?= -isystem $(PZSTDDIR)/googletest/googletest/include
|
||||||
|
GTEST_LIB ?= -L $(PZSTDDIR)/googletest/build/googlemock/gtest
|
||||||
|
|
||||||
|
CPPFLAGS = -I$(PZSTDDIR) $(GTEST_INC) $(GTEST_LIB)
|
||||||
|
CXXFLAGS ?= -O3
|
||||||
|
CXXFLAGS += -std=c++11
|
||||||
|
CXXFLAGS += $(MOREFLAGS)
|
||||||
|
FLAGS = $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS)
|
||||||
|
|
||||||
|
%: %.cpp
|
||||||
|
$(CXX) $(FLAGS) $^ -o $@$(EXT) -lgtest -lgtest_main -lpthread
|
||||||
|
|
||||||
|
.PHONY: test clean
|
||||||
|
|
||||||
|
test: BufferTest RangeTest ScopeGuardTest ThreadPoolTest WorkQueueTest
|
||||||
|
@./BufferTest$(EXT)
|
||||||
|
@./RangeTest$(EXT)
|
||||||
|
@./ScopeGuardTest$(EXT)
|
||||||
|
@./ThreadPoolTest$(EXT)
|
||||||
|
@./WorkQueueTest$(EXT)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f BufferTest RangeTest ScopeGuardTest ThreadPoolTest WorkQueueTest
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#include "utils/Range.h"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace pzstd;
|
||||||
|
|
||||||
|
// Range is directly copied from folly.
|
||||||
|
// Just some sanity tests to make sure everything seems to work.
|
||||||
|
|
||||||
|
TEST(Range, Constructors) {
|
||||||
|
StringPiece empty;
|
||||||
|
EXPECT_TRUE(empty.empty());
|
||||||
|
EXPECT_EQ(0, empty.size());
|
||||||
|
|
||||||
|
std::string str = "hello";
|
||||||
|
{
|
||||||
|
Range<std::string::const_iterator> piece(str.begin(), str.end());
|
||||||
|
EXPECT_EQ(5, piece.size());
|
||||||
|
EXPECT_EQ('h', *piece.data());
|
||||||
|
EXPECT_EQ('o', *(piece.end() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
StringPiece piece(str.data(), str.size());
|
||||||
|
EXPECT_EQ(5, piece.size());
|
||||||
|
EXPECT_EQ('h', *piece.data());
|
||||||
|
EXPECT_EQ('o', *(piece.end() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
StringPiece piece(str);
|
||||||
|
EXPECT_EQ(5, piece.size());
|
||||||
|
EXPECT_EQ('h', *piece.data());
|
||||||
|
EXPECT_EQ('o', *(piece.end() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
StringPiece piece(str.c_str());
|
||||||
|
EXPECT_EQ(5, piece.size());
|
||||||
|
EXPECT_EQ('h', *piece.data());
|
||||||
|
EXPECT_EQ('o', *(piece.end() - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Range, Modifiers) {
|
||||||
|
StringPiece range("hello world");
|
||||||
|
ASSERT_EQ(11, range.size());
|
||||||
|
|
||||||
|
{
|
||||||
|
auto hello = range.subpiece(0, 5);
|
||||||
|
EXPECT_EQ(5, hello.size());
|
||||||
|
EXPECT_EQ('h', *hello.data());
|
||||||
|
EXPECT_EQ('o', *(hello.end() - 1));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto hello = range;
|
||||||
|
hello.subtract(6);
|
||||||
|
EXPECT_EQ(5, hello.size());
|
||||||
|
EXPECT_EQ('h', *hello.data());
|
||||||
|
EXPECT_EQ('o', *(hello.end() - 1));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto world = range;
|
||||||
|
world.advance(6);
|
||||||
|
EXPECT_EQ(5, world.size());
|
||||||
|
EXPECT_EQ('w', *world.data());
|
||||||
|
EXPECT_EQ('d', *(world.end() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string expected = "hello world";
|
||||||
|
EXPECT_EQ(expected, std::string(range.begin(), range.end()));
|
||||||
|
EXPECT_EQ(expected, std::string(range.data(), range.size()));
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#include "utils/ScopeGuard.h"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
using namespace pzstd;
|
||||||
|
|
||||||
|
TEST(ScopeGuard, Dismiss) {
|
||||||
|
{
|
||||||
|
auto guard = makeScopeGuard([&] { EXPECT_TRUE(false); });
|
||||||
|
guard.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ScopeGuard, Executes) {
|
||||||
|
bool executed = false;
|
||||||
|
{
|
||||||
|
auto guard = makeScopeGuard([&] { executed = true; });
|
||||||
|
}
|
||||||
|
EXPECT_TRUE(executed);
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#include "utils/ThreadPool.h"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <atomic>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace pzstd;
|
||||||
|
|
||||||
|
TEST(ThreadPool, Ordering) {
|
||||||
|
std::vector<int> results;
|
||||||
|
|
||||||
|
{
|
||||||
|
ThreadPool executor(1);
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
executor.add([ &results, i ] { results.push_back(i); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
EXPECT_EQ(i, results[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ThreadPool, AllJobsFinished) {
|
||||||
|
std::atomic<unsigned> numFinished{0};
|
||||||
|
std::atomic<bool> start{false};
|
||||||
|
{
|
||||||
|
ThreadPool executor(5);
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
executor.add([ &numFinished, &start ] {
|
||||||
|
while (!start.load()) {
|
||||||
|
// spin
|
||||||
|
}
|
||||||
|
++numFinished;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
start.store(true);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(10, numFinished.load());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ThreadPool, AddJobWhileJoining) {
|
||||||
|
std::atomic<bool> done{false};
|
||||||
|
{
|
||||||
|
ThreadPool executor(1);
|
||||||
|
executor.add([&executor, &done] {
|
||||||
|
while (!done.load()) {
|
||||||
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
|
// Sleep for a second to be sure that we are joining
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
executor.add([] {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
done.store(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,262 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
#include "utils/Buffer.h"
|
||||||
|
#include "utils/WorkQueue.h"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace pzstd;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct Popper {
|
||||||
|
WorkQueue<int>* queue;
|
||||||
|
int* results;
|
||||||
|
std::mutex* mutex;
|
||||||
|
|
||||||
|
void operator()() {
|
||||||
|
int result;
|
||||||
|
while (queue->pop(result)) {
|
||||||
|
std::lock_guard<std::mutex> lock(*mutex);
|
||||||
|
results[result] = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WorkQueue, SingleThreaded) {
|
||||||
|
WorkQueue<int> queue;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
queue.push(5);
|
||||||
|
EXPECT_TRUE(queue.pop(result));
|
||||||
|
EXPECT_EQ(5, result);
|
||||||
|
|
||||||
|
queue.push(1);
|
||||||
|
queue.push(2);
|
||||||
|
EXPECT_TRUE(queue.pop(result));
|
||||||
|
EXPECT_EQ(1, result);
|
||||||
|
EXPECT_TRUE(queue.pop(result));
|
||||||
|
EXPECT_EQ(2, result);
|
||||||
|
|
||||||
|
queue.push(1);
|
||||||
|
queue.push(2);
|
||||||
|
queue.finish();
|
||||||
|
EXPECT_TRUE(queue.pop(result));
|
||||||
|
EXPECT_EQ(1, result);
|
||||||
|
EXPECT_TRUE(queue.pop(result));
|
||||||
|
EXPECT_EQ(2, result);
|
||||||
|
EXPECT_FALSE(queue.pop(result));
|
||||||
|
|
||||||
|
queue.waitUntilFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WorkQueue, SPSC) {
|
||||||
|
WorkQueue<int> queue;
|
||||||
|
const int max = 100;
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
queue.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::thread thread([ &queue, max ] {
|
||||||
|
int result;
|
||||||
|
for (int i = 0;; ++i) {
|
||||||
|
if (!queue.pop(result)) {
|
||||||
|
EXPECT_EQ(i, max);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
EXPECT_EQ(i, result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
std::this_thread::yield();
|
||||||
|
for (int i = 10; i < max; ++i) {
|
||||||
|
queue.push(i);
|
||||||
|
}
|
||||||
|
queue.finish();
|
||||||
|
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WorkQueue, SPMC) {
|
||||||
|
WorkQueue<int> queue;
|
||||||
|
std::vector<int> results(50, -1);
|
||||||
|
std::mutex mutex;
|
||||||
|
std::vector<std::thread> threads;
|
||||||
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
threads.emplace_back(Popper{&queue, results.data(), &mutex});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 50; ++i) {
|
||||||
|
queue.push(i);
|
||||||
|
}
|
||||||
|
queue.finish();
|
||||||
|
|
||||||
|
for (auto& thread : threads) {
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 50; ++i) {
|
||||||
|
EXPECT_EQ(i, results[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WorkQueue, MPMC) {
|
||||||
|
WorkQueue<int> queue;
|
||||||
|
std::vector<int> results(100, -1);
|
||||||
|
std::mutex mutex;
|
||||||
|
std::vector<std::thread> popperThreads;
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
popperThreads.emplace_back(Popper{&queue, results.data(), &mutex});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::thread> pusherThreads;
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
auto min = i * 50;
|
||||||
|
auto max = (i + 1) * 50;
|
||||||
|
pusherThreads.emplace_back(
|
||||||
|
[ &queue, min, max ] {
|
||||||
|
for (int i = min; i < max; ++i) {
|
||||||
|
queue.push(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& thread : pusherThreads) {
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
queue.finish();
|
||||||
|
|
||||||
|
for (auto& thread : popperThreads) {
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 100; ++i) {
|
||||||
|
EXPECT_EQ(i, results[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WorkQueue, BoundedSizeWorks) {
|
||||||
|
WorkQueue<int> queue(1);
|
||||||
|
int result;
|
||||||
|
queue.push(5);
|
||||||
|
queue.pop(result);
|
||||||
|
queue.push(5);
|
||||||
|
queue.pop(result);
|
||||||
|
queue.push(5);
|
||||||
|
queue.finish();
|
||||||
|
queue.pop(result);
|
||||||
|
EXPECT_EQ(5, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WorkQueue, BoundedSizePushAfterFinish) {
|
||||||
|
WorkQueue<int> queue(1);
|
||||||
|
int result;
|
||||||
|
queue.push(5);
|
||||||
|
std::thread pusher([&queue] {
|
||||||
|
queue.push(6);
|
||||||
|
});
|
||||||
|
// Dirtily try and make sure that pusher has run.
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
queue.finish();
|
||||||
|
EXPECT_TRUE(queue.pop(result));
|
||||||
|
EXPECT_EQ(5, result);
|
||||||
|
EXPECT_FALSE(queue.pop(result));
|
||||||
|
|
||||||
|
pusher.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WorkQueue, SetMaxSize) {
|
||||||
|
WorkQueue<int> queue(2);
|
||||||
|
int result;
|
||||||
|
queue.push(5);
|
||||||
|
queue.push(6);
|
||||||
|
queue.setMaxSize(1);
|
||||||
|
std::thread pusher([&queue] {
|
||||||
|
queue.push(7);
|
||||||
|
});
|
||||||
|
// Dirtily try and make sure that pusher has run.
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
queue.finish();
|
||||||
|
EXPECT_TRUE(queue.pop(result));
|
||||||
|
EXPECT_EQ(5, result);
|
||||||
|
EXPECT_TRUE(queue.pop(result));
|
||||||
|
EXPECT_EQ(6, result);
|
||||||
|
EXPECT_FALSE(queue.pop(result));
|
||||||
|
|
||||||
|
pusher.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WorkQueue, BoundedSizeMPMC) {
|
||||||
|
WorkQueue<int> queue(10);
|
||||||
|
std::vector<int> results(200, -1);
|
||||||
|
std::mutex mutex;
|
||||||
|
std::vector<std::thread> popperThreads;
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
popperThreads.emplace_back(Popper{&queue, results.data(), &mutex});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::thread> pusherThreads;
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
auto min = i * 100;
|
||||||
|
auto max = (i + 1) * 100;
|
||||||
|
pusherThreads.emplace_back(
|
||||||
|
[ &queue, min, max ] {
|
||||||
|
for (int i = min; i < max; ++i) {
|
||||||
|
queue.push(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& thread : pusherThreads) {
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
queue.finish();
|
||||||
|
|
||||||
|
for (auto& thread : popperThreads) {
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 200; ++i) {
|
||||||
|
EXPECT_EQ(i, results[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BufferWorkQueue, SizeCalculatedCorrectly) {
|
||||||
|
{
|
||||||
|
BufferWorkQueue queue;
|
||||||
|
queue.finish();
|
||||||
|
EXPECT_EQ(0, queue.size());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
BufferWorkQueue queue;
|
||||||
|
queue.push(Buffer(10));
|
||||||
|
queue.finish();
|
||||||
|
EXPECT_EQ(10, queue.size());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
BufferWorkQueue queue;
|
||||||
|
queue.push(Buffer(10));
|
||||||
|
queue.push(Buffer(5));
|
||||||
|
queue.finish();
|
||||||
|
EXPECT_EQ(15, queue.size());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
BufferWorkQueue queue;
|
||||||
|
queue.push(Buffer(10));
|
||||||
|
queue.push(Buffer(5));
|
||||||
|
queue.finish();
|
||||||
|
Buffer buffer;
|
||||||
|
queue.pop(buffer);
|
||||||
|
EXPECT_EQ(5, queue.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-6
@@ -55,20 +55,21 @@ streaming_decompression : streaming_decompression.c
|
|||||||
clean:
|
clean:
|
||||||
@rm -f core *.o tmp* result* *.zst \
|
@rm -f core *.o tmp* result* *.zst \
|
||||||
simple_compression simple_decompression \
|
simple_compression simple_decompression \
|
||||||
dictionary_compression dictionary_decompression \
|
dictionary_compression dictionary_decompression \
|
||||||
streaming_compression streaming_decompression
|
streaming_compression streaming_decompression
|
||||||
@echo Cleaning completed
|
@echo Cleaning completed
|
||||||
|
|
||||||
test: all
|
test: all
|
||||||
cp README.md tmp
|
cp README.md tmp
|
||||||
|
cp Makefile tmp2
|
||||||
@echo starting simple compression
|
@echo starting simple compression
|
||||||
./simple_compression tmp
|
./simple_compression tmp
|
||||||
./simple_decompression tmp.zst
|
./simple_decompression tmp.zst
|
||||||
./streaming_decompression tmp.zst
|
./streaming_decompression tmp.zst > /dev/null
|
||||||
@echo starting streaming compression
|
@echo starting streaming compression
|
||||||
./streaming_compression tmp
|
./streaming_compression tmp
|
||||||
./streaming_decompression tmp.zst
|
./streaming_decompression tmp.zst > /dev/null
|
||||||
@echo starting dictionary compression
|
@echo starting dictionary compression
|
||||||
./dictionary_compression tmp README.md
|
./dictionary_compression tmp2 tmp README.md
|
||||||
./dictionary_decompression tmp.zst README.md
|
./dictionary_decompression tmp2.zst tmp.zst README.md
|
||||||
@echo tests completed
|
@echo tests completed
|
||||||
|
|||||||
+18
-5
@@ -1,18 +1,31 @@
|
|||||||
Zstandard library : usage examples
|
Zstandard library : usage examples
|
||||||
==================================
|
==================================
|
||||||
|
|
||||||
- [Simple compression](simple_compression.c)
|
- [Simple compression](simple_compression.c) :
|
||||||
Compress a single file.
|
Compress a single file.
|
||||||
Introduces usage of : `ZSTD_compress()`
|
Introduces usage of : `ZSTD_compress()`
|
||||||
|
|
||||||
- [Simple decompression](simple_decompression.c)
|
- [Simple decompression](simple_decompression.c) :
|
||||||
Decompress a single file compressed by zstd.
|
Decompress a single file.
|
||||||
|
Only compatible with simple compression.
|
||||||
|
Result remains in memory.
|
||||||
Introduces usage of : `ZSTD_decompress()`
|
Introduces usage of : `ZSTD_decompress()`
|
||||||
|
|
||||||
- [Dictionary compression](dictionary_compression.c)
|
- [Streaming compression](streaming_compression.c) :
|
||||||
|
Compress a single file.
|
||||||
|
Introduces usage of : `ZSTD_compressStream()`
|
||||||
|
|
||||||
|
- [Streaming decompression](streaming_decompression.c) :
|
||||||
|
Decompress a single file compressed by zstd.
|
||||||
|
Compatible with both simple and streaming compression.
|
||||||
|
Result is sent to stdout.
|
||||||
|
Introduces usage of : `ZSTD_decompressStream()`
|
||||||
|
|
||||||
|
- [Dictionary compression](dictionary_compression.c) :
|
||||||
Compress multiple files using the same dictionary.
|
Compress multiple files using the same dictionary.
|
||||||
Introduces usage of : `ZSTD_createCDict()` and `ZSTD_compress_usingCDict()`
|
Introduces usage of : `ZSTD_createCDict()` and `ZSTD_compress_usingCDict()`
|
||||||
|
|
||||||
- [Dictionary decompression](dictionary_decompression.c)
|
- [Dictionary decompression](dictionary_decompression.c) :
|
||||||
Decompress multiple files using the same dictionary.
|
Decompress multiple files using the same dictionary.
|
||||||
|
Result remains in memory.
|
||||||
Introduces usage of : `ZSTD_createDDict()` and `ZSTD_decompress_usingDDict()`
|
Introduces usage of : `ZSTD_createDDict()` and `ZSTD_decompress_usingDDict()`
|
||||||
|
|||||||
@@ -1,27 +1,11 @@
|
|||||||
/*
|
/**
|
||||||
Dictionary compression
|
* Copyright 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Educational program using zstd library
|
* All rights reserved.
|
||||||
Copyright (C) Yann Collet 2016
|
*
|
||||||
|
* This source code is licensed under the license found in the
|
||||||
|
* LICENSE-examples file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h> // malloc, exit
|
#include <stdlib.h> // malloc, exit
|
||||||
#include <stdio.h> // printf
|
#include <stdio.h> // printf
|
||||||
@@ -89,12 +73,12 @@ static void saveFile_orDie(const char* fileName, const void* buff, size_t buffSi
|
|||||||
|
|
||||||
/* createDict() :
|
/* createDict() :
|
||||||
`dictFileName` is supposed to have been created using `zstd --train` */
|
`dictFileName` is supposed to have been created using `zstd --train` */
|
||||||
static ZSTD_CDict* createCDict_orDie(const char* dictFileName)
|
static ZSTD_CDict* createCDict_orDie(const char* dictFileName, int cLevel)
|
||||||
{
|
{
|
||||||
size_t dictSize;
|
size_t dictSize;
|
||||||
printf("loading dictionary %s \n", dictFileName);
|
printf("loading dictionary %s \n", dictFileName);
|
||||||
void* const dictBuffer = loadFile_orDie(dictFileName, &dictSize);
|
void* const dictBuffer = loadFile_orDie(dictFileName, &dictSize);
|
||||||
ZSTD_CDict* const cdict = ZSTD_createCDict(dictBuffer, dictSize, 3);
|
ZSTD_CDict* const cdict = ZSTD_createCDict(dictBuffer, dictSize, cLevel);
|
||||||
if (!cdict) {
|
if (!cdict) {
|
||||||
fprintf(stderr, "ZSTD_createCDict error \n");
|
fprintf(stderr, "ZSTD_createCDict error \n");
|
||||||
exit(7);
|
exit(7);
|
||||||
@@ -112,6 +96,7 @@ static void compress(const char* fname, const char* oname, const ZSTD_CDict* cdi
|
|||||||
void* const cBuff = malloc_orDie(cBuffSize);
|
void* const cBuff = malloc_orDie(cBuffSize);
|
||||||
|
|
||||||
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
||||||
|
if (cctx==NULL) { fprintf(stderr, "ZSTD_createCCtx() error \n"); exit(10); }
|
||||||
size_t const cSize = ZSTD_compress_usingCDict(cctx, cBuff, cBuffSize, fBuff, fSize, cdict);
|
size_t const cSize = ZSTD_compress_usingCDict(cctx, cBuff, cBuffSize, fBuff, fSize, cdict);
|
||||||
if (ZSTD_isError(cSize)) {
|
if (ZSTD_isError(cSize)) {
|
||||||
fprintf(stderr, "error compressing %s : %s \n", fname, ZSTD_getErrorName(cSize));
|
fprintf(stderr, "error compressing %s : %s \n", fname, ZSTD_getErrorName(cSize));
|
||||||
@@ -123,7 +108,7 @@ static void compress(const char* fname, const char* oname, const ZSTD_CDict* cdi
|
|||||||
/* success */
|
/* success */
|
||||||
printf("%25s : %6u -> %7u - %s \n", fname, (unsigned)fSize, (unsigned)cSize, oname);
|
printf("%25s : %6u -> %7u - %s \n", fname, (unsigned)fSize, (unsigned)cSize, oname);
|
||||||
|
|
||||||
ZSTD_freeCCtx(cctx);
|
ZSTD_freeCCtx(cctx); /* never fails */
|
||||||
free(fBuff);
|
free(fBuff);
|
||||||
free(cBuff);
|
free(cBuff);
|
||||||
}
|
}
|
||||||
@@ -143,6 +128,7 @@ static char* createOutFilename_orDie(const char* filename)
|
|||||||
int main(int argc, const char** argv)
|
int main(int argc, const char** argv)
|
||||||
{
|
{
|
||||||
const char* const exeName = argv[0];
|
const char* const exeName = argv[0];
|
||||||
|
int const cLevel = 3;
|
||||||
|
|
||||||
if (argc<3) {
|
if (argc<3) {
|
||||||
fprintf(stderr, "wrong arguments\n");
|
fprintf(stderr, "wrong arguments\n");
|
||||||
@@ -153,7 +139,7 @@ int main(int argc, const char** argv)
|
|||||||
|
|
||||||
/* load dictionary only once */
|
/* load dictionary only once */
|
||||||
const char* const dictName = argv[argc-1];
|
const char* const dictName = argv[argc-1];
|
||||||
ZSTD_CDict* const dictPtr = createCDict_orDie(dictName);
|
ZSTD_CDict* const dictPtr = createCDict_orDie(dictName, cLevel);
|
||||||
|
|
||||||
int u;
|
int u;
|
||||||
for (u=1; u<argc-1; u++) {
|
for (u=1; u<argc-1; u++) {
|
||||||
|
|||||||
@@ -1,27 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
Dictionary decompression
|
* Copyright 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Educational program using zstd library
|
* All rights reserved.
|
||||||
Copyright (C) Yann Collet 2016
|
*
|
||||||
|
* This source code is licensed under the license found in the
|
||||||
|
* LICENSE-examples file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h> // malloc, exit
|
#include <stdlib.h> // malloc, exit
|
||||||
#include <stdio.h> // printf
|
#include <stdio.h> // printf
|
||||||
@@ -96,11 +81,11 @@ static void decompress(const char* fname, const ZSTD_DDict* ddict)
|
|||||||
fprintf(stderr, "%s : original size unknown \n", fname);
|
fprintf(stderr, "%s : original size unknown \n", fname);
|
||||||
exit(6);
|
exit(6);
|
||||||
}
|
}
|
||||||
void* const rBuff = malloc_orDie(rSize);
|
void* const rBuff = malloc_orDie((size_t)rSize);
|
||||||
|
|
||||||
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
|
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
|
||||||
|
if (dctx==NULL) { fprintf(stderr, "ZSTD_createDCtx() error \n"); exit(10); }
|
||||||
size_t const dSize = ZSTD_decompress_usingDDict(dctx, rBuff, rSize, cBuff, cSize, ddict);
|
size_t const dSize = ZSTD_decompress_usingDDict(dctx, rBuff, rSize, cBuff, cSize, ddict);
|
||||||
|
|
||||||
if (dSize != rSize) {
|
if (dSize != rSize) {
|
||||||
fprintf(stderr, "error decoding %s : %s \n", fname, ZSTD_getErrorName(dSize));
|
fprintf(stderr, "error decoding %s : %s \n", fname, ZSTD_getErrorName(dSize));
|
||||||
exit(7);
|
exit(7);
|
||||||
|
|||||||
@@ -1,27 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
Simple compression
|
* Copyright 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Educational program using zstd library
|
* All rights reserved.
|
||||||
Copyright (C) Yann Collet 2016
|
*
|
||||||
|
* This source code is licensed under the license found in the
|
||||||
|
* LICENSE-examples file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h> // malloc, exit
|
#include <stdlib.h> // malloc, exit
|
||||||
#include <stdio.h> // fprintf, perror
|
#include <stdio.h> // fprintf, perror
|
||||||
@@ -68,7 +53,7 @@ static void* loadFile_orDie(const char* fileName, size_t* size)
|
|||||||
fprintf(stderr, "fread: %s : %s \n", fileName, strerror(errno));
|
fprintf(stderr, "fread: %s : %s \n", fileName, strerror(errno));
|
||||||
exit(4);
|
exit(4);
|
||||||
}
|
}
|
||||||
fclose(inFile);
|
fclose(inFile); /* can't fail, read only */
|
||||||
*size = buffSize;
|
*size = buffSize;
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
@@ -116,7 +101,7 @@ static const char* createOutFilename_orDie(const char* filename)
|
|||||||
{
|
{
|
||||||
size_t const inL = strlen(filename);
|
size_t const inL = strlen(filename);
|
||||||
size_t const outL = inL + 5;
|
size_t const outL = inL + 5;
|
||||||
void* outSpace = malloc_orDie(outL);
|
void* const outSpace = malloc_orDie(outL);
|
||||||
memset(outSpace, 0, outL);
|
memset(outSpace, 0, outL);
|
||||||
strcat(outSpace, filename);
|
strcat(outSpace, filename);
|
||||||
strcat(outSpace, ".zst");
|
strcat(outSpace, ".zst");
|
||||||
|
|||||||
@@ -1,27 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
Simple decompression
|
* Copyright 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Educational program using zstd library
|
* All rights reserved.
|
||||||
Copyright (C) Yann Collet 2016
|
*
|
||||||
|
* This source code is licensed under the license found in the
|
||||||
|
* LICENSE-examples file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h> // malloc, exit
|
#include <stdlib.h> // malloc, exit
|
||||||
#include <stdio.h> // printf
|
#include <stdio.h> // printf
|
||||||
@@ -68,7 +53,7 @@ static void* loadFile_X(const char* fileName, size_t* size)
|
|||||||
printf("fread: %s : %s \n", fileName, strerror(errno));
|
printf("fread: %s : %s \n", fileName, strerror(errno));
|
||||||
exit(4);
|
exit(4);
|
||||||
}
|
}
|
||||||
fclose(inFile);
|
fclose(inFile); /* can't fail (read only) */
|
||||||
*size = buffSize;
|
*size = buffSize;
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
@@ -83,7 +68,7 @@ static void decompress(const char* fname)
|
|||||||
printf("%s : original size unknown \n", fname);
|
printf("%s : original size unknown \n", fname);
|
||||||
exit(5);
|
exit(5);
|
||||||
}
|
}
|
||||||
void* const rBuff = malloc_X(rSize);
|
void* const rBuff = malloc_X((size_t)rSize);
|
||||||
|
|
||||||
size_t const dSize = ZSTD_decompress(rBuff, rSize, cBuff, cSize);
|
size_t const dSize = ZSTD_decompress(rBuff, rSize, cBuff, cSize);
|
||||||
|
|
||||||
|
|||||||
@@ -1,27 +1,11 @@
|
|||||||
/*
|
/**
|
||||||
Streaming compression
|
* Copyright 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Educational program using zstd library
|
* All rights reserved.
|
||||||
Copyright (C) Yann Collet 2016
|
*
|
||||||
|
* This source code is licensed under the license found in the
|
||||||
|
* LICENSE-examples file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h> // malloc, exit
|
#include <stdlib.h> // malloc, exit
|
||||||
#include <stdio.h> // fprintf, perror, feof
|
#include <stdio.h> // fprintf, perror, feof
|
||||||
@@ -81,31 +65,34 @@ static void compressFile_orDie(const char* fname, const char* outName, int cLeve
|
|||||||
{
|
{
|
||||||
FILE* const fin = fopen_orDie(fname, "rb");
|
FILE* const fin = fopen_orDie(fname, "rb");
|
||||||
FILE* const fout = fopen_orDie(outName, "wb");
|
FILE* const fout = fopen_orDie(outName, "wb");
|
||||||
size_t const buffInSize = ZSTD_CStreamInSize();;
|
size_t const buffInSize = ZSTD_CStreamInSize(); /* can always read one full block */
|
||||||
void* const buffIn = malloc_orDie(buffInSize);
|
void* const buffIn = malloc_orDie(buffInSize);
|
||||||
size_t const buffOutSize = ZSTD_CStreamOutSize();;
|
size_t const buffOutSize = ZSTD_CStreamOutSize(); /* can always flush a full block */
|
||||||
void* const buffOut = malloc_orDie(buffOutSize);
|
void* const buffOut = malloc_orDie(buffOutSize);
|
||||||
size_t read, toRead = buffInSize;
|
|
||||||
|
|
||||||
ZSTD_CStream* const cstream = ZSTD_createCStream();
|
ZSTD_CStream* const cstream = ZSTD_createCStream();
|
||||||
if (cstream==NULL) { fprintf(stderr, "ZSTD_createCStream() error \n"); exit(10); }
|
if (cstream==NULL) { fprintf(stderr, "ZSTD_createCStream() error \n"); exit(10); }
|
||||||
size_t const initResult = ZSTD_initCStream(cstream, cLevel);
|
size_t const initResult = ZSTD_initCStream(cstream, cLevel);
|
||||||
if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_initCStream() error \n"); exit(11); }
|
if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_initCStream() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); }
|
||||||
|
|
||||||
|
size_t read, toRead = buffInSize;
|
||||||
while( (read = fread_orDie(buffIn, toRead, fin)) ) {
|
while( (read = fread_orDie(buffIn, toRead, fin)) ) {
|
||||||
ZSTD_inBuffer input = { buffIn, read, 0 };
|
ZSTD_inBuffer input = { buffIn, read, 0 };
|
||||||
while (input.pos < input.size) {
|
while (input.pos < input.size) {
|
||||||
ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
|
ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
|
||||||
toRead = ZSTD_compressStream(cstream, &output , &input);
|
toRead = ZSTD_compressStream(cstream, &output , &input); /* toRead is guaranteed to be <= ZSTD_CStreamInSize() */
|
||||||
|
if (ZSTD_isError(toRead)) { fprintf(stderr, "ZSTD_compressStream() error : %s \n", ZSTD_getErrorName(toRead)); exit(12); }
|
||||||
|
if (toRead > buffInSize) toRead = buffInSize; /* Safely handle when `buffInSize` is manually changed to a smaller value */
|
||||||
fwrite_orDie(buffOut, output.pos, fout);
|
fwrite_orDie(buffOut, output.pos, fout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
|
ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
|
||||||
size_t const remainingToFlush = ZSTD_endStream(cstream, &output);
|
size_t const remainingToFlush = ZSTD_endStream(cstream, &output); /* close frame */
|
||||||
if (remainingToFlush) { fprintf(stderr, "not fully flushed"); exit(12); }
|
if (remainingToFlush) { fprintf(stderr, "not fully flushed"); exit(13); }
|
||||||
fwrite_orDie(buffOut, output.pos, fout);
|
fwrite_orDie(buffOut, output.pos, fout);
|
||||||
|
|
||||||
|
ZSTD_freeCStream(cstream);
|
||||||
fclose_orDie(fout);
|
fclose_orDie(fout);
|
||||||
fclose_orDie(fin);
|
fclose_orDie(fin);
|
||||||
free(buffIn);
|
free(buffIn);
|
||||||
|
|||||||
@@ -1,33 +1,16 @@
|
|||||||
/*
|
/**
|
||||||
Streaming compression
|
* Copyright 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Educational program using zstd library
|
* All rights reserved.
|
||||||
Copyright (C) Yann Collet 2016
|
*
|
||||||
|
* This source code is licensed under the license found in the
|
||||||
|
* LICENSE-examples file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h> // malloc, exit
|
#include <stdlib.h> // malloc, exit
|
||||||
#include <stdio.h> // fprintf, perror, feof
|
#include <stdio.h> // fprintf, perror, feof
|
||||||
#include <string.h> // strerror
|
#include <string.h> // strerror
|
||||||
#include <errno.h> // errno
|
#include <errno.h> // errno
|
||||||
#define ZSTD_STATIC_LINKING_ONLY // streaming API defined as "experimental" for the time being
|
|
||||||
#include <zstd.h> // presumes zstd library is installed
|
#include <zstd.h> // presumes zstd library is installed
|
||||||
|
|
||||||
|
|
||||||
@@ -59,6 +42,15 @@ static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file)
|
|||||||
exit(4);
|
exit(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t fwrite_orDie(const void* buffer, size_t sizeToWrite, FILE* file)
|
||||||
|
{
|
||||||
|
size_t const writtenSize = fwrite(buffer, 1, sizeToWrite, file);
|
||||||
|
if (writtenSize == sizeToWrite) return sizeToWrite; /* good */
|
||||||
|
/* error */
|
||||||
|
perror("fwrite");
|
||||||
|
exit(5);
|
||||||
|
}
|
||||||
|
|
||||||
static size_t fclose_orDie(FILE* file)
|
static size_t fclose_orDie(FILE* file)
|
||||||
{
|
{
|
||||||
if (!fclose(file)) return 0;
|
if (!fclose(file)) return 0;
|
||||||
@@ -71,28 +63,31 @@ static size_t fclose_orDie(FILE* file)
|
|||||||
static void decompressFile_orDie(const char* fname)
|
static void decompressFile_orDie(const char* fname)
|
||||||
{
|
{
|
||||||
FILE* const fin = fopen_orDie(fname, "rb");
|
FILE* const fin = fopen_orDie(fname, "rb");
|
||||||
size_t const buffInSize = ZSTD_DStreamInSize();;
|
size_t const buffInSize = ZSTD_DStreamInSize();
|
||||||
void* const buffIn = malloc_orDie(buffInSize);
|
void* const buffIn = malloc_orDie(buffInSize);
|
||||||
size_t const buffOutSize = ZSTD_DStreamOutSize();;
|
FILE* const fout = stdout;
|
||||||
|
size_t const buffOutSize = ZSTD_DStreamOutSize(); /* Guarantee to successfully flush at least one complete compressed block in all circumstances. */
|
||||||
void* const buffOut = malloc_orDie(buffOutSize);
|
void* const buffOut = malloc_orDie(buffOutSize);
|
||||||
size_t read, toRead = buffInSize;
|
|
||||||
|
|
||||||
ZSTD_DStream* const dstream = ZSTD_createDStream();
|
ZSTD_DStream* const dstream = ZSTD_createDStream();
|
||||||
if (dstream==NULL) { fprintf(stderr, "ZSTD_createDStream() error \n"); exit(10); }
|
if (dstream==NULL) { fprintf(stderr, "ZSTD_createDStream() error \n"); exit(10); }
|
||||||
size_t const initResult = ZSTD_initDStream(dstream);
|
size_t const initResult = ZSTD_initDStream(dstream);
|
||||||
if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_initDStream() error \n"); exit(11); }
|
if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_initDStream() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); }
|
||||||
|
|
||||||
while( (read = fread_orDie(buffIn, toRead, fin)) ) {
|
size_t read, toRead = initResult;
|
||||||
|
while ( (read = fread_orDie(buffIn, toRead, fin)) ) {
|
||||||
ZSTD_inBuffer input = { buffIn, read, 0 };
|
ZSTD_inBuffer input = { buffIn, read, 0 };
|
||||||
while (input.pos < input.size) {
|
while (input.pos < input.size) {
|
||||||
ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
|
ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
|
||||||
toRead = ZSTD_decompressStream(dstream, &output , &input);
|
toRead = ZSTD_decompressStream(dstream, &output , &input); /* toRead : size of next compressed block */
|
||||||
/* note : data is just "sinked" into buffOut
|
if (ZSTD_isError(toRead)) { fprintf(stderr, "ZSTD_decompressStream() error : %s \n", ZSTD_getErrorName(toRead)); exit(12); }
|
||||||
a more complete example would write it to disk or stdout */
|
fwrite_orDie(buffOut, output.pos, fout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZSTD_freeDStream(dstream);
|
||||||
fclose_orDie(fin);
|
fclose_orDie(fin);
|
||||||
|
fclose_orDie(fout);
|
||||||
free(buffIn);
|
free(buffIn);
|
||||||
free(buffOut);
|
free(buffOut);
|
||||||
}
|
}
|
||||||
@@ -104,14 +99,12 @@ int main(int argc, const char** argv)
|
|||||||
const char* const inFilename = argv[1];
|
const char* const inFilename = argv[1];
|
||||||
|
|
||||||
if (argc!=2) {
|
if (argc!=2) {
|
||||||
printf("wrong arguments\n");
|
fprintf(stderr, "wrong arguments\n");
|
||||||
printf("usage:\n");
|
fprintf(stderr, "usage:\n");
|
||||||
printf("%s FILE\n", exeName);
|
fprintf(stderr, "%s FILE\n", exeName);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
decompressFile_orDie(inFilename);
|
decompressFile_orDie(inFilename);
|
||||||
printf("%s correctly decoded (in memory). \n", inFilename);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-36
@@ -1,33 +1,10 @@
|
|||||||
# ################################################################
|
# ################################################################
|
||||||
# ZSTD library - Makefile
|
# Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
# Copyright (C) Yann Collet 2015-2016
|
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# BSD license
|
# This source code is licensed under the BSD-style license found in the
|
||||||
|
# LICENSE file in the root directory of this source tree. An additional grant
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# of patent rights can be found in the PATENTS file in the same directory.
|
||||||
# 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 HOLDER 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 numbers
|
# Version numbers
|
||||||
@@ -101,7 +78,7 @@ clean:
|
|||||||
|
|
||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
#make install is validated only for Linux, OSX, kFreeBSD, Hurd and some BSD targets
|
#make install is validated only for Linux, OSX, kFreeBSD, Hurd and some BSD targets
|
||||||
ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU FreeBSD DragonFly))
|
ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU FreeBSD DragonFly NetBSD))
|
||||||
|
|
||||||
libzstd.pc:
|
libzstd.pc:
|
||||||
libzstd.pc: libzstd.pc.in
|
libzstd.pc: libzstd.pc.in
|
||||||
@@ -125,14 +102,14 @@ install: libzstd libzstd.pc
|
|||||||
@echo zstd static and shared library installed
|
@echo zstd static and shared library installed
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
@rm -f $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT)
|
$(RM) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT)
|
||||||
@rm -f $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR)
|
$(RM) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR)
|
||||||
@rm -f $(DESTDIR)$(LIBDIR)/pkgconfig/libzstd.pc
|
$(RM) $(DESTDIR)$(LIBDIR)/pkgconfig/libzstd.pc
|
||||||
@[ -x $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_VER) ] && rm -f $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_VER)
|
$(RM) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_VER)
|
||||||
@[ -f $(DESTDIR)$(LIBDIR)/libzstd.a ] && rm -f $(DESTDIR)$(LIBDIR)/libzstd.a
|
$(RM) $(DESTDIR)$(LIBDIR)/libzstd.a
|
||||||
@[ -f $(DESTDIR)$(INCLUDEDIR)/zstd.h ] && rm -f $(DESTDIR)$(INCLUDEDIR)/zstd.h
|
$(RM) $(DESTDIR)$(INCLUDEDIR)/zstd.h
|
||||||
@[ -f $(DESTDIR)$(INCLUDEDIR)/zbuff.h ] && rm -f $(DESTDIR)$(INCLUDEDIR)/zbuff.h
|
$(RM) $(DESTDIR)$(INCLUDEDIR)/zbuff.h
|
||||||
@[ -f $(DESTDIR)$(INCLUDEDIR)/zdict.h ] && rm -f $(DESTDIR)$(INCLUDEDIR)/zdict.h
|
$(RM) $(DESTDIR)$(INCLUDEDIR)/zdict.h
|
||||||
@echo zstd libraries successfully uninstalled
|
@echo zstd libraries successfully uninstalled
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
zstd - library files
|
Zstandard library files
|
||||||
================================
|
================================
|
||||||
|
|
||||||
The __lib__ directory contains several directories.
|
The __lib__ directory contains several directories.
|
||||||
|
|||||||
+10
-31
@@ -1,35 +1,12 @@
|
|||||||
/* ******************************************************************
|
/**
|
||||||
Error codes and messages
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) 2013-2016, Yann Collet
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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 */
|
/* Note : this module is expected to remain private, do not expose it */
|
||||||
|
|
||||||
#ifndef ERROR_H_MODULE
|
#ifndef ERROR_H_MODULE
|
||||||
@@ -93,6 +70,8 @@ ERR_STATIC const char* ERR_getErrorString(ERR_enum code)
|
|||||||
case PREFIX(no_error): return "No error detected";
|
case PREFIX(no_error): return "No error detected";
|
||||||
case PREFIX(GENERIC): return "Error (generic)";
|
case PREFIX(GENERIC): return "Error (generic)";
|
||||||
case PREFIX(prefix_unknown): return "Unknown frame descriptor";
|
case PREFIX(prefix_unknown): return "Unknown frame descriptor";
|
||||||
|
case PREFIX(version_unsupported): return "Version not supported";
|
||||||
|
case PREFIX(parameter_unknown): return "Unknown parameter type";
|
||||||
case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter";
|
case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter";
|
||||||
case PREFIX(frameParameter_unsupportedBy32bits): return "Frame parameter unsupported in 32-bits mode";
|
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(compressionParameter_unsupported): return "Compression parameter is out of bound";
|
||||||
|
|||||||
+14
-32
@@ -1,35 +1,12 @@
|
|||||||
/* ******************************************************************
|
/**
|
||||||
Error codes list
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) 2016, Yann Collet
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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
|
#ifndef ERROR_PUBLIC_H_MODULE
|
||||||
#define ERROR_PUBLIC_H_MODULE
|
#define ERROR_PUBLIC_H_MODULE
|
||||||
|
|
||||||
@@ -37,14 +14,19 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*===== dependency =====*/
|
||||||
|
#include <stddef.h> /* size_t */
|
||||||
|
|
||||||
/* ****************************************
|
|
||||||
|
/*-****************************************
|
||||||
* error codes list
|
* error codes list
|
||||||
******************************************/
|
******************************************/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ZSTD_error_no_error,
|
ZSTD_error_no_error,
|
||||||
ZSTD_error_GENERIC,
|
ZSTD_error_GENERIC,
|
||||||
ZSTD_error_prefix_unknown,
|
ZSTD_error_prefix_unknown,
|
||||||
|
ZSTD_error_version_unsupported,
|
||||||
|
ZSTD_error_parameter_unknown,
|
||||||
ZSTD_error_frameParameter_unsupported,
|
ZSTD_error_frameParameter_unsupported,
|
||||||
ZSTD_error_frameParameter_unsupportedBy32bits,
|
ZSTD_error_frameParameter_unsupportedBy32bits,
|
||||||
ZSTD_error_compressionParameter_unsupported,
|
ZSTD_error_compressionParameter_unsupported,
|
||||||
|
|||||||
+1
-1
@@ -503,7 +503,7 @@ MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePt
|
|||||||
BIT_flushBits(bitC);
|
BIT_flushBits(bitC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*<===== Decompression =====>*/
|
/* ====== Decompression ====== */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
U16 tableLog;
|
U16 tableLog;
|
||||||
|
|||||||
+14
-16
@@ -42,12 +42,15 @@
|
|||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
||||||
#else
|
#else
|
||||||
# ifdef __GNUC__
|
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
||||||
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
# ifdef __GNUC__
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
# define FORCE_INLINE static inline __attribute__((always_inline))
|
||||||
|
# else
|
||||||
|
# define FORCE_INLINE static inline
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
# define FORCE_INLINE static inline
|
# define FORCE_INLINE static
|
||||||
# endif
|
# endif /* __STDC_VERSION__ */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -68,6 +71,9 @@
|
|||||||
#define FSE_isError ERR_isError
|
#define FSE_isError ERR_isError
|
||||||
#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
|
#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
|
||||||
|
|
||||||
|
/* check and forward error code */
|
||||||
|
#define CHECK_F(f) { size_t const e = f; if (FSE_isError(e)) return e; }
|
||||||
|
|
||||||
|
|
||||||
/* **************************************************************
|
/* **************************************************************
|
||||||
* Complex types
|
* Complex types
|
||||||
@@ -152,7 +158,6 @@ size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned
|
|||||||
position = (position + step) & tableMask;
|
position = (position + step) & tableMask;
|
||||||
while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */
|
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 */
|
if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +174,6 @@ size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef FSE_COMMONDEFS_ONLY
|
#ifndef FSE_COMMONDEFS_ONLY
|
||||||
|
|
||||||
/*-*******************************************************
|
/*-*******************************************************
|
||||||
@@ -234,8 +238,7 @@ FORCE_INLINE size_t FSE_decompress_usingDTable_generic(
|
|||||||
FSE_DState_t state2;
|
FSE_DState_t state2;
|
||||||
|
|
||||||
/* Init */
|
/* Init */
|
||||||
{ size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize); /* replaced last arg by maxCompressed Size */
|
CHECK_F(BIT_initDStream(&bitD, cSrc, cSrcSize));
|
||||||
if (FSE_isError(errorCode)) return errorCode; }
|
|
||||||
|
|
||||||
FSE_initDState(&state1, &bitD, dt);
|
FSE_initDState(&state1, &bitD, dt);
|
||||||
FSE_initDState(&state2, &bitD, dt);
|
FSE_initDState(&state2, &bitD, dt);
|
||||||
@@ -243,7 +246,7 @@ FORCE_INLINE size_t FSE_decompress_usingDTable_generic(
|
|||||||
#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD)
|
#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD)
|
||||||
|
|
||||||
/* 4 symbols per loop */
|
/* 4 symbols per loop */
|
||||||
for ( ; (BIT_reloadDStream(&bitD)==BIT_DStream_unfinished) && (op<olimit) ; op+=4) {
|
for ( ; (BIT_reloadDStream(&bitD)==BIT_DStream_unfinished) & (op<olimit) ; op+=4) {
|
||||||
op[0] = FSE_GETSYMBOL(&state1);
|
op[0] = FSE_GETSYMBOL(&state1);
|
||||||
|
|
||||||
if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
|
if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
|
||||||
@@ -266,18 +269,14 @@ FORCE_INLINE size_t FSE_decompress_usingDTable_generic(
|
|||||||
/* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */
|
/* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */
|
||||||
while (1) {
|
while (1) {
|
||||||
if (op>(omax-2)) return ERROR(dstSize_tooSmall);
|
if (op>(omax-2)) return ERROR(dstSize_tooSmall);
|
||||||
|
|
||||||
*op++ = FSE_GETSYMBOL(&state1);
|
*op++ = FSE_GETSYMBOL(&state1);
|
||||||
|
|
||||||
if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
|
if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
|
||||||
*op++ = FSE_GETSYMBOL(&state2);
|
*op++ = FSE_GETSYMBOL(&state2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op>(omax-2)) return ERROR(dstSize_tooSmall);
|
if (op>(omax-2)) return ERROR(dstSize_tooSmall);
|
||||||
|
|
||||||
*op++ = FSE_GETSYMBOL(&state2);
|
*op++ = FSE_GETSYMBOL(&state2);
|
||||||
|
|
||||||
if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
|
if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
|
||||||
*op++ = FSE_GETSYMBOL(&state1);
|
*op++ = FSE_GETSYMBOL(&state1);
|
||||||
break;
|
break;
|
||||||
@@ -320,8 +319,7 @@ size_t FSE_decompress(void* dst, size_t maxDstSize, const void* cSrc, size_t cSr
|
|||||||
cSrcSize -= NCountLength;
|
cSrcSize -= NCountLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
{ size_t const errorCode = FSE_buildDTable (dt, counting, maxSymbolValue, tableLog);
|
CHECK_F( FSE_buildDTable (dt, counting, maxSymbolValue, tableLog) );
|
||||||
if (FSE_isError(errorCode)) return errorCode; }
|
|
||||||
|
|
||||||
return FSE_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, dt); /* always return, even if it is an error code */
|
return FSE_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, dt); /* always return, even if it is an error code */
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-33
@@ -1,37 +1,12 @@
|
|||||||
/* ******************************************************************
|
/**
|
||||||
mem.h
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
low-level memory access routines
|
* All rights reserved.
|
||||||
Copyright (C) 2013-2015, Yann Collet.
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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
|
#ifndef MEM_H_MODULE
|
||||||
#define MEM_H_MODULE
|
#define MEM_H_MODULE
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -115,7 +115,7 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcp
|
|||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# define FORCE_INLINE static __forceinline
|
# define FORCE_INLINE static __forceinline
|
||||||
#else
|
#else
|
||||||
# if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
||||||
# ifdef __GNUC__
|
# ifdef __GNUC__
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
# define FORCE_INLINE static inline __attribute__((always_inline))
|
||||||
# else
|
# else
|
||||||
|
|||||||
+15
-28
@@ -1,33 +1,20 @@
|
|||||||
/*
|
/**
|
||||||
Buffered version of Zstd compression library
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) 2015-2016, Yann Collet.
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
/* ***************************************************************
|
||||||
|
* NOTES/WARNINGS
|
||||||
|
*****************************************************************/
|
||||||
|
/* The streaming API defined here will soon be deprecated by the
|
||||||
|
* new one in 'zstd.h'; consider migrating towards newer streaming
|
||||||
|
* API. See 'lib/README.md'.
|
||||||
|
*****************************************************************/
|
||||||
|
|
||||||
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_H_23987
|
#ifndef ZSTD_BUFFERED_H_23987
|
||||||
#define ZSTD_BUFFERED_H_23987
|
#define ZSTD_BUFFERED_H_23987
|
||||||
|
|
||||||
|
|||||||
+23
-31
@@ -1,33 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
Common functions of Zstd compression library
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) 2015-2016, Yann Collet.
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
@@ -75,17 +54,30 @@ const char* ZBUFF_getErrorName(size_t errorCode) { return ERR_getErrorName(error
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*=**************************************************************
|
||||||
|
* Custom allocator
|
||||||
|
****************************************************************/
|
||||||
|
/* default uses stdlib */
|
||||||
void* ZSTD_defaultAllocFunction(void* opaque, size_t size)
|
void* ZSTD_defaultAllocFunction(void* opaque, size_t size)
|
||||||
{
|
{
|
||||||
void* address = malloc(size);
|
void* address = malloc(size);
|
||||||
(void)opaque;
|
(void)opaque;
|
||||||
/* printf("alloc %p, %d opaque=%p \n", address, (int)size, opaque); */
|
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZSTD_defaultFreeFunction(void* opaque, void* address)
|
void ZSTD_defaultFreeFunction(void* opaque, void* address)
|
||||||
{
|
{
|
||||||
(void)opaque;
|
(void)opaque;
|
||||||
/* if (address) printf("free %p opaque=%p \n", address, opaque); */
|
|
||||||
free(address);
|
free(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* ZSTD_malloc(size_t size, ZSTD_customMem customMem)
|
||||||
|
{
|
||||||
|
return customMem.customAlloc(customMem.opaque, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZSTD_free(void* ptr, ZSTD_customMem customMem)
|
||||||
|
{
|
||||||
|
if (ptr!=NULL)
|
||||||
|
customMem.customFree(customMem.opaque, ptr);
|
||||||
|
}
|
||||||
|
|||||||
+42
-58
@@ -1,37 +1,37 @@
|
|||||||
/*
|
/**
|
||||||
zstd_internal - common functions to include
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Header File for include
|
* All rights reserved.
|
||||||
Copyright (C) 2014-2016, Yann Collet.
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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 ZSTD_CCOMMON_H_MODULE
|
#ifndef ZSTD_CCOMMON_H_MODULE
|
||||||
#define ZSTD_CCOMMON_H_MODULE
|
#define ZSTD_CCOMMON_H_MODULE
|
||||||
|
|
||||||
|
/*-*******************************************************
|
||||||
|
* 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 */
|
||||||
|
# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */
|
||||||
|
#else
|
||||||
|
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
||||||
|
# ifdef __GNUC__
|
||||||
|
# define FORCE_INLINE static inline __attribute__((always_inline))
|
||||||
|
# else
|
||||||
|
# define FORCE_INLINE static inline
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# define FORCE_INLINE static
|
||||||
|
# endif /* __STDC_VERSION__ */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Dependencies
|
* Dependencies
|
||||||
***************************************/
|
***************************************/
|
||||||
@@ -42,28 +42,17 @@
|
|||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Common macros
|
* shared macros
|
||||||
***************************************/
|
***************************************/
|
||||||
#define MIN(a,b) ((a)<(b) ? (a) : (b))
|
#define MIN(a,b) ((a)<(b) ? (a) : (b))
|
||||||
#define MAX(a,b) ((a)>(b) ? (a) : (b))
|
#define MAX(a,b) ((a)>(b) ? (a) : (b))
|
||||||
|
#define CHECK_F(f) { size_t const errcod = f; if (ERR_isError(errcod)) return errcod; } /* check and Forward error code */
|
||||||
|
#define CHECK_E(f, e) { size_t const errcod = f; if (ERR_isError(errcod)) return ERROR(e); } /* check and send Error code */
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Common constants
|
* Common constants
|
||||||
***************************************/
|
***************************************/
|
||||||
#define ZSTD_OPT_DEBUG 0 /* 3 = compression stats; 5 = check encoded sequences; 9 = full logs */
|
|
||||||
#if defined(ZSTD_OPT_DEBUG) && ZSTD_OPT_DEBUG>=9
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#define ZSTD_LOG_PARSER(...) printf(__VA_ARGS__)
|
|
||||||
#define ZSTD_LOG_ENCODE(...) printf(__VA_ARGS__)
|
|
||||||
#define ZSTD_LOG_BLOCK(...) printf(__VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define ZSTD_LOG_PARSER(...)
|
|
||||||
#define ZSTD_LOG_ENCODE(...)
|
|
||||||
#define ZSTD_LOG_BLOCK(...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ZSTD_OPT_NUM (1<<12)
|
#define ZSTD_OPT_NUM (1<<12)
|
||||||
#define ZSTD_DICT_MAGIC 0xEC30A437 /* v0.7+ */
|
#define ZSTD_DICT_MAGIC 0xEC30A437 /* v0.7+ */
|
||||||
|
|
||||||
@@ -119,7 +108,8 @@ static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|||||||
static const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
|
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,
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1,
|
||||||
-1,-1,-1,-1 };
|
-1,-1,-1,-1 };
|
||||||
static const U32 LL_defaultNormLog = 6;
|
#define LL_DEFAULTNORMLOG 6 /* for static allocation */
|
||||||
|
static const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG;
|
||||||
|
|
||||||
static const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
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,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
@@ -129,11 +119,13 @@ 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, 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;
|
#define ML_DEFAULTNORMLOG 6 /* for static allocation */
|
||||||
|
static const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG;
|
||||||
|
|
||||||
static const S16 OF_defaultNorm[MaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
|
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 };
|
1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1 };
|
||||||
static const U32 OF_defaultNormLog = 5;
|
#define OF_DEFAULTNORMLOG 5 /* for static allocation */
|
||||||
|
static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
|
||||||
|
|
||||||
|
|
||||||
/*-*******************************************
|
/*-*******************************************
|
||||||
@@ -184,16 +176,6 @@ typedef struct {
|
|||||||
U32 rep[ZSTD_REP_NUM];
|
U32 rep[ZSTD_REP_NUM];
|
||||||
} ZSTD_optimal_t;
|
} ZSTD_optimal_t;
|
||||||
|
|
||||||
#if ZSTD_OPT_DEBUG == 3
|
|
||||||
#include ".debug/zstd_stats.h"
|
|
||||||
#else
|
|
||||||
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_statsInit(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; }
|
|
||||||
#endif /* #if ZSTD_OPT_DEBUG == 3 */
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct seqDef_s {
|
typedef struct seqDef_s {
|
||||||
U32 offset;
|
U32 offset;
|
||||||
@@ -233,7 +215,6 @@ typedef struct {
|
|||||||
U32 cachedPrice;
|
U32 cachedPrice;
|
||||||
U32 cachedLitLength;
|
U32 cachedLitLength;
|
||||||
const BYTE* cachedLiterals;
|
const BYTE* cachedLiterals;
|
||||||
ZSTD_stats_t stats;
|
|
||||||
} seqStore_t;
|
} seqStore_t;
|
||||||
|
|
||||||
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx);
|
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx);
|
||||||
@@ -244,6 +225,9 @@ int ZSTD_isSkipFrame(ZSTD_DCtx* dctx);
|
|||||||
void* ZSTD_defaultAllocFunction(void* opaque, size_t size);
|
void* ZSTD_defaultAllocFunction(void* opaque, size_t size);
|
||||||
void ZSTD_defaultFreeFunction(void* opaque, void* address);
|
void ZSTD_defaultFreeFunction(void* opaque, void* address);
|
||||||
static const ZSTD_customMem defaultCustomMem = { ZSTD_defaultAllocFunction, ZSTD_defaultFreeFunction, NULL };
|
static const ZSTD_customMem defaultCustomMem = { ZSTD_defaultAllocFunction, ZSTD_defaultFreeFunction, NULL };
|
||||||
|
void* ZSTD_malloc(size_t size, ZSTD_customMem customMem);
|
||||||
|
void ZSTD_free(void* ptr, ZSTD_customMem customMem);
|
||||||
|
|
||||||
|
|
||||||
/*====== common function ======*/
|
/*====== common function ======*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,162 +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_STATS_H
|
|
||||||
#define ZSTD_STATS_H
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
|
||||||
* Types
|
|
||||||
***************************************/
|
|
||||||
struct ZSTD_stats_s {
|
|
||||||
U32 priceOffset, priceOffCode, priceMatchLength, priceLiteral, priceLitLength;
|
|
||||||
U32 totalMatchSum, totalLitSum, totalSeqSum, totalRepSum;
|
|
||||||
U32 litSum, matchLengthSum, litLengthSum, offCodeSum;
|
|
||||||
U32 matchLengthFreq[MaxML+1];
|
|
||||||
U32 litLengthFreq[MaxLL+1];
|
|
||||||
U32 litFreq[1<<Litbits];
|
|
||||||
U32 offCodeFreq[MaxOff+1];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
|
||||||
* 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)
|
|
||||||
{
|
|
||||||
stats->totalMatchSum += stats->totalSeqSum * ((searchLength == 3) ? 3 : 4);
|
|
||||||
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\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)
|
|
||||||
{
|
|
||||||
stats->totalLitSum = stats->totalMatchSum = stats->totalSeqSum = stats->totalRepSum = 1;
|
|
||||||
stats->priceOffset = stats->priceOffCode = stats->priceMatchLength = stats->priceLiteral = stats->priceLitLength = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MEM_STATIC void ZSTD_statsResetFreqs(ZSTD_stats_t* stats)
|
|
||||||
{
|
|
||||||
unsigned u;
|
|
||||||
|
|
||||||
stats->litSum = (2<<Litbits);
|
|
||||||
stats->litLengthSum = MaxLL+1;
|
|
||||||
stats->matchLengthSum = MaxML+1;
|
|
||||||
stats->offCodeSum = (MaxOff+1);
|
|
||||||
|
|
||||||
for (u=0; u<=MaxLit; u++)
|
|
||||||
stats->litFreq[u] = 1;
|
|
||||||
for (u=0; u<=MaxLL; u++)
|
|
||||||
stats->litLengthFreq[u] = 1;
|
|
||||||
for (u=0; u<=MaxML; u++)
|
|
||||||
stats->matchLengthFreq[u] = 1;
|
|
||||||
for (u=0; u<=MaxOff; u++)
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
U32 u;
|
|
||||||
/* 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;
|
|
||||||
for (u=0; u < litLength; u++)
|
|
||||||
stats->litFreq[literals[u]]++;
|
|
||||||
|
|
||||||
/* literal Length */
|
|
||||||
{ static const BYTE LL_Code[64] = { 0, 1, 2, 3, 4, 5, 6, 7,
|
|
||||||
8, 9, 10, 11, 12, 13, 14, 15,
|
|
||||||
16, 16, 17, 17, 18, 18, 19, 19,
|
|
||||||
20, 20, 20, 20, 21, 21, 21, 21,
|
|
||||||
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 */
|
|
||||||
{ BYTE offCode = (BYTE)ZSTD_highbit(offset+1);
|
|
||||||
stats->priceOffCode += ZSTD_highbit(stats->offCodeSum+1) - ZSTD_highbit(stats->offCodeFreq[offCode]+1);
|
|
||||||
stats->priceOffset += offCode;
|
|
||||||
stats->offCodeSum++;
|
|
||||||
stats->offCodeFreq[offCode]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* match Length */
|
|
||||||
{ static const BYTE ML_Code[128] = { 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, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
|
|
||||||
38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ZSTD_STATIC_H */
|
|
||||||
@@ -41,12 +41,15 @@
|
|||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
||||||
#else
|
#else
|
||||||
# ifdef __GNUC__
|
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
||||||
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
# ifdef __GNUC__
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
# define FORCE_INLINE static inline __attribute__((always_inline))
|
||||||
|
# else
|
||||||
|
# define FORCE_INLINE static inline
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
# define FORCE_INLINE static inline
|
# define FORCE_INLINE static
|
||||||
# endif
|
# endif /* __STDC_VERSION__ */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,24 +35,8 @@
|
|||||||
/* **************************************************************
|
/* **************************************************************
|
||||||
* Compiler specifics
|
* 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 */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
# define FORCE_INLINE static __forceinline
|
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# 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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -89,7 +73,7 @@ unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS
|
|||||||
struct HUF_CElt_s {
|
struct HUF_CElt_s {
|
||||||
U16 val;
|
U16 val;
|
||||||
BYTE nbBits;
|
BYTE nbBits;
|
||||||
}; /* typedef'd to HUF_CElt within huf_static.h */
|
}; /* typedef'd to HUF_CElt within "huf.h" */
|
||||||
|
|
||||||
typedef struct nodeElt_s {
|
typedef struct nodeElt_s {
|
||||||
U32 count;
|
U32 count;
|
||||||
@@ -124,7 +108,8 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize,
|
|||||||
if ((size>1) & (size < maxSymbolValue/2)) { /* FSE compressed */
|
if ((size>1) & (size < maxSymbolValue/2)) { /* FSE compressed */
|
||||||
op[0] = (BYTE)size;
|
op[0] = (BYTE)size;
|
||||||
return size+1;
|
return size+1;
|
||||||
} }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* raw values */
|
/* raw values */
|
||||||
if (maxSymbolValue > (256-128)) return ERROR(GENERIC); /* should not happen */
|
if (maxSymbolValue > (256-128)) return ERROR(GENERIC); /* should not happen */
|
||||||
@@ -491,7 +476,7 @@ static size_t HUF_compress_internal (
|
|||||||
/* Scan input and build symbol stats */
|
/* Scan input and build symbol stats */
|
||||||
{ size_t const largest = FSE_count (count, &maxSymbolValue, (const BYTE*)src, srcSize);
|
{ size_t const largest = FSE_count (count, &maxSymbolValue, (const BYTE*)src, srcSize);
|
||||||
if (HUF_isError(largest)) return largest;
|
if (HUF_isError(largest)) return largest;
|
||||||
if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* rle */
|
if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */
|
||||||
if (largest <= (srcSize >> 7)+1) return 0; /* Fast heuristic : not compressible enough */
|
if (largest <= (srcSize >> 7)+1) return 0; /* Fast heuristic : not compressible enough */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,33 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
Buffered version of Zstd compression library
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) 2015-2016, Yann Collet.
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
@@ -98,7 +77,7 @@ struct ZBUFF_CCtx_s {
|
|||||||
U32 checksum;
|
U32 checksum;
|
||||||
U32 frameEnded;
|
U32 frameEnded;
|
||||||
ZSTD_customMem customMem;
|
ZSTD_customMem customMem;
|
||||||
}; /* typedef'd tp ZBUFF_CCtx within "zstd_buffered.h" */
|
}; /* typedef'd tp ZBUFF_CCtx within "zbuff.h" */
|
||||||
|
|
||||||
ZBUFF_CCtx* ZBUFF_createCCtx(void)
|
ZBUFF_CCtx* ZBUFF_createCCtx(void)
|
||||||
{
|
{
|
||||||
|
|||||||
+289
-281
@@ -1,51 +1,11 @@
|
|||||||
/*
|
/**
|
||||||
ZSTD HC - High Compression Mode of Zstandard
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) 2015-2016, Yann Collet.
|
* All rights reserved.
|
||||||
|
*
|
||||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
Redistribution and use in source and binary forms, with or without
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
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
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*-*******************************************************
|
|
||||||
* 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 */
|
|
||||||
#else
|
|
||||||
# ifdef __GNUC__
|
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
|
||||||
# else
|
|
||||||
# define FORCE_INLINE static inline
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
@@ -54,7 +14,7 @@
|
|||||||
#include <string.h> /* memset */
|
#include <string.h> /* memset */
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
|
#define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
|
||||||
#include "xxhash.h" /* XXH_reset, update, digest */
|
#include "xxhash.h" /* XXH_reset, update, digest */
|
||||||
#define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */
|
#define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */
|
||||||
#include "fse.h"
|
#include "fse.h"
|
||||||
#define HUF_STATIC_LINKING_ONLY
|
#define HUF_STATIC_LINKING_ONLY
|
||||||
@@ -133,29 +93,27 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
|
|||||||
{
|
{
|
||||||
ZSTD_CCtx* cctx;
|
ZSTD_CCtx* cctx;
|
||||||
|
|
||||||
if (!customMem.customAlloc && !customMem.customFree)
|
if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
|
||||||
customMem = defaultCustomMem;
|
if (!customMem.customAlloc || !customMem.customFree) return NULL;
|
||||||
|
|
||||||
if (!customMem.customAlloc || !customMem.customFree)
|
cctx = (ZSTD_CCtx*) ZSTD_malloc(sizeof(ZSTD_CCtx), customMem);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
cctx = (ZSTD_CCtx*) customMem.customAlloc(customMem.opaque, sizeof(ZSTD_CCtx));
|
|
||||||
if (!cctx) return NULL;
|
if (!cctx) return NULL;
|
||||||
memset(cctx, 0, sizeof(ZSTD_CCtx));
|
memset(cctx, 0, sizeof(ZSTD_CCtx));
|
||||||
memcpy(&(cctx->customMem), &customMem, sizeof(ZSTD_customMem));
|
memcpy(&(cctx->customMem), &customMem, sizeof(customMem));
|
||||||
return cctx;
|
return cctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
|
size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
|
||||||
{
|
{
|
||||||
if (cctx==NULL) return 0; /* support free on NULL */
|
if (cctx==NULL) return 0; /* support free on NULL */
|
||||||
if (cctx->workSpace) cctx->customMem.customFree(cctx->customMem.opaque, cctx->workSpace);
|
ZSTD_free(cctx->workSpace, cctx->customMem);
|
||||||
cctx->customMem.customFree(cctx->customMem.opaque, cctx);
|
ZSTD_free(cctx, cctx->customMem);
|
||||||
return 0; /* reserved as a potential error code in the future */
|
return 0; /* reserved as a potential error code in the future */
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZSTD_sizeofCCtx(const ZSTD_CCtx* cctx)
|
size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx)
|
||||||
{
|
{
|
||||||
|
if (cctx==NULL) return 0; /* support sizeof on NULL */
|
||||||
return sizeof(*cctx) + cctx->workSpaceSize;
|
return sizeof(*cctx) + cctx->workSpaceSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,19 +123,17 @@ const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) /* hidden interface *
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define CLAMP(val,min,max) { if (val<min) val=min; else if (val>max) val=max; }
|
|
||||||
#define CLAMPCHECK(val,min,max) { if ((val<min) || (val>max)) return ERROR(compressionParameter_unsupported); }
|
|
||||||
|
|
||||||
/** ZSTD_checkParams() :
|
/** ZSTD_checkParams() :
|
||||||
ensure param values remain within authorized range.
|
ensure param values remain within authorized range.
|
||||||
@return : 0, or an error code if one value is beyond authorized range */
|
@return : 0, or an error code if one value is beyond authorized range */
|
||||||
size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
|
size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
|
||||||
{
|
{
|
||||||
|
# define CLAMPCHECK(val,min,max) { if ((val<min) | (val>max)) return ERROR(compressionParameter_unsupported); }
|
||||||
CLAMPCHECK(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
|
CLAMPCHECK(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
|
||||||
CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
|
CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
|
||||||
CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
|
CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
|
||||||
CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
|
CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
|
||||||
{ U32 const searchLengthMin = (cParams.strategy == ZSTD_fast || cParams.strategy == ZSTD_greedy) ? ZSTD_SEARCHLENGTH_MIN+1 : ZSTD_SEARCHLENGTH_MIN;
|
{ U32 const searchLengthMin = ((cParams.strategy == ZSTD_fast) | (cParams.strategy == ZSTD_greedy)) ? ZSTD_SEARCHLENGTH_MIN+1 : ZSTD_SEARCHLENGTH_MIN;
|
||||||
U32 const searchLengthMax = (cParams.strategy == ZSTD_fast) ? ZSTD_SEARCHLENGTH_MAX : ZSTD_SEARCHLENGTH_MAX-1;
|
U32 const searchLengthMax = (cParams.strategy == ZSTD_fast) ? ZSTD_SEARCHLENGTH_MAX : ZSTD_SEARCHLENGTH_MAX-1;
|
||||||
CLAMPCHECK(cParams.searchLength, searchLengthMin, searchLengthMax); }
|
CLAMPCHECK(cParams.searchLength, searchLengthMin, searchLengthMax); }
|
||||||
CLAMPCHECK(cParams.targetLength, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
|
CLAMPCHECK(cParams.targetLength, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
|
||||||
@@ -186,21 +142,8 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** ZSTD_checkCParams_advanced() :
|
|
||||||
temporary work-around, while the compressor compatibility remains limited regarding windowLog < 18 */
|
|
||||||
size_t ZSTD_checkCParams_advanced(ZSTD_compressionParameters cParams, U64 srcSize)
|
|
||||||
{
|
|
||||||
if (srcSize > (1ULL << ZSTD_WINDOWLOG_MIN)) return ZSTD_checkCParams(cParams);
|
|
||||||
if (cParams.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) return ERROR(compressionParameter_unsupported);
|
|
||||||
if (srcSize <= (1ULL << cParams.windowLog)) cParams.windowLog = ZSTD_WINDOWLOG_MIN; /* fake value - temporary work around */
|
|
||||||
if (srcSize <= (1ULL << cParams.chainLog)) cParams.chainLog = ZSTD_CHAINLOG_MIN; /* fake value - temporary work around */
|
|
||||||
if ((srcSize <= (1ULL << cParams.hashLog)) && ((U32)cParams.strategy < (U32)ZSTD_btlazy2)) cParams.hashLog = ZSTD_HASHLOG_MIN; /* fake value - temporary work around */
|
|
||||||
return ZSTD_checkCParams(cParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** ZSTD_adjustCParams() :
|
/** ZSTD_adjustCParams() :
|
||||||
optimize cPar for a 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.
|
||||||
@@ -213,16 +156,15 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
|
|||||||
{ 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_highbit32((U32)(rSize)-1) + 1;
|
U32 const srcLog = MAX(ZSTD_HASHLOG_MIN, ZSTD_highbit32((U32)(rSize)-1) + 1);
|
||||||
if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;
|
if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;
|
||||||
} }
|
} }
|
||||||
if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog;
|
if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog;
|
||||||
{ U32 const btPlus = (cPar.strategy == ZSTD_btlazy2) || (cPar.strategy == ZSTD_btopt);
|
{ U32 const btPlus = (cPar.strategy == ZSTD_btlazy2) | (cPar.strategy == ZSTD_btopt);
|
||||||
U32 const maxChainLog = cPar.windowLog+btPlus;
|
U32 const maxChainLog = cPar.windowLog+btPlus;
|
||||||
if (cPar.chainLog > maxChainLog) cPar.chainLog = maxChainLog; } /* <= ZSTD_CHAINLOG_MAX */
|
if (cPar.chainLog > maxChainLog) cPar.chainLog = maxChainLog; } /* <= ZSTD_CHAINLOG_MAX */
|
||||||
|
|
||||||
if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */
|
if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */
|
||||||
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;
|
return cPar;
|
||||||
}
|
}
|
||||||
@@ -249,81 +191,116 @@ size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams)
|
|||||||
return sizeof(ZSTD_CCtx) + neededSpace;
|
return sizeof(ZSTD_CCtx) + neededSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static U32 ZSTD_equivalentParams(ZSTD_parameters param1, ZSTD_parameters param2)
|
||||||
|
{
|
||||||
|
return (param1.cParams.hashLog == param2.cParams.hashLog)
|
||||||
|
& (param1.cParams.chainLog == param2.cParams.chainLog)
|
||||||
|
& (param1.cParams.strategy == param2.cParams.strategy)
|
||||||
|
& ((param1.cParams.searchLength==3) == (param2.cParams.searchLength==3));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! ZSTD_continueCCtx() :
|
||||||
|
reuse CCtx without reset (note : requires no dictionary) */
|
||||||
|
static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 frameContentSize)
|
||||||
|
{
|
||||||
|
U32 const end = (U32)(cctx->nextSrc - cctx->base);
|
||||||
|
cctx->params = params;
|
||||||
|
cctx->frameContentSize = frameContentSize;
|
||||||
|
cctx->lowLimit = end;
|
||||||
|
cctx->dictLimit = end;
|
||||||
|
cctx->nextToUpdate = end+1;
|
||||||
|
cctx->stage = ZSTDcs_init;
|
||||||
|
cctx->dictID = 0;
|
||||||
|
cctx->loadedDictEnd = 0;
|
||||||
|
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) cctx->rep[i] = repStartValue[i]; }
|
||||||
|
cctx->seqStore.litLengthSum = 0; /* force reset of btopt stats */
|
||||||
|
XXH64_reset(&cctx->xxhState, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset, ZSTDcrp_fullReset } ZSTD_compResetPolicy_e;
|
||||||
|
|
||||||
/*! ZSTD_resetCCtx_advanced() :
|
/*! ZSTD_resetCCtx_advanced() :
|
||||||
note : 'params' is expected to be validated */
|
note : 'params' must be validated */
|
||||||
static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
||||||
ZSTD_parameters params, U64 frameContentSize,
|
ZSTD_parameters params, U64 frameContentSize,
|
||||||
U32 reset)
|
ZSTD_compResetPolicy_e const crp)
|
||||||
{ /* note : params considered validated here */
|
{
|
||||||
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog);
|
if (crp == ZSTDcrp_continue)
|
||||||
U32 const divider = (params.cParams.searchLength==3) ? 3 : 4;
|
if (ZSTD_equivalentParams(params, zc->params))
|
||||||
size_t const maxNbSeq = blockSize / divider;
|
return ZSTD_continueCCtx(zc, params, frameContentSize);
|
||||||
size_t const tokenSpace = blockSize + 11*maxNbSeq;
|
|
||||||
size_t const chainSize = (params.cParams.strategy == ZSTD_fast) ? 0 : (1 << params.cParams.chainLog);
|
|
||||||
size_t const hSize = ((size_t)1) << params.cParams.hashLog;
|
|
||||||
U32 const hashLog3 = (params.cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, params.cParams.windowLog);
|
|
||||||
size_t const h3Size = ((size_t)1) << hashLog3;
|
|
||||||
size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
|
|
||||||
void* ptr;
|
|
||||||
|
|
||||||
/* Check if workSpace is large enough, alloc a new one if needed */
|
{ size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog);
|
||||||
{ size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits))*sizeof(U32)
|
U32 const divider = (params.cParams.searchLength==3) ? 3 : 4;
|
||||||
+ (ZSTD_OPT_NUM+1)*(sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t));
|
size_t const maxNbSeq = blockSize / divider;
|
||||||
size_t const neededSpace = tableSpace + (256*sizeof(U32)) /* huffTable */ + tokenSpace
|
size_t const tokenSpace = blockSize + 11*maxNbSeq;
|
||||||
+ ((params.cParams.strategy == ZSTD_btopt) ? optSpace : 0);
|
size_t const chainSize = (params.cParams.strategy == ZSTD_fast) ? 0 : (1 << params.cParams.chainLog);
|
||||||
if (zc->workSpaceSize < neededSpace) {
|
size_t const hSize = ((size_t)1) << params.cParams.hashLog;
|
||||||
zc->customMem.customFree(zc->customMem.opaque, zc->workSpace);
|
U32 const hashLog3 = (params.cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, params.cParams.windowLog);
|
||||||
zc->workSpace = zc->customMem.customAlloc(zc->customMem.opaque, neededSpace);
|
size_t const h3Size = ((size_t)1) << hashLog3;
|
||||||
if (zc->workSpace == NULL) return ERROR(memory_allocation);
|
size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
|
||||||
zc->workSpaceSize = neededSpace;
|
void* ptr;
|
||||||
} }
|
|
||||||
|
|
||||||
if (reset) memset(zc->workSpace, 0, tableSpace ); /* reset only tables */
|
/* Check if workSpace is large enough, alloc a new one if needed */
|
||||||
XXH64_reset(&zc->xxhState, 0);
|
{ size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits))*sizeof(U32)
|
||||||
zc->hashLog3 = hashLog3;
|
+ (ZSTD_OPT_NUM+1)*(sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t));
|
||||||
zc->hashTable = (U32*)(zc->workSpace);
|
size_t const neededSpace = tableSpace + (256*sizeof(U32)) /* huffTable */ + tokenSpace
|
||||||
zc->chainTable = zc->hashTable + hSize;
|
+ ((params.cParams.strategy == ZSTD_btopt) ? optSpace : 0);
|
||||||
zc->hashTable3 = zc->chainTable + chainSize;
|
if (zc->workSpaceSize < neededSpace) {
|
||||||
ptr = zc->hashTable3 + h3Size;
|
ZSTD_free(zc->workSpace, zc->customMem);
|
||||||
zc->hufTable = (HUF_CElt*)ptr;
|
zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
|
||||||
zc->flagStaticTables = 0;
|
if (zc->workSpace == NULL) return ERROR(memory_allocation);
|
||||||
ptr = ((U32*)ptr) + 256; /* note : HUF_CElt* is incomplete type, size is simulated using U32 */
|
zc->workSpaceSize = neededSpace;
|
||||||
|
} }
|
||||||
|
|
||||||
zc->nextToUpdate = 1;
|
if (crp!=ZSTDcrp_noMemset) memset(zc->workSpace, 0, tableSpace); /* reset tables only */
|
||||||
zc->nextSrc = NULL;
|
XXH64_reset(&zc->xxhState, 0);
|
||||||
zc->base = NULL;
|
zc->hashLog3 = hashLog3;
|
||||||
zc->dictBase = NULL;
|
zc->hashTable = (U32*)(zc->workSpace);
|
||||||
zc->dictLimit = 0;
|
zc->chainTable = zc->hashTable + hSize;
|
||||||
zc->lowLimit = 0;
|
zc->hashTable3 = zc->chainTable + chainSize;
|
||||||
zc->params = params;
|
ptr = zc->hashTable3 + h3Size;
|
||||||
zc->blockSize = blockSize;
|
zc->hufTable = (HUF_CElt*)ptr;
|
||||||
zc->frameContentSize = frameContentSize;
|
zc->flagStaticTables = 0;
|
||||||
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) zc->rep[i] = repStartValue[i]; }
|
ptr = ((U32*)ptr) + 256; /* note : HUF_CElt* is incomplete type, size is simulated using U32 */
|
||||||
|
|
||||||
if (params.cParams.strategy == ZSTD_btopt) {
|
zc->nextToUpdate = 1;
|
||||||
zc->seqStore.litFreq = (U32*)ptr;
|
zc->nextSrc = NULL;
|
||||||
zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1<<Litbits);
|
zc->base = NULL;
|
||||||
zc->seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (MaxLL+1);
|
zc->dictBase = NULL;
|
||||||
zc->seqStore.offCodeFreq = zc->seqStore.matchLengthFreq + (MaxML+1);
|
zc->dictLimit = 0;
|
||||||
ptr = zc->seqStore.offCodeFreq + (MaxOff+1);
|
zc->lowLimit = 0;
|
||||||
zc->seqStore.matchTable = (ZSTD_match_t*)ptr;
|
zc->params = params;
|
||||||
ptr = zc->seqStore.matchTable + ZSTD_OPT_NUM+1;
|
zc->blockSize = blockSize;
|
||||||
zc->seqStore.priceTable = (ZSTD_optimal_t*)ptr;
|
zc->frameContentSize = frameContentSize;
|
||||||
ptr = zc->seqStore.priceTable + ZSTD_OPT_NUM+1;
|
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) zc->rep[i] = repStartValue[i]; }
|
||||||
zc->seqStore.litLengthSum = 0;
|
|
||||||
|
if (params.cParams.strategy == ZSTD_btopt) {
|
||||||
|
zc->seqStore.litFreq = (U32*)ptr;
|
||||||
|
zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1<<Litbits);
|
||||||
|
zc->seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (MaxLL+1);
|
||||||
|
zc->seqStore.offCodeFreq = zc->seqStore.matchLengthFreq + (MaxML+1);
|
||||||
|
ptr = zc->seqStore.offCodeFreq + (MaxOff+1);
|
||||||
|
zc->seqStore.matchTable = (ZSTD_match_t*)ptr;
|
||||||
|
ptr = zc->seqStore.matchTable + ZSTD_OPT_NUM+1;
|
||||||
|
zc->seqStore.priceTable = (ZSTD_optimal_t*)ptr;
|
||||||
|
ptr = zc->seqStore.priceTable + ZSTD_OPT_NUM+1;
|
||||||
|
zc->seqStore.litLengthSum = 0;
|
||||||
|
}
|
||||||
|
zc->seqStore.sequencesStart = (seqDef*)ptr;
|
||||||
|
ptr = zc->seqStore.sequencesStart + maxNbSeq;
|
||||||
|
zc->seqStore.llCode = (BYTE*) ptr;
|
||||||
|
zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq;
|
||||||
|
zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq;
|
||||||
|
zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq;
|
||||||
|
|
||||||
|
zc->stage = ZSTDcs_init;
|
||||||
|
zc->dictID = 0;
|
||||||
|
zc->loadedDictEnd = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
zc->seqStore.sequencesStart = (seqDef*)ptr;
|
|
||||||
ptr = zc->seqStore.sequencesStart + maxNbSeq;
|
|
||||||
zc->seqStore.llCode = (BYTE*) ptr;
|
|
||||||
zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq;
|
|
||||||
zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq;
|
|
||||||
zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq;
|
|
||||||
|
|
||||||
zc->stage = ZSTDcs_init;
|
|
||||||
zc->dictID = 0;
|
|
||||||
zc->loadedDictEnd = 0;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -331,13 +308,12 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
|||||||
* Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
|
* Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
|
||||||
* Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
|
* Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
|
||||||
* @return : 0, or an error code */
|
* @return : 0, or an error code */
|
||||||
size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx)
|
size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize)
|
||||||
{
|
{
|
||||||
if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong);
|
if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong);
|
||||||
|
|
||||||
memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
|
memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
|
||||||
ZSTD_resetCCtx_advanced(dstCCtx, srcCCtx->params, srcCCtx->frameContentSize, 0);
|
ZSTD_resetCCtx_advanced(dstCCtx, srcCCtx->params, pledgedSrcSize, ZSTDcrp_noMemset);
|
||||||
dstCCtx->params.fParams.contentSizeFlag = 0; /* content size different from the one set during srcCCtx init */
|
|
||||||
|
|
||||||
/* copy tables */
|
/* copy tables */
|
||||||
{ size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
|
{ size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
|
||||||
@@ -691,8 +667,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|||||||
FSE_CState_t stateOffsetBits;
|
FSE_CState_t stateOffsetBits;
|
||||||
FSE_CState_t stateLitLength;
|
FSE_CState_t stateLitLength;
|
||||||
|
|
||||||
{ size_t const errorCode = BIT_initCStream(&blockStream, op, oend-op);
|
CHECK_E(BIT_initCStream(&blockStream, op, oend-op), dstSize_tooSmall); /* not enough space remaining */
|
||||||
if (ERR_isError(errorCode)) return ERROR(dstSize_tooSmall); } /* not enough space remaining */
|
|
||||||
|
|
||||||
/* first symbols */
|
/* first symbols */
|
||||||
FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);
|
FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);
|
||||||
@@ -765,8 +740,6 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const v
|
|||||||
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, (const BYTE*)literals, offsetCode, matchCode); /* debug only */
|
|
||||||
|
|
||||||
/* copy Literals */
|
/* copy Literals */
|
||||||
ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
|
ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
|
||||||
seqStorePtr->lit += litLength;
|
seqStorePtr->lit += litLength;
|
||||||
@@ -1108,7 +1081,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
|
|
||||||
if (ip <= ilimit) {
|
if (ip <= ilimit) {
|
||||||
/* Fill Table */
|
/* Fill Table */
|
||||||
hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;
|
hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;
|
||||||
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) {
|
||||||
@@ -1232,9 +1205,20 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
|
|||||||
offset = (U32)(ip-matchLong);
|
offset = (U32)(ip-matchLong);
|
||||||
while (((ip>anchor) & (matchLong>lowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
|
while (((ip>anchor) & (matchLong>lowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
|
||||||
} else if ( (matchIndexS > lowestIndex) && (MEM_read32(match) == MEM_read32(ip)) ) {
|
} else if ( (matchIndexS > lowestIndex) && (MEM_read32(match) == MEM_read32(ip)) ) {
|
||||||
mLength = ZSTD_count(ip+4, match+4, iend) + 4;
|
size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
|
||||||
offset = (U32)(ip-match);
|
U32 const matchIndex3 = hashLong[h3];
|
||||||
while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
|
const BYTE* match3 = base + matchIndex3;
|
||||||
|
hashLong[h3] = current + 1;
|
||||||
|
if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
|
||||||
|
mLength = ZSTD_count(ip+9, match3+8, iend) + 8;
|
||||||
|
ip++;
|
||||||
|
offset = (U32)(ip-match3);
|
||||||
|
while (((ip>anchor) & (match3>lowest)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
|
||||||
|
} else {
|
||||||
|
mLength = ZSTD_count(ip+4, match+4, iend) + 4;
|
||||||
|
offset = (U32)(ip-match);
|
||||||
|
while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ip += ((ip-anchor) >> g_searchStrength) + 1;
|
ip += ((ip-anchor) >> g_searchStrength) + 1;
|
||||||
continue;
|
continue;
|
||||||
@@ -1361,16 +1345,32 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
offset_2 = offset_1;
|
offset_2 = offset_1;
|
||||||
offset_1 = offset;
|
offset_1 = offset;
|
||||||
ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
|
ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
|
||||||
|
|
||||||
} else if ((matchIndex > lowestIndex) && (MEM_read32(match) == MEM_read32(ip))) {
|
} else if ((matchIndex > lowestIndex) && (MEM_read32(match) == MEM_read32(ip))) {
|
||||||
const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
|
size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
|
||||||
const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
|
U32 const matchIndex3 = hashLong[h3];
|
||||||
|
const BYTE* const match3Base = matchIndex3 < dictLimit ? dictBase : base;
|
||||||
|
const BYTE* match3 = match3Base + matchIndex3;
|
||||||
U32 offset;
|
U32 offset;
|
||||||
mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
|
hashLong[h3] = current + 1;
|
||||||
while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
|
if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
|
||||||
offset = current - matchIndex;
|
const BYTE* matchEnd = matchIndex3 < dictLimit ? dictEnd : iend;
|
||||||
|
const BYTE* lowMatchPtr = matchIndex3 < dictLimit ? dictStart : lowPrefixPtr;
|
||||||
|
mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, lowPrefixPtr) + 8;
|
||||||
|
ip++;
|
||||||
|
offset = current+1 - matchIndex3;
|
||||||
|
while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
|
||||||
|
} else {
|
||||||
|
const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
|
||||||
|
const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
|
||||||
|
mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
|
||||||
|
offset = current - matchIndex;
|
||||||
|
while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
|
||||||
|
}
|
||||||
offset_2 = offset_1;
|
offset_2 = offset_1;
|
||||||
offset_1 = offset;
|
offset_1 = offset;
|
||||||
ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
|
ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ip += ((ip-anchor) >> g_searchStrength) + 1;
|
ip += ((ip-anchor) >> g_searchStrength) + 1;
|
||||||
continue;
|
continue;
|
||||||
@@ -1945,7 +1945,6 @@ _storeSequence:
|
|||||||
{ size_t const lastLLSize = iend - anchor;
|
{ size_t const lastLLSize = iend - anchor;
|
||||||
memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
||||||
seqStorePtr->lit += lastLLSize;
|
seqStorePtr->lit += lastLLSize;
|
||||||
ZSTD_statsUpdatePrices(&seqStorePtr->stats, lastLLSize, anchor, 0, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2235,8 +2234,6 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
|
|||||||
BYTE* const ostart = (BYTE*)dst;
|
BYTE* const ostart = (BYTE*)dst;
|
||||||
BYTE* op = ostart;
|
BYTE* op = ostart;
|
||||||
U32 const maxDist = 1 << cctx->params.cParams.windowLog;
|
U32 const maxDist = 1 << cctx->params.cParams.windowLog;
|
||||||
ZSTD_stats_t* stats = &cctx->seqStore.stats;
|
|
||||||
ZSTD_statsInit(stats); /* debug only */
|
|
||||||
|
|
||||||
if (cctx->params.fParams.checksumFlag)
|
if (cctx->params.fParams.checksumFlag)
|
||||||
XXH64_update(&cctx->xxhState, src, srcSize);
|
XXH64_update(&cctx->xxhState, src, srcSize);
|
||||||
@@ -2244,7 +2241,6 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
|
|||||||
while (remaining) {
|
while (remaining) {
|
||||||
U32 const lastBlock = lastFrameChunk & (blockSize >= remaining);
|
U32 const lastBlock = lastFrameChunk & (blockSize >= remaining);
|
||||||
size_t cSize;
|
size_t cSize;
|
||||||
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;
|
||||||
@@ -2253,7 +2249,8 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
|
|||||||
if (cctx->lowLimit > (1<<30)) {
|
if (cctx->lowLimit > (1<<30)) {
|
||||||
U32 const btplus = (cctx->params.cParams.strategy == ZSTD_btlazy2) | (cctx->params.cParams.strategy == ZSTD_btopt);
|
U32 const btplus = (cctx->params.cParams.strategy == ZSTD_btlazy2) | (cctx->params.cParams.strategy == ZSTD_btopt);
|
||||||
U32 const chainMask = (1 << (cctx->params.cParams.chainLog - btplus)) - 1;
|
U32 const chainMask = (1 << (cctx->params.cParams.chainLog - btplus)) - 1;
|
||||||
U32 const newLowLimit = cctx->lowLimit & chainMask; /* preserve position % chainSize */
|
U32 const supLog = MAX(cctx->params.cParams.chainLog, 17 /* blockSize */);
|
||||||
|
U32 const newLowLimit = (cctx->lowLimit & chainMask) + (1 << supLog); /* preserve position % chainSize, ensure current-repcode doesn't underflow */
|
||||||
U32 const correction = cctx->lowLimit - newLowLimit;
|
U32 const correction = cctx->lowLimit - newLowLimit;
|
||||||
ZSTD_reduceIndex(cctx, correction);
|
ZSTD_reduceIndex(cctx, correction);
|
||||||
cctx->base += correction;
|
cctx->base += correction;
|
||||||
@@ -2293,7 +2290,6 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending;
|
if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending;
|
||||||
ZSTD_statsPrint(stats, cctx->params.cParams.searchLength); /* debug only */
|
|
||||||
return op-ostart;
|
return op-ostart;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2402,7 +2398,6 @@ size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const
|
|||||||
{
|
{
|
||||||
size_t const blockSizeMax = ZSTD_getBlockSizeMax(cctx);
|
size_t const blockSizeMax = ZSTD_getBlockSizeMax(cctx);
|
||||||
if (srcSize > blockSizeMax) return ERROR(srcSize_wrong);
|
if (srcSize > blockSizeMax) return ERROR(srcSize_wrong);
|
||||||
ZSTD_LOG_BLOCK("%p: ZSTD_compressBlock searchLength=%d\n", cctx->base, cctx->params.cParams.searchLength);
|
|
||||||
return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0, 0);
|
return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2479,8 +2474,7 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|||||||
unsigned offcodeMaxValue = MaxOff, offcodeLog = OffFSELog;
|
unsigned offcodeMaxValue = MaxOff, offcodeLog = OffFSELog;
|
||||||
size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
|
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_buildCTable(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog);
|
CHECK_E (FSE_buildCTable(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted);
|
||||||
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
|
||||||
dictPtr += offcodeHeaderSize;
|
dictPtr += offcodeHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2488,8 +2482,7 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|||||||
unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
|
unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
|
||||||
size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
|
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_buildCTable(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
|
CHECK_E (FSE_buildCTable(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted);
|
||||||
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
|
||||||
dictPtr += matchlengthHeaderSize;
|
dictPtr += matchlengthHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2497,8 +2490,7 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|||||||
unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
|
unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
|
||||||
size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
|
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_buildCTable(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog);
|
CHECK_E(FSE_buildCTable(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted);
|
||||||
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
|
||||||
dictPtr += litlengthHeaderSize;
|
dictPtr += litlengthHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2523,8 +2515,9 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* dict, si
|
|||||||
zc->dictID = zc->params.fParams.noDictIDFlag ? 0 : MEM_readLE32((const char*)dict+4);
|
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+8 /* skip dictHeader */, dictSize-8) + 8;
|
{ size_t const loadError = ZSTD_loadDictEntropyStats(zc, (const char*)dict+8 /* skip dictHeader */, dictSize-8);
|
||||||
if (ZSTD_isError(eSize)) return eSize;
|
size_t const eSize = loadError + 8;
|
||||||
|
if (ZSTD_isError(loadError)) return loadError;
|
||||||
return ZSTD_loadDictionaryContent(zc, (const char*)dict+eSize, dictSize-eSize);
|
return ZSTD_loadDictionaryContent(zc, (const char*)dict+eSize, dictSize-eSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2532,14 +2525,13 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* dict, si
|
|||||||
|
|
||||||
/*! ZSTD_compressBegin_internal() :
|
/*! ZSTD_compressBegin_internal() :
|
||||||
* @return : 0, or an error code */
|
* @return : 0, or an error code */
|
||||||
static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* zc,
|
static size_t ZSTD_compressBegin_internal(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)
|
||||||
{
|
{
|
||||||
size_t const resetError = ZSTD_resetCCtx_advanced(zc, params, pledgedSrcSize, 1);
|
ZSTD_compResetPolicy_e const crp = dictSize ? ZSTDcrp_fullReset : ZSTDcrp_continue;
|
||||||
if (ZSTD_isError(resetError)) return resetError;
|
CHECK_F(ZSTD_resetCCtx_advanced(cctx, params, pledgedSrcSize, crp));
|
||||||
|
return ZSTD_compress_insertDictionary(cctx, dict, dictSize);
|
||||||
return ZSTD_compress_insertDictionary(zc, dict, dictSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2550,9 +2542,7 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
|
|||||||
ZSTD_parameters params, unsigned long long pledgedSrcSize)
|
ZSTD_parameters params, unsigned long long pledgedSrcSize)
|
||||||
{
|
{
|
||||||
/* compression parameters verification and optimization */
|
/* compression parameters verification and optimization */
|
||||||
{ size_t const errorCode = ZSTD_checkCParams_advanced(params.cParams, pledgedSrcSize);
|
CHECK_F(ZSTD_checkCParams(params.cParams));
|
||||||
if (ZSTD_isError(errorCode)) return errorCode; }
|
|
||||||
|
|
||||||
return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, pledgedSrcSize);
|
return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, pledgedSrcSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2560,14 +2550,12 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
|
|||||||
size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, 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 const params = ZSTD_getParams(compressionLevel, 0, dictSize);
|
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
|
||||||
ZSTD_LOG_BLOCK("%p: ZSTD_compressBegin_usingDict compressionLevel=%d\n", cctx->base, compressionLevel);
|
|
||||||
return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, 0);
|
return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_compressBegin(ZSTD_CCtx* zc, int compressionLevel)
|
size_t ZSTD_compressBegin(ZSTD_CCtx* zc, int compressionLevel)
|
||||||
{
|
{
|
||||||
ZSTD_LOG_BLOCK("%p: ZSTD_compressBegin compressionLevel=%d\n", zc->base, compressionLevel);
|
|
||||||
return ZSTD_compressBegin_usingDict(zc, NULL, 0, compressionLevel);
|
return ZSTD_compressBegin_usingDict(zc, NULL, 0, compressionLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2581,7 +2569,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
|
|||||||
BYTE* op = ostart;
|
BYTE* op = ostart;
|
||||||
size_t fhSize = 0;
|
size_t fhSize = 0;
|
||||||
|
|
||||||
if (cctx->stage == ZSTDcs_created) return ERROR(stage_wrong); /*< not even init ! */
|
if (cctx->stage == ZSTDcs_created) return ERROR(stage_wrong); /* init missing */
|
||||||
|
|
||||||
/* special case : empty frame */
|
/* special case : empty frame */
|
||||||
if (cctx->stage == ZSTDcs_init) {
|
if (cctx->stage == ZSTDcs_init) {
|
||||||
@@ -2632,9 +2620,7 @@ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
|
|||||||
const void* dict,size_t dictSize,
|
const void* dict,size_t dictSize,
|
||||||
ZSTD_parameters params)
|
ZSTD_parameters params)
|
||||||
{
|
{
|
||||||
size_t const errorCode = ZSTD_compressBegin_internal(cctx, dict, dictSize, params, srcSize);
|
CHECK_F(ZSTD_compressBegin_internal(cctx, dict, dictSize, params, srcSize));
|
||||||
if(ZSTD_isError(errorCode)) return errorCode;
|
|
||||||
|
|
||||||
return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
|
return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2644,8 +2630,7 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
|||||||
const void* dict,size_t dictSize,
|
const void* dict,size_t dictSize,
|
||||||
ZSTD_parameters params)
|
ZSTD_parameters params)
|
||||||
{
|
{
|
||||||
size_t const errorCode = ZSTD_checkCParams_advanced(params.cParams, srcSize);
|
CHECK_F(ZSTD_checkCParams(params.cParams));
|
||||||
if (ZSTD_isError(errorCode)) return errorCode;
|
|
||||||
return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
|
return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2653,13 +2638,11 @@ size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, co
|
|||||||
{
|
{
|
||||||
ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, dictSize);
|
ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, dictSize);
|
||||||
params.fParams.contentSizeFlag = 1;
|
params.fParams.contentSizeFlag = 1;
|
||||||
ZSTD_LOG_BLOCK("%p: ZSTD_compress_usingDict srcSize=%d dictSize=%d compressionLevel=%d\n", ctx->base, (int)srcSize, (int)dictSize, compressionLevel);
|
|
||||||
return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
|
return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZSTD_compressCCtx (ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel)
|
size_t ZSTD_compressCCtx (ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel)
|
||||||
{
|
{
|
||||||
ZSTD_LOG_BLOCK("%p: ZSTD_compressCCtx srcSize=%d compressionLevel=%d\n", ctx->base, (int)srcSize, compressionLevel);
|
|
||||||
return ZSTD_compress_usingDict(ctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel);
|
return ZSTD_compress_usingDict(ctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2670,7 +2653,7 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS
|
|||||||
memset(&ctxBody, 0, sizeof(ctxBody));
|
memset(&ctxBody, 0, sizeof(ctxBody));
|
||||||
memcpy(&ctxBody.customMem, &defaultCustomMem, sizeof(ZSTD_customMem));
|
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);
|
||||||
ctxBody.customMem.customFree(ctxBody.customMem.opaque, ctxBody.workSpace); /* can't free ctxBody, since it's on stack; just free heap content */
|
ZSTD_free(ctxBody.workSpace, defaultCustomMem); /* can't free ctxBody itself, as it's on stack; free only heap content */
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2681,33 +2664,36 @@ struct ZSTD_CDict_s {
|
|||||||
void* dictContent;
|
void* dictContent;
|
||||||
size_t dictContentSize;
|
size_t dictContentSize;
|
||||||
ZSTD_CCtx* refContext;
|
ZSTD_CCtx* refContext;
|
||||||
}; /* typedef'd tp ZSTD_CDict within zstd.h */
|
}; /* typedef'd tp ZSTD_CDict within "zstd.h" */
|
||||||
|
|
||||||
|
size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
|
||||||
|
{
|
||||||
|
if (cdict==NULL) return 0; /* support sizeof on NULL */
|
||||||
|
return ZSTD_sizeof_CCtx(cdict->refContext) + cdict->dictContentSize;
|
||||||
|
}
|
||||||
|
|
||||||
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, ZSTD_parameters params, ZSTD_customMem customMem)
|
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, ZSTD_parameters params, ZSTD_customMem customMem)
|
||||||
{
|
{
|
||||||
if (!customMem.customAlloc && !customMem.customFree)
|
if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
|
||||||
customMem = defaultCustomMem;
|
if (!customMem.customAlloc || !customMem.customFree) return NULL;
|
||||||
|
|
||||||
if (!customMem.customAlloc || !customMem.customFree) /* can't have 1/2 custom alloc/free as NULL */
|
{ ZSTD_CDict* const cdict = (ZSTD_CDict*) ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
|
||||||
return NULL;
|
void* const dictContent = ZSTD_malloc(dictSize, customMem);
|
||||||
|
|
||||||
{ 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);
|
ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
|
||||||
|
|
||||||
if (!dictContent || !cdict || !cctx) {
|
if (!dictContent || !cdict || !cctx) {
|
||||||
customMem.customFree(customMem.opaque, dictContent);
|
ZSTD_free(dictContent, customMem);
|
||||||
customMem.customFree(customMem.opaque, cdict);
|
ZSTD_free(cdict, customMem);
|
||||||
customMem.customFree(customMem.opaque, cctx);
|
ZSTD_free(cctx, customMem);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(dictContent, dict, dictSize);
|
memcpy(dictContent, dict, dictSize);
|
||||||
{ size_t const errorCode = ZSTD_compressBegin_advanced(cctx, dictContent, dictSize, params, 0);
|
{ size_t const errorCode = ZSTD_compressBegin_advanced(cctx, dictContent, dictSize, params, 0);
|
||||||
if (ZSTD_isError(errorCode)) {
|
if (ZSTD_isError(errorCode)) {
|
||||||
customMem.customFree(customMem.opaque, dictContent);
|
ZSTD_free(dictContent, customMem);
|
||||||
customMem.customFree(customMem.opaque, cdict);
|
ZSTD_free(cdict, customMem);
|
||||||
customMem.customFree(customMem.opaque, cctx);
|
ZSTD_free(cctx, customMem);
|
||||||
return NULL;
|
return NULL;
|
||||||
} }
|
} }
|
||||||
|
|
||||||
@@ -2728,11 +2714,19 @@ ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionL
|
|||||||
|
|
||||||
size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
|
size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
|
||||||
{
|
{
|
||||||
ZSTD_freeFunction const cFree = cdict->refContext->customMem.customFree;
|
if (cdict==NULL) return 0; /* support free on NULL */
|
||||||
void* const opaque = cdict->refContext->customMem.opaque;
|
{ ZSTD_customMem const cMem = cdict->refContext->customMem;
|
||||||
ZSTD_freeCCtx(cdict->refContext);
|
ZSTD_freeCCtx(cdict->refContext);
|
||||||
cFree(opaque, cdict->dictContent);
|
ZSTD_free(cdict->dictContent, cMem);
|
||||||
cFree(opaque, cdict);
|
ZSTD_free(cdict, cMem);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict, U64 pledgedSrcSize)
|
||||||
|
{
|
||||||
|
if (cdict->dictContentSize) CHECK_F(ZSTD_copyCCtx(cctx, cdict->refContext, pledgedSrcSize))
|
||||||
|
else CHECK_F(ZSTD_compressBegin_advanced(cctx, NULL, 0, cdict->refContext->params, pledgedSrcSize));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2740,13 +2734,12 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
|
|||||||
* Compression using a digested Dictionary.
|
* Compression using a digested Dictionary.
|
||||||
* Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.
|
* Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.
|
||||||
* Note that compression level is decided during dictionary creation */
|
* Note that compression level is decided during dictionary creation */
|
||||||
ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
|
size_t ZSTD_compress_usingCDict(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,
|
||||||
const ZSTD_CDict* cdict)
|
const ZSTD_CDict* cdict)
|
||||||
{
|
{
|
||||||
size_t const errorCode = ZSTD_copyCCtx(cctx, cdict->refContext);
|
CHECK_F(ZSTD_compressBegin_usingCDict(cctx, cdict, srcSize));
|
||||||
if (ZSTD_isError(errorCode)) return errorCode;
|
|
||||||
|
|
||||||
if (cdict->refContext->params.fParams.contentSizeFlag==1) {
|
if (cdict->refContext->params.fParams.contentSizeFlag==1) {
|
||||||
cctx->params.fParams.contentSizeFlag = 1;
|
cctx->params.fParams.contentSizeFlag = 1;
|
||||||
@@ -2765,7 +2758,8 @@ ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
|
|||||||
typedef enum { zcss_init, zcss_load, zcss_flush, zcss_final } ZSTD_cStreamStage;
|
typedef enum { zcss_init, zcss_load, zcss_flush, zcss_final } ZSTD_cStreamStage;
|
||||||
|
|
||||||
struct ZSTD_CStream_s {
|
struct ZSTD_CStream_s {
|
||||||
ZSTD_CCtx* zc;
|
ZSTD_CCtx* cctx;
|
||||||
|
ZSTD_CDict* cdict;
|
||||||
char* inBuff;
|
char* inBuff;
|
||||||
size_t inBuffSize;
|
size_t inBuffSize;
|
||||||
size_t inToCompress;
|
size_t inToCompress;
|
||||||
@@ -2791,29 +2785,29 @@ ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem)
|
|||||||
{
|
{
|
||||||
ZSTD_CStream* zcs;
|
ZSTD_CStream* zcs;
|
||||||
|
|
||||||
if (!customMem.customAlloc && !customMem.customFree)
|
if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
|
||||||
customMem = defaultCustomMem;
|
if (!customMem.customAlloc || !customMem.customFree) return NULL;
|
||||||
|
|
||||||
if (!customMem.customAlloc || !customMem.customFree)
|
zcs = (ZSTD_CStream*)ZSTD_malloc(sizeof(ZSTD_CStream), customMem);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
zcs = (ZSTD_CStream*)customMem.customAlloc(customMem.opaque, sizeof(ZSTD_CStream));
|
|
||||||
if (zcs==NULL) return NULL;
|
if (zcs==NULL) return NULL;
|
||||||
memset(zcs, 0, sizeof(ZSTD_CStream));
|
memset(zcs, 0, sizeof(ZSTD_CStream));
|
||||||
memcpy(&zcs->customMem, &customMem, sizeof(ZSTD_customMem));
|
memcpy(&zcs->customMem, &customMem, sizeof(ZSTD_customMem));
|
||||||
zcs->zc = ZSTD_createCCtx_advanced(customMem);
|
zcs->cctx = ZSTD_createCCtx_advanced(customMem);
|
||||||
if (zcs->zc == NULL) { ZSTD_freeCStream(zcs); return NULL; }
|
if (zcs->cctx == NULL) { ZSTD_freeCStream(zcs); return NULL; }
|
||||||
return zcs;
|
return zcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
|
size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
|
||||||
{
|
{
|
||||||
if (zcs==NULL) return 0; /* support free on NULL */
|
if (zcs==NULL) return 0; /* support free on NULL */
|
||||||
ZSTD_freeCCtx(zcs->zc);
|
{ ZSTD_customMem const cMem = zcs->customMem;
|
||||||
if (zcs->inBuff) zcs->customMem.customFree(zcs->customMem.opaque, zcs->inBuff);
|
ZSTD_freeCCtx(zcs->cctx);
|
||||||
if (zcs->outBuff) zcs->customMem.customFree(zcs->customMem.opaque, zcs->outBuff);
|
ZSTD_freeCDict(zcs->cdict);
|
||||||
zcs->customMem.customFree(zcs->customMem.opaque, zcs);
|
ZSTD_free(zcs->inBuff, cMem);
|
||||||
return 0;
|
ZSTD_free(zcs->outBuff, cMem);
|
||||||
|
ZSTD_free(zcs, cMem);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2822,6 +2816,19 @@ size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
|
|||||||
size_t ZSTD_CStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
|
size_t ZSTD_CStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
|
||||||
size_t ZSTD_CStreamOutSize(void) { return ZSTD_compressBound(ZSTD_BLOCKSIZE_ABSOLUTEMAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ; }
|
size_t ZSTD_CStreamOutSize(void) { return ZSTD_compressBound(ZSTD_BLOCKSIZE_ABSOLUTEMAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ; }
|
||||||
|
|
||||||
|
size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
|
||||||
|
{
|
||||||
|
CHECK_F(ZSTD_compressBegin_usingCDict(zcs->cctx, zcs->cdict, pledgedSrcSize));
|
||||||
|
|
||||||
|
zcs->inToCompress = 0;
|
||||||
|
zcs->inBuffPos = 0;
|
||||||
|
zcs->inBuffTarget = zcs->blockSize;
|
||||||
|
zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
|
||||||
|
zcs->stage = zcss_load;
|
||||||
|
zcs->frameEnded = 0;
|
||||||
|
return 0; /* ready to go */
|
||||||
|
}
|
||||||
|
|
||||||
size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
|
size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
|
||||||
const void* dict, size_t dictSize,
|
const void* dict, size_t dictSize,
|
||||||
ZSTD_parameters params, unsigned long long pledgedSrcSize)
|
ZSTD_parameters params, unsigned long long pledgedSrcSize)
|
||||||
@@ -2830,30 +2837,26 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
|
|||||||
{ size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
|
{ size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
|
||||||
if (zcs->inBuffSize < neededInBuffSize) {
|
if (zcs->inBuffSize < neededInBuffSize) {
|
||||||
zcs->inBuffSize = neededInBuffSize;
|
zcs->inBuffSize = neededInBuffSize;
|
||||||
zcs->customMem.customFree(zcs->customMem.opaque, zcs->inBuff); /* should not be necessary */
|
ZSTD_free(zcs->inBuff, zcs->customMem);
|
||||||
zcs->inBuff = (char*)zcs->customMem.customAlloc(zcs->customMem.opaque, neededInBuffSize);
|
zcs->inBuff = (char*) ZSTD_malloc(neededInBuffSize, zcs->customMem);
|
||||||
if (zcs->inBuff == NULL) return ERROR(memory_allocation);
|
if (zcs->inBuff == NULL) return ERROR(memory_allocation);
|
||||||
}
|
}
|
||||||
zcs->blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, neededInBuffSize);
|
zcs->blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, neededInBuffSize);
|
||||||
}
|
}
|
||||||
if (zcs->outBuffSize < ZSTD_compressBound(zcs->blockSize)+1) {
|
if (zcs->outBuffSize < ZSTD_compressBound(zcs->blockSize)+1) {
|
||||||
zcs->outBuffSize = ZSTD_compressBound(zcs->blockSize)+1;
|
zcs->outBuffSize = ZSTD_compressBound(zcs->blockSize)+1;
|
||||||
zcs->customMem.customFree(zcs->customMem.opaque, zcs->outBuff); /* should not be necessary */
|
ZSTD_free(zcs->outBuff, zcs->customMem);
|
||||||
zcs->outBuff = (char*)zcs->customMem.customAlloc(zcs->customMem.opaque, zcs->outBuffSize);
|
zcs->outBuff = (char*) ZSTD_malloc(zcs->outBuffSize, zcs->customMem);
|
||||||
if (zcs->outBuff == NULL) return ERROR(memory_allocation);
|
if (zcs->outBuff == NULL) return ERROR(memory_allocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
{ size_t const errorCode = ZSTD_compressBegin_advanced(zcs->zc, dict, dictSize, params, pledgedSrcSize);
|
ZSTD_freeCDict(zcs->cdict);
|
||||||
if (ZSTD_isError(errorCode)) return errorCode; }
|
zcs->cdict = ZSTD_createCDict_advanced(dict, dictSize, params, zcs->customMem);
|
||||||
|
if (zcs->cdict == NULL) return ERROR(memory_allocation);
|
||||||
|
|
||||||
zcs->inToCompress = 0;
|
|
||||||
zcs->inBuffPos = 0;
|
|
||||||
zcs->inBuffTarget = zcs->blockSize;
|
|
||||||
zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
|
|
||||||
zcs->stage = zcss_load;
|
|
||||||
zcs->checksum = params.fParams.checksumFlag > 0;
|
zcs->checksum = params.fParams.checksumFlag > 0;
|
||||||
zcs->frameEnded = 0;
|
|
||||||
return 0; /* ready to go */
|
return ZSTD_resetCStream(zcs, pledgedSrcSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
|
size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
|
||||||
@@ -2867,6 +2870,11 @@ size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
|
|||||||
return ZSTD_initCStream_usingDict(zcs, NULL, 0, compressionLevel);
|
return ZSTD_initCStream_usingDict(zcs, NULL, 0, compressionLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
|
||||||
|
{
|
||||||
|
if (zcs==NULL) return 0; /* support sizeof on NULL */
|
||||||
|
return sizeof(zcs) + ZSTD_sizeof_CCtx(zcs->cctx) + ZSTD_sizeof_CDict(zcs->cdict) + zcs->outBuffSize + zcs->inBuffSize;
|
||||||
|
}
|
||||||
|
|
||||||
/*====== Compression ======*/
|
/*====== Compression ======*/
|
||||||
|
|
||||||
@@ -2916,8 +2924,8 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
|
|||||||
else
|
else
|
||||||
cDst = zcs->outBuff, oSize = zcs->outBuffSize;
|
cDst = zcs->outBuff, oSize = zcs->outBuffSize;
|
||||||
cSize = (flush == zsf_end) ?
|
cSize = (flush == zsf_end) ?
|
||||||
ZSTD_compressEnd(zcs->zc, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize) :
|
ZSTD_compressEnd(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize) :
|
||||||
ZSTD_compressContinue(zcs->zc, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize);
|
ZSTD_compressContinue(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize);
|
||||||
if (ZSTD_isError(cSize)) return cSize;
|
if (ZSTD_isError(cSize)) return cSize;
|
||||||
if (flush == zsf_end) zcs->frameEnded = 1;
|
if (flush == zsf_end) zcs->frameEnded = 1;
|
||||||
/* prepare next block */
|
/* prepare next block */
|
||||||
@@ -2982,8 +2990,8 @@ size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
|
|||||||
size_t srcSize = 0;
|
size_t srcSize = 0;
|
||||||
size_t sizeWritten = output->size - output->pos;
|
size_t sizeWritten = output->size - output->pos;
|
||||||
size_t const result = ZSTD_compressStream_generic(zcs,
|
size_t const result = ZSTD_compressStream_generic(zcs,
|
||||||
(char*)(output->dst) + output->pos, &sizeWritten,
|
(char*)(output->dst) + output->pos, &sizeWritten,
|
||||||
&srcSize, &srcSize, /* use a valid src address instead of NULL */
|
&srcSize, &srcSize, /* use a valid src address instead of NULL */
|
||||||
zsf_flush);
|
zsf_flush);
|
||||||
output->pos += sizeWritten;
|
output->pos += sizeWritten;
|
||||||
if (ZSTD_isError(result)) return result;
|
if (ZSTD_isError(result)) return result;
|
||||||
@@ -3011,7 +3019,7 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
|
|||||||
/* create epilogue */
|
/* create epilogue */
|
||||||
zcs->stage = zcss_final;
|
zcs->stage = zcss_final;
|
||||||
zcs->outBuffContentSize = !notEnded ? 0 :
|
zcs->outBuffContentSize = !notEnded ? 0 :
|
||||||
ZSTD_compressEnd(zcs->zc, zcs->outBuff, zcs->outBuffSize, NULL, 0); /* write epilogue, including final empty block, into outBuff */
|
ZSTD_compressEnd(zcs->cctx, zcs->outBuff, zcs->outBuffSize, NULL, 0); /* write epilogue, including final empty block, into outBuff */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* flush epilogue */
|
/* flush epilogue */
|
||||||
@@ -3036,15 +3044,15 @@ int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
|
|||||||
static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
|
static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
|
||||||
{ /* "default" */
|
{ /* "default" */
|
||||||
/* W, C, H, S, L, TL, strat */
|
/* W, C, H, S, L, TL, strat */
|
||||||
{ 18, 12, 12, 1, 7, 16, ZSTD_fast }, /* level 0 - not used */
|
{ 18, 12, 12, 1, 7, 16, ZSTD_fast }, /* level 0 - never used */
|
||||||
{ 19, 13, 14, 1, 7, 16, ZSTD_fast }, /* level 1 */
|
{ 19, 13, 14, 1, 7, 16, ZSTD_fast }, /* level 1 */
|
||||||
{ 19, 15, 16, 1, 6, 16, ZSTD_fast }, /* level 2 */
|
{ 19, 15, 16, 1, 6, 16, ZSTD_fast }, /* level 2 */
|
||||||
{ 20, 16, 18, 1, 5, 16, ZSTD_dfast }, /* level 3 */
|
{ 20, 16, 17, 1, 5, 16, ZSTD_dfast }, /* level 3.*/
|
||||||
{ 20, 13, 17, 2, 5, 16, ZSTD_greedy }, /* level 4.*/
|
{ 20, 18, 18, 1, 5, 16, ZSTD_dfast }, /* level 4.*/
|
||||||
{ 20, 15, 18, 3, 5, 16, ZSTD_greedy }, /* level 5 */
|
{ 20, 15, 18, 3, 5, 16, ZSTD_greedy }, /* level 5 */
|
||||||
{ 21, 16, 19, 2, 5, 16, ZSTD_lazy }, /* level 6 */
|
{ 21, 16, 19, 2, 5, 16, ZSTD_lazy }, /* level 6 */
|
||||||
{ 21, 17, 20, 3, 5, 16, ZSTD_lazy }, /* level 7 */
|
{ 21, 17, 20, 3, 5, 16, ZSTD_lazy }, /* level 7 */
|
||||||
{ 21, 18, 20, 3, 5, 16, ZSTD_lazy2 }, /* level 8.*/
|
{ 21, 18, 20, 3, 5, 16, ZSTD_lazy2 }, /* level 8 */
|
||||||
{ 21, 20, 20, 3, 5, 16, ZSTD_lazy2 }, /* level 9 */
|
{ 21, 20, 20, 3, 5, 16, ZSTD_lazy2 }, /* level 9 */
|
||||||
{ 21, 19, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 10 */
|
{ 21, 19, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 10 */
|
||||||
{ 22, 20, 22, 4, 5, 16, ZSTD_lazy2 }, /* level 11 */
|
{ 22, 20, 22, 4, 5, 16, ZSTD_lazy2 }, /* level 11 */
|
||||||
@@ -3053,33 +3061,33 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
|
|||||||
{ 22, 21, 22, 6, 5, 16, ZSTD_lazy2 }, /* level 14 */
|
{ 22, 21, 22, 6, 5, 16, ZSTD_lazy2 }, /* level 14 */
|
||||||
{ 22, 21, 21, 5, 5, 16, ZSTD_btlazy2 }, /* level 15 */
|
{ 22, 21, 21, 5, 5, 16, ZSTD_btlazy2 }, /* level 15 */
|
||||||
{ 23, 22, 22, 5, 5, 16, ZSTD_btlazy2 }, /* level 16 */
|
{ 23, 22, 22, 5, 5, 16, ZSTD_btlazy2 }, /* level 16 */
|
||||||
{ 23, 23, 22, 5, 5, 16, ZSTD_btlazy2 }, /* level 17.*/
|
{ 23, 21, 22, 4, 5, 24, ZSTD_btopt }, /* level 17 */
|
||||||
{ 23, 23, 22, 6, 5, 24, ZSTD_btopt }, /* level 18.*/
|
{ 23, 23, 22, 6, 5, 32, ZSTD_btopt }, /* level 18 */
|
||||||
{ 23, 23, 22, 6, 3, 48, ZSTD_btopt }, /* level 19.*/
|
{ 23, 23, 22, 6, 3, 48, ZSTD_btopt }, /* level 19 */
|
||||||
{ 25, 26, 23, 7, 3, 64, ZSTD_btopt }, /* level 20.*/
|
{ 25, 25, 23, 7, 3, 64, ZSTD_btopt }, /* level 20 */
|
||||||
{ 26, 26, 23, 7, 3,256, ZSTD_btopt }, /* level 21.*/
|
{ 26, 26, 23, 7, 3,256, ZSTD_btopt }, /* level 21 */
|
||||||
{ 27, 27, 25, 9, 3,512, ZSTD_btopt }, /* level 22.*/
|
{ 27, 27, 25, 9, 3,512, ZSTD_btopt }, /* level 22 */
|
||||||
},
|
},
|
||||||
{ /* for srcSize <= 256 KB */
|
{ /* for srcSize <= 256 KB */
|
||||||
/* W, C, H, S, L, T, strat */
|
/* W, C, H, S, L, T, strat */
|
||||||
{ 18, 12, 12, 1, 7, 4, ZSTD_fast }, /* level 0 - not used */
|
{ 0, 0, 0, 0, 0, 0, ZSTD_fast }, /* level 0 - not used */
|
||||||
{ 18, 13, 14, 1, 6, 4, ZSTD_fast }, /* level 1 */
|
{ 18, 13, 14, 1, 6, 8, ZSTD_fast }, /* level 1 */
|
||||||
{ 18, 15, 17, 1, 5, 4, ZSTD_fast }, /* level 2 */
|
{ 18, 14, 13, 1, 5, 8, ZSTD_dfast }, /* level 2 */
|
||||||
{ 18, 13, 15, 1, 5, 4, ZSTD_greedy }, /* level 3.*/
|
{ 18, 16, 15, 1, 5, 8, ZSTD_dfast }, /* level 3 */
|
||||||
{ 18, 15, 17, 1, 5, 4, ZSTD_greedy }, /* level 4.*/
|
{ 18, 15, 17, 1, 5, 8, ZSTD_greedy }, /* level 4.*/
|
||||||
{ 18, 16, 17, 4, 5, 4, ZSTD_greedy }, /* level 5 */
|
{ 18, 16, 17, 4, 5, 8, ZSTD_greedy }, /* level 5.*/
|
||||||
{ 18, 17, 17, 5, 5, 4, ZSTD_greedy }, /* level 6 */
|
{ 18, 16, 17, 3, 5, 8, ZSTD_lazy }, /* level 6.*/
|
||||||
{ 18, 17, 17, 4, 4, 4, ZSTD_lazy }, /* level 7 */
|
{ 18, 17, 17, 4, 4, 8, ZSTD_lazy }, /* level 7 */
|
||||||
{ 18, 17, 17, 4, 4, 4, ZSTD_lazy2 }, /* level 8 */
|
{ 18, 17, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */
|
||||||
{ 18, 17, 17, 5, 4, 4, ZSTD_lazy2 }, /* level 9 */
|
{ 18, 17, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */
|
||||||
{ 18, 17, 17, 6, 4, 4, ZSTD_lazy2 }, /* level 10 */
|
{ 18, 17, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */
|
||||||
{ 18, 18, 17, 6, 4, 4, ZSTD_lazy2 }, /* level 11.*/
|
{ 18, 18, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 11.*/
|
||||||
{ 18, 18, 17, 7, 4, 4, ZSTD_lazy2 }, /* level 12.*/
|
{ 18, 18, 17, 7, 4, 8, ZSTD_lazy2 }, /* level 12.*/
|
||||||
{ 18, 19, 17, 7, 4, 4, ZSTD_btlazy2 }, /* level 13 */
|
{ 18, 19, 17, 6, 4, 8, ZSTD_btlazy2 }, /* level 13 */
|
||||||
{ 18, 18, 18, 4, 4, 16, ZSTD_btopt }, /* level 14.*/
|
{ 18, 18, 18, 4, 4, 16, ZSTD_btopt }, /* level 14.*/
|
||||||
{ 18, 18, 18, 8, 4, 24, ZSTD_btopt }, /* level 15.*/
|
{ 18, 18, 18, 4, 3, 16, ZSTD_btopt }, /* level 15.*/
|
||||||
{ 18, 19, 18, 8, 3, 48, ZSTD_btopt }, /* level 16.*/
|
{ 18, 19, 18, 6, 3, 32, ZSTD_btopt }, /* level 16.*/
|
||||||
{ 18, 19, 18, 8, 3, 96, ZSTD_btopt }, /* level 17.*/
|
{ 18, 19, 18, 8, 3, 64, ZSTD_btopt }, /* level 17.*/
|
||||||
{ 18, 19, 18, 9, 3,128, ZSTD_btopt }, /* level 18.*/
|
{ 18, 19, 18, 9, 3,128, ZSTD_btopt }, /* level 18.*/
|
||||||
{ 18, 19, 18, 10, 3,256, ZSTD_btopt }, /* level 19.*/
|
{ 18, 19, 18, 10, 3,256, ZSTD_btopt }, /* level 19.*/
|
||||||
{ 18, 19, 18, 11, 3,512, ZSTD_btopt }, /* level 20.*/
|
{ 18, 19, 18, 11, 3,512, ZSTD_btopt }, /* level 20.*/
|
||||||
|
|||||||
+13
-138
@@ -1,35 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
ZSTD Optimal mode
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) 2016, Przemyslaw Skibinski, Yann Collet.
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Note : this file is intended to be included within zstd_compress.c */
|
/* Note : this file is intended to be included within zstd_compress.c */
|
||||||
|
|
||||||
@@ -199,7 +176,6 @@ MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const B
|
|||||||
opt[pos].off = offset_; \
|
opt[pos].off = offset_; \
|
||||||
opt[pos].litlen = litlen_; \
|
opt[pos].litlen = litlen_; \
|
||||||
opt[pos].price = price_; \
|
opt[pos].price = price_; \
|
||||||
ZSTD_LOG_PARSER("%d: SET price[%d/%d]=%d litlen=%d len=%d off=%d\n", (int)(inr-base), (int)pos, (int)last_pos, opt[pos].price, opt[pos].litlen, opt[pos].mlen, opt[pos].off); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -295,25 +271,11 @@ static U32 ZSTD_insertBtAndGetAllMatches (
|
|||||||
if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
|
if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
|
||||||
match = base + matchIndex;
|
match = base + matchIndex;
|
||||||
if (match[matchLength] == ip[matchLength]) {
|
if (match[matchLength] == ip[matchLength]) {
|
||||||
#if ZSTD_OPT_DEBUG >= 5
|
|
||||||
size_t ml;
|
|
||||||
if (matchIndex < dictLimit)
|
|
||||||
ml = ZSTD_count_2segments(ip, dictBase + matchIndex, iLimit, dictEnd, prefixStart);
|
|
||||||
else
|
|
||||||
ml = ZSTD_count(ip, match, ip+matchLength);
|
|
||||||
if (ml < matchLength)
|
|
||||||
printf("%d: ERROR_NOEXT: offset=%d matchLength=%d matchIndex=%d dictLimit=%d ml=%d\n", current, (int)(current - matchIndex), (int)matchLength, (int)matchIndex, (int)dictLimit, (int)ml), exit(0);
|
|
||||||
#endif
|
|
||||||
matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iLimit) +1;
|
matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iLimit) +1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match = dictBase + matchIndex;
|
match = dictBase + matchIndex;
|
||||||
#if ZSTD_OPT_DEBUG >= 5
|
|
||||||
if (memcmp(match, ip, matchLength) != 0)
|
|
||||||
printf("%d: ERROR_EXT: matchLength=%d ZSTD_count=%d\n", current, (int)matchLength, (int)ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart)), exit(0);
|
|
||||||
#endif
|
|
||||||
matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart);
|
matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart);
|
||||||
ZSTD_LOG_PARSER("%d: ZSTD_INSERTBTANDGETALLMATCHES=%d offset=%d dictBase=%p dictEnd=%p prefixStart=%p ip=%p match=%p\n", (int)current, (int)matchLength, (int)(current - matchIndex), dictBase, dictEnd, prefixStart, ip, match);
|
|
||||||
if (matchIndex+matchLength >= dictLimit)
|
if (matchIndex+matchLength >= dictLimit)
|
||||||
match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
|
match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
|
||||||
}
|
}
|
||||||
@@ -441,8 +403,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) rep[i]=ctx->rep[i]; }
|
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) rep[i]=ctx->rep[i]; }
|
||||||
inr = ip;
|
inr = ip;
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* Match Loop */
|
/* Match Loop */
|
||||||
while (ip < ilimit) {
|
while (ip < ilimit) {
|
||||||
U32 cur, match_num, last_pos, litlen, price;
|
U32 cur, match_num, last_pos, litlen, price;
|
||||||
@@ -458,7 +418,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
if ( (repCur > 0) && (repCur < (S32)(ip-prefixStart))
|
if ( (repCur > 0) && (repCur < (S32)(ip-prefixStart))
|
||||||
&& (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(ip - repCur, minMatch))) {
|
&& (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(ip - repCur, minMatch))) {
|
||||||
mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repCur, iend) + minMatch;
|
mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repCur, iend) + minMatch;
|
||||||
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;
|
||||||
@@ -474,7 +433,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
|
|
||||||
match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, ip, iend, maxSearches, mls, matches, minMatch);
|
match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, ip, iend, maxSearches, mls, matches, minMatch);
|
||||||
|
|
||||||
ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos);
|
|
||||||
if (!last_pos && !match_num) { ip++; continue; }
|
if (!last_pos && !match_num) { ip++; continue; }
|
||||||
|
|
||||||
if (match_num && (matches[match_num-1].len > sufficient_len || matches[match_num-1].len >= ZSTD_OPT_NUM)) {
|
if (match_num && (matches[match_num-1].len > sufficient_len || matches[match_num-1].len >= ZSTD_OPT_NUM)) {
|
||||||
@@ -490,7 +448,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
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);
|
|
||||||
while (mlen <= best_mlen) {
|
while (mlen <= best_mlen) {
|
||||||
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH);
|
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH);
|
||||||
if (mlen > last_pos || price < opt[mlen].price)
|
if (mlen > last_pos || price < opt[mlen].price)
|
||||||
@@ -520,7 +477,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1);
|
price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen)))
|
if (cur > last_pos || price <= opt[cur].price)
|
||||||
SET_PRICE(cur, 1, 0, litlen, price);
|
SET_PRICE(cur, 1, 0, litlen, price);
|
||||||
|
|
||||||
if (cur == last_pos) break;
|
if (cur == last_pos) break;
|
||||||
@@ -529,20 +486,16 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
mlen = opt[cur].mlen;
|
mlen = opt[cur].mlen;
|
||||||
if (opt[cur].off > ZSTD_REP_MOVE_OPT) {
|
if (opt[cur].off > ZSTD_REP_MOVE_OPT) {
|
||||||
opt[cur].rep[2] = opt[cur-mlen].rep[1];
|
opt[cur].rep[2] = opt[cur-mlen].rep[1];
|
||||||
opt[cur].rep[1] = opt[cur-mlen].rep[0];
|
opt[cur].rep[1] = opt[cur-mlen].rep[0];
|
||||||
opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT;
|
opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT;
|
||||||
ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]);
|
|
||||||
} else {
|
} else {
|
||||||
opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2];
|
opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2];
|
||||||
opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1];
|
opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1];
|
||||||
opt[cur].rep[0] = ((opt[cur].off==ZSTD_REP_MOVE_OPT) && (mlen != 1)) ? (opt[cur-mlen].rep[0] - 1) : (opt[cur-mlen].rep[opt[cur].off]);
|
opt[cur].rep[0] = ((opt[cur].off==ZSTD_REP_MOVE_OPT) && (mlen != 1)) ? (opt[cur-mlen].rep[0] - 1) : (opt[cur-mlen].rep[opt[cur].off]);
|
||||||
ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, 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, last_i = ZSTD_REP_CHECK + (mlen != 1);
|
{ U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
|
||||||
for (i=(opt[cur].mlen != 1); i<last_i; i++) { /* check rep */
|
for (i=(opt[cur].mlen != 1); i<last_i; i++) { /* check rep */
|
||||||
@@ -550,15 +503,12 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
if ( (repCur > 0) && (repCur < (S32)(inr-prefixStart))
|
if ( (repCur > 0) && (repCur < (S32)(inr-prefixStart))
|
||||||
&& (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(inr - repCur, minMatch))) {
|
&& (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(inr - repCur, minMatch))) {
|
||||||
mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - repCur, iend) + minMatch;
|
mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - repCur, 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) {
|
||||||
best_mlen = mlen; best_off = i; last_pos = cur + 1;
|
best_mlen = mlen; best_off = i; last_pos = cur + 1;
|
||||||
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);
|
|
||||||
goto _storeSequence;
|
goto _storeSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
//best_off = ((i<=1) & (opt[cur].mlen != 1)) ? 1-i : i;
|
|
||||||
best_off = i - (opt[cur].mlen != 1);
|
best_off = i - (opt[cur].mlen != 1);
|
||||||
|
|
||||||
if (opt[cur].mlen == 1) {
|
if (opt[cur].mlen == 1) {
|
||||||
@@ -573,7 +523,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
|
if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
|
||||||
@@ -583,7 +532,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
} } }
|
} } }
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (match_num > 0 && (matches[match_num-1].len > sufficient_len || cur + matches[match_num-1].len >= ZSTD_OPT_NUM)) {
|
if (match_num > 0 && (matches[match_num-1].len > sufficient_len || cur + matches[match_num-1].len >= ZSTD_OPT_NUM)) {
|
||||||
best_mlen = matches[match_num-1].len;
|
best_mlen = matches[match_num-1].len;
|
||||||
@@ -597,7 +545,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
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: Found1 cur=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(inr-base), cur, matches[u].len, matches[u].off, best_mlen, last_pos);
|
|
||||||
while (mlen <= best_mlen) {
|
while (mlen <= best_mlen) {
|
||||||
if (opt[cur].mlen == 1) {
|
if (opt[cur].mlen == 1) {
|
||||||
litlen = opt[cur].litlen;
|
litlen = opt[cur].litlen;
|
||||||
@@ -610,12 +557,11 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off-1, mlen - MINMATCH);
|
price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off-1, mlen - MINMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ZSTD_LOG_PARSER("%d: Found2 mlen=%d best_mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_mlen, matches[u].off, price, litlen);
|
|
||||||
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, matches[u].off, litlen, price);
|
SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price);
|
||||||
|
|
||||||
mlen++;
|
mlen++;
|
||||||
} } } // for (cur = 1; cur <= last_pos; cur++)
|
} } }
|
||||||
|
|
||||||
best_mlen = opt[last_pos].mlen;
|
best_mlen = opt[last_pos].mlen;
|
||||||
best_off = opt[last_pos].off;
|
best_off = opt[last_pos].off;
|
||||||
@@ -623,10 +569,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
|
|||||||
|
|
||||||
/* store sequence */
|
/* store sequence */
|
||||||
_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
|
_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
|
||||||
for (u = 1; u <= last_pos; u++)
|
|
||||||
ZSTD_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep[0], opt[u].rep[1]);
|
|
||||||
ZSTD_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep[0]=%d\n", (int)(ip-base+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep[0]);
|
|
||||||
|
|
||||||
opt[0].mlen = 1;
|
opt[0].mlen = 1;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -641,18 +583,15 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (u = 0; u <= last_pos;) {
|
for (u = 0; u <= last_pos;) {
|
||||||
ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep[0], opt[u].rep[1]);
|
|
||||||
u += opt[u].mlen;
|
u += opt[u].mlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (cur=0; cur < last_pos; ) {
|
for (cur=0; cur < last_pos; ) {
|
||||||
ZSTD_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]);
|
|
||||||
mlen = opt[cur].mlen;
|
mlen = opt[cur].mlen;
|
||||||
if (mlen == 1) { ip++; cur++; continue; }
|
if (mlen == 1) { ip++; cur++; continue; }
|
||||||
offset = opt[cur].off;
|
offset = opt[cur].off;
|
||||||
cur += mlen;
|
cur += mlen;
|
||||||
litLength = (U32)(ip - anchor);
|
litLength = (U32)(ip - anchor);
|
||||||
// ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]);
|
|
||||||
|
|
||||||
if (offset > ZSTD_REP_MOVE_OPT) {
|
if (offset > ZSTD_REP_MOVE_OPT) {
|
||||||
rep[2] = rep[1];
|
rep[2] = rep[1];
|
||||||
@@ -666,26 +605,9 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
|
|||||||
rep[1] = rep[0];
|
rep[1] = rep[0];
|
||||||
rep[0] = best_off;
|
rep[0] = best_off;
|
||||||
}
|
}
|
||||||
if ((litLength==0) & (offset==0)) { ZSTD_LOG_ENCODE("ERROR (litLength==0) & (offset==0)\n"); };
|
|
||||||
if (litLength==0) offset--;
|
if (litLength==0) offset--;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]);
|
|
||||||
|
|
||||||
#if ZSTD_OPT_DEBUG >= 5
|
|
||||||
U32 ml2;
|
|
||||||
if (offset+1 > ZSTD_REP_MOVE_OPT)
|
|
||||||
ml2 = (U32)ZSTD_count(ip, ip-(offset+1-ZSTD_REP_MOVE_OPT), iend);
|
|
||||||
else
|
|
||||||
ml2 = (U32)ZSTD_count(ip, ip-rep[0], iend);
|
|
||||||
if ((offset >= 8) && (ml2 < mlen || ml2 < minMatch)) {
|
|
||||||
printf("%d: ERROR_NoExt iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); exit(0); }
|
|
||||||
if (ip < anchor) {
|
|
||||||
printf("%d: ERROR_NoExt ip < anchor iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); exit(0); }
|
|
||||||
if (ip + mlen > iend) {
|
|
||||||
printf("%d: ERROR_NoExt ip + mlen >= iend iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); exit(0); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
|
ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
|
||||||
ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
|
ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
|
||||||
anchor = ip = ip + mlen;
|
anchor = ip = ip + mlen;
|
||||||
@@ -696,7 +618,6 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
|
|||||||
|
|
||||||
/* Last Literals */
|
/* Last Literals */
|
||||||
{ size_t const lastLLSize = iend - anchor;
|
{ size_t const lastLLSize = iend - anchor;
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -738,8 +659,6 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
ip += (ip==prefixStart);
|
ip += (ip==prefixStart);
|
||||||
inr = ip;
|
inr = ip;
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* Match Loop */
|
/* Match Loop */
|
||||||
while (ip < ilimit) {
|
while (ip < ilimit) {
|
||||||
U32 cur, match_num, last_pos, litlen, price;
|
U32 cur, match_num, last_pos, litlen, price;
|
||||||
@@ -764,7 +683,6 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
||||||
mlen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
|
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);
|
|
||||||
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;
|
||||||
@@ -782,7 +700,6 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
|
|
||||||
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) */
|
||||||
|
|
||||||
ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos);
|
|
||||||
if (!last_pos && !match_num) { ip++; continue; }
|
if (!last_pos && !match_num) { ip++; continue; }
|
||||||
|
|
||||||
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) opt[0].rep[i] = rep[i]; }
|
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) opt[0].rep[i] = rep[i]; }
|
||||||
@@ -798,11 +715,10 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
|
|
||||||
best_mlen = (last_pos) ? last_pos : minMatch;
|
best_mlen = (last_pos) ? last_pos : minMatch;
|
||||||
|
|
||||||
// set prices using matches at position = 0
|
/* set prices using matches at position = 0 */
|
||||||
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);
|
|
||||||
litlen = opt[0].litlen;
|
litlen = opt[0].litlen;
|
||||||
while (mlen <= best_mlen) {
|
while (mlen <= best_mlen) {
|
||||||
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH);
|
price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH);
|
||||||
@@ -812,7 +728,6 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
} }
|
} }
|
||||||
|
|
||||||
if (last_pos < minMatch) {
|
if (last_pos < minMatch) {
|
||||||
// ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
|
|
||||||
ip++; continue;
|
ip++; continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -831,7 +746,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1);
|
price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen)))
|
if (cur > last_pos || price <= opt[cur].price)
|
||||||
SET_PRICE(cur, 1, 0, litlen, price);
|
SET_PRICE(cur, 1, 0, litlen, price);
|
||||||
|
|
||||||
if (cur == last_pos) break;
|
if (cur == last_pos) break;
|
||||||
@@ -844,15 +759,12 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
opt[cur].rep[2] = opt[cur-mlen].rep[1];
|
opt[cur].rep[2] = opt[cur-mlen].rep[1];
|
||||||
opt[cur].rep[1] = opt[cur-mlen].rep[0];
|
opt[cur].rep[1] = opt[cur-mlen].rep[0];
|
||||||
opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT;
|
opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT;
|
||||||
ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]);
|
|
||||||
} else {
|
} else {
|
||||||
opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2];
|
opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2];
|
||||||
opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1];
|
opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1];
|
||||||
opt[cur].rep[0] = ((opt[cur].off==ZSTD_REP_MOVE_OPT) && (mlen != 1)) ? (opt[cur-mlen].rep[0] - 1) : (opt[cur-mlen].rep[opt[cur].off]);
|
opt[cur].rep[0] = ((opt[cur].off==ZSTD_REP_MOVE_OPT) && (mlen != 1)) ? (opt[cur-mlen].rep[0] - 1) : (opt[cur-mlen].rep[opt[cur].off]);
|
||||||
ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, 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, last_i = ZSTD_REP_CHECK + (mlen != 1);
|
{ U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
|
||||||
@@ -867,11 +779,9 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
/* repcode detected */
|
/* repcode detected */
|
||||||
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
||||||
mlen = (U32)ZSTD_count_2segments(inr+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
|
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) {
|
||||||
best_mlen = mlen; best_off = i; last_pos = cur + 1;
|
best_mlen = mlen; best_off = i; last_pos = cur + 1;
|
||||||
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);
|
|
||||||
goto _storeSequence;
|
goto _storeSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -888,7 +798,6 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
|
if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
|
||||||
@@ -898,7 +807,6 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
} } }
|
} } }
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (match_num > 0 && matches[match_num-1].len > sufficient_len) {
|
if (match_num > 0 && matches[match_num-1].len > sufficient_len) {
|
||||||
best_mlen = matches[match_num-1].len;
|
best_mlen = matches[match_num-1].len;
|
||||||
@@ -914,7 +822,6 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
|
mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
|
||||||
best_mlen = (cur + matches[u].len < ZSTD_OPT_NUM) ? matches[u].len : ZSTD_OPT_NUM - cur;
|
best_mlen = (cur + matches[u].len < ZSTD_OPT_NUM) ? matches[u].len : ZSTD_OPT_NUM - cur;
|
||||||
|
|
||||||
// ZSTD_LOG_PARSER("%d: Found1 cur=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(inr-base), cur, matches[u].len, matches[u].off, best_mlen, last_pos);
|
|
||||||
while (mlen <= best_mlen) {
|
while (mlen <= best_mlen) {
|
||||||
if (opt[cur].mlen == 1) {
|
if (opt[cur].mlen == 1) {
|
||||||
litlen = opt[cur].litlen;
|
litlen = opt[cur].litlen;
|
||||||
@@ -927,7 +834,6 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off-1, mlen - MINMATCH);
|
price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off-1, mlen - MINMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ZSTD_LOG_PARSER("%d: Found2 mlen=%d best_mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_mlen, matches[u].off, price, litlen);
|
|
||||||
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, matches[u].off, litlen, price);
|
SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price);
|
||||||
|
|
||||||
@@ -940,10 +846,6 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
|
|
||||||
/* store sequence */
|
/* store sequence */
|
||||||
_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
|
_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
|
||||||
for (u = 1; u <= last_pos; u++)
|
|
||||||
ZSTD_LOG_PARSER("%d: price[%u/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep[0], opt[u].rep[1]);
|
|
||||||
ZSTD_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep[0]=%d\n", (int)(ip-base+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep[0]);
|
|
||||||
|
|
||||||
opt[0].mlen = 1;
|
opt[0].mlen = 1;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -958,18 +860,15 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (u = 0; u <= last_pos; ) {
|
for (u = 0; u <= last_pos; ) {
|
||||||
ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep[0], opt[u].rep[1]);
|
|
||||||
u += opt[u].mlen;
|
u += opt[u].mlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (cur=0; cur < last_pos; ) {
|
for (cur=0; cur < last_pos; ) {
|
||||||
ZSTD_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]);
|
|
||||||
mlen = opt[cur].mlen;
|
mlen = opt[cur].mlen;
|
||||||
if (mlen == 1) { ip++; cur++; continue; }
|
if (mlen == 1) { ip++; cur++; continue; }
|
||||||
offset = opt[cur].off;
|
offset = opt[cur].off;
|
||||||
cur += mlen;
|
cur += mlen;
|
||||||
litLength = (U32)(ip - anchor);
|
litLength = (U32)(ip - anchor);
|
||||||
// ZSTD_LOG_ENCODE("%d/%d: ENCODE1 literals=%d mlen=%d off=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]);
|
|
||||||
|
|
||||||
if (offset > ZSTD_REP_MOVE_OPT) {
|
if (offset > ZSTD_REP_MOVE_OPT) {
|
||||||
rep[2] = rep[1];
|
rep[2] = rep[1];
|
||||||
@@ -984,32 +883,9 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
|
|||||||
rep[0] = best_off;
|
rep[0] = best_off;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((litLength==0) & (offset==0)) { ZSTD_LOG_ENCODE("ERROR (litLength==0) & (offset==0)\n"); };
|
|
||||||
if (litLength==0) offset--;
|
if (litLength==0) offset--;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]);
|
|
||||||
|
|
||||||
#if ZSTD_OPT_DEBUG >= 5
|
|
||||||
U32 ml2;
|
|
||||||
if (offset+1 > ZSTD_REP_MOVE_OPT) {
|
|
||||||
best_off = offset+1 - ZSTD_REP_MOVE_OPT;
|
|
||||||
if (best_off > (size_t)(ip - prefixStart)) {
|
|
||||||
const BYTE* match = dictEnd - (best_off - (ip - prefixStart));
|
|
||||||
ml2 = ZSTD_count_2segments(ip, match, iend, dictEnd, prefixStart);
|
|
||||||
ZSTD_LOG_PARSER("%d: ZSTD_count_2segments=%d offset=%d dictBase=%p dictEnd=%p prefixStart=%p ip=%p match=%p\n", (int)current, (int)ml2, (int)best_off, dictBase, dictEnd, prefixStart, ip, match);
|
|
||||||
}
|
|
||||||
else ml2 = (U32)ZSTD_count(ip, ip-best_off, iend);
|
|
||||||
}
|
|
||||||
else ml2 = (U32)ZSTD_count(ip, ip-rep[0], iend);
|
|
||||||
if ((offset >= 8) && (ml2 < mlen || ml2 < minMatch)) {
|
|
||||||
printf("%d: ERROR_Ext iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); exit(0); }
|
|
||||||
if (ip < anchor) {
|
|
||||||
printf("%d: ERROR_Ext ip < anchor iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); exit(0); }
|
|
||||||
if (ip + mlen > iend) {
|
|
||||||
printf("%d: ERROR_Ext ip + mlen >= iend iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); exit(0); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
|
ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
|
||||||
ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
|
ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
|
||||||
anchor = ip = ip + mlen;
|
anchor = ip = ip + mlen;
|
||||||
@@ -1020,7 +896,6 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
|
|||||||
|
|
||||||
/* Last Literals */
|
/* Last Literals */
|
||||||
{ size_t lastLLSize = iend - anchor;
|
{ size_t lastLLSize = iend - anchor;
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,30 +37,22 @@
|
|||||||
****************************************************************/
|
****************************************************************/
|
||||||
#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
||||||
/* inline is defined */
|
/* inline is defined */
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER) || defined(__GNUC__)
|
||||||
# define inline __inline
|
# define inline __inline
|
||||||
#else
|
#else
|
||||||
# define inline /* disable inline */
|
# define inline /* disable inline */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER /* Visual Studio */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
# define FORCE_INLINE static __forceinline
|
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# 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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* **************************************************************
|
/* **************************************************************
|
||||||
* Includes
|
* Dependencies
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
#include <string.h> /* memcpy, memset */
|
#include <string.h> /* memcpy, memset */
|
||||||
#include "bitstream.h"
|
#include "bitstream.h" /* BIT_* */
|
||||||
#include "fse.h" /* header compression */
|
#include "fse.h" /* header compression */
|
||||||
#define HUF_STATIC_LINKING_ONLY
|
#define HUF_STATIC_LINKING_ONLY
|
||||||
#include "huf.h"
|
#include "huf.h"
|
||||||
@@ -103,7 +95,7 @@ size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize)
|
|||||||
HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
|
HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
|
||||||
|
|
||||||
HUF_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable));
|
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_SYMBOLVALUE_MAX + 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;
|
||||||
@@ -388,22 +380,22 @@ static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 co
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* fill DTable */
|
/* fill DTable */
|
||||||
{ U32 s; for (s=0; s<sortedListSize; s++) { /* note : sortedSymbols already skipped */
|
{ U32 s; for (s=0; s<sortedListSize; s++) { /* note : sortedSymbols already skipped */
|
||||||
const U32 symbol = sortedSymbols[s].symbol;
|
const U32 symbol = sortedSymbols[s].symbol;
|
||||||
const U32 weight = sortedSymbols[s].weight;
|
const U32 weight = sortedSymbols[s].weight;
|
||||||
const U32 nbBits = nbBitsBaseline - weight;
|
const U32 nbBits = nbBitsBaseline - weight;
|
||||||
const U32 length = 1 << (sizeLog-nbBits);
|
const U32 length = 1 << (sizeLog-nbBits);
|
||||||
const U32 start = rankVal[weight];
|
const U32 start = rankVal[weight];
|
||||||
U32 i = start;
|
U32 i = start;
|
||||||
const U32 end = start + length;
|
const U32 end = start + length;
|
||||||
|
|
||||||
MEM_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8)));
|
MEM_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8)));
|
||||||
DElt.nbBits = (BYTE)(nbBits + consumed);
|
DElt.nbBits = (BYTE)(nbBits + consumed);
|
||||||
DElt.length = 2;
|
DElt.length = 2;
|
||||||
do { DTable[i++] = DElt; } while (i<end); /* since length >= 1 */
|
do { DTable[i++] = DElt; } while (i<end); /* since length >= 1 */
|
||||||
|
|
||||||
rankVal[weight] += length;
|
rankVal[weight] += length;
|
||||||
}}
|
} }
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef U32 rankVal_t[HUF_TABLELOG_ABSOLUTEMAX][HUF_TABLELOG_ABSOLUTEMAX + 1];
|
typedef U32 rankVal_t[HUF_TABLELOG_ABSOLUTEMAX][HUF_TABLELOG_ABSOLUTEMAX + 1];
|
||||||
@@ -442,8 +434,8 @@ static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog,
|
|||||||
MEM_writeLE16(&(DElt.sequence), symbol);
|
MEM_writeLE16(&(DElt.sequence), symbol);
|
||||||
DElt.nbBits = (BYTE)(nbBits);
|
DElt.nbBits = (BYTE)(nbBits);
|
||||||
DElt.length = 1;
|
DElt.length = 1;
|
||||||
{ U32 u;
|
{ U32 const end = start + length;
|
||||||
const U32 end = start + length;
|
U32 u;
|
||||||
for (u = start; u < end; u++) DTable[u] = DElt;
|
for (u = start; u < end; u++) DTable[u] = DElt;
|
||||||
} }
|
} }
|
||||||
rankVal[weight] += length;
|
rankVal[weight] += length;
|
||||||
@@ -467,7 +459,7 @@ size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize)
|
|||||||
|
|
||||||
HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable)); /* if compilation fails here, assertion is false */
|
HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable)); /* if compilation fails here, assertion is false */
|
||||||
if (maxTableLog > HUF_TABLELOG_ABSOLUTEMAX) return ERROR(tableLog_tooLarge);
|
if (maxTableLog > HUF_TABLELOG_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_SYMBOLVALUE_MAX + 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;
|
||||||
@@ -533,7 +525,7 @@ size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize)
|
|||||||
|
|
||||||
static U32 HUF_decodeSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog)
|
static U32 HUF_decodeSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* 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 */
|
||||||
memcpy(op, dt+val, 2);
|
memcpy(op, dt+val, 2);
|
||||||
BIT_skipBits(DStream, dt[val].nbBits);
|
BIT_skipBits(DStream, dt[val].nbBits);
|
||||||
return dt[val].length;
|
return dt[val].length;
|
||||||
@@ -541,7 +533,7 @@ static U32 HUF_decodeSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4
|
|||||||
|
|
||||||
static U32 HUF_decodeLastSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog)
|
static U32 HUF_decodeLastSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* 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 */
|
||||||
memcpy(op, dt+val, 1);
|
memcpy(op, dt+val, 1);
|
||||||
if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits);
|
if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits);
|
||||||
else {
|
else {
|
||||||
@@ -570,7 +562,7 @@ static inline size_t HUF_decodeStreamX4(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* c
|
|||||||
BYTE* const pStart = p;
|
BYTE* const pStart = p;
|
||||||
|
|
||||||
/* up to 8 symbols at a time */
|
/* up to 8 symbols at a time */
|
||||||
while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p < pEnd-7)) {
|
while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) {
|
||||||
HUF_DECODE_SYMBOLX4_2(p, bitDPtr);
|
HUF_DECODE_SYMBOLX4_2(p, bitDPtr);
|
||||||
HUF_DECODE_SYMBOLX4_1(p, bitDPtr);
|
HUF_DECODE_SYMBOLX4_1(p, bitDPtr);
|
||||||
HUF_DECODE_SYMBOLX4_2(p, bitDPtr);
|
HUF_DECODE_SYMBOLX4_2(p, bitDPtr);
|
||||||
@@ -578,7 +570,7 @@ static inline size_t HUF_decodeStreamX4(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* c
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* closer to end : up to 2 symbols at a time */
|
/* 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);
|
||||||
|
|
||||||
while (p <= pEnd-2)
|
while (p <= pEnd-2)
|
||||||
@@ -697,7 +689,7 @@ static size_t HUF_decompress4X4_usingDTable_internal(
|
|||||||
|
|
||||||
/* 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);
|
||||||
for ( ; (endSignal==BIT_DStream_unfinished) && (op4<(oend-7)) ; ) {
|
for ( ; (endSignal==BIT_DStream_unfinished) & (op4<(oend-(sizeof(bitD4.bitContainer)-1))) ; ) {
|
||||||
HUF_DECODE_SYMBOLX4_2(op1, &bitD1);
|
HUF_DECODE_SYMBOLX4_2(op1, &bitD1);
|
||||||
HUF_DECODE_SYMBOLX4_2(op2, &bitD2);
|
HUF_DECODE_SYMBOLX4_2(op2, &bitD2);
|
||||||
HUF_DECODE_SYMBOLX4_2(op3, &bitD3);
|
HUF_DECODE_SYMBOLX4_2(op3, &bitD3);
|
||||||
@@ -722,7 +714,7 @@ static size_t HUF_decompress4X4_usingDTable_internal(
|
|||||||
if (op1 > opStart2) return ERROR(corruption_detected);
|
if (op1 > opStart2) return ERROR(corruption_detected);
|
||||||
if (op2 > opStart3) return ERROR(corruption_detected);
|
if (op2 > opStart3) return ERROR(corruption_detected);
|
||||||
if (op3 > opStart4) return ERROR(corruption_detected);
|
if (op3 > opStart4) return ERROR(corruption_detected);
|
||||||
/* note : op4 supposed already verified within main loop */
|
/* note : op4 already verified within main loop */
|
||||||
|
|
||||||
/* finish bitStreams one by one */
|
/* finish bitStreams one by one */
|
||||||
HUF_decodeStreamX4(op1, &bitD1, opStart2, dt, dtLog);
|
HUF_decodeStreamX4(op1, &bitD1, opStart2, dt, dtLog);
|
||||||
@@ -848,9 +840,6 @@ size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcS
|
|||||||
{ U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
|
{ U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
|
||||||
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_decompress4X4(dst, dstSize, cSrc, cSrcSize); /* multi-streams double-symbols decoding */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
|
||||||
|
|||||||
@@ -1,33 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
Buffered version of Zstd compression library
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) 2015-2016, Yann Collet.
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
@@ -40,30 +19,6 @@
|
|||||||
#include "zbuff.h"
|
#include "zbuff.h"
|
||||||
|
|
||||||
|
|
||||||
/*-***************************************************************************
|
|
||||||
* Streaming decompression howto
|
|
||||||
*
|
|
||||||
* A ZBUFF_DCtx object is required to track streaming operations.
|
|
||||||
* Use ZBUFF_createDCtx() and ZBUFF_freeDCtx() to create/release resources.
|
|
||||||
* Use ZBUFF_decompressInit() to start a new decompression operation,
|
|
||||||
* or ZBUFF_decompressInitDictionary() if decompression requires a dictionary.
|
|
||||||
* Note that ZBUFF_DCtx objects can be re-init multiple times.
|
|
||||||
*
|
|
||||||
* Use ZBUFF_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 ZBUFF_isError().
|
|
||||||
*
|
|
||||||
* Hint : recommended buffer sizes (not compulsory) : ZBUFF_recommendedDInSize() and ZBUFF_recommendedDOutSize()
|
|
||||||
* output : ZBUFF_recommendedDOutSize==128 KB block size is the internal unit, it ensures it's always possible to write a full block when decoded.
|
|
||||||
* input : ZBUFF_recommendedDInSize == 128KB + 3;
|
|
||||||
* just follow indications from ZBUFF_decompressContinue() to minimize latency. It should always be <= 128 KB + 3 .
|
|
||||||
* *******************************************************************************/
|
|
||||||
|
|
||||||
typedef enum { ZBUFFds_init, ZBUFFds_loadHeader,
|
typedef enum { ZBUFFds_init, ZBUFFds_loadHeader,
|
||||||
ZBUFFds_read, ZBUFFds_load, ZBUFFds_flush } ZBUFF_dStage;
|
ZBUFFds_read, ZBUFFds_load, ZBUFFds_flush } ZBUFF_dStage;
|
||||||
|
|
||||||
@@ -83,7 +38,7 @@ struct ZBUFF_DCtx_s {
|
|||||||
BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
|
BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
|
||||||
size_t lhSize;
|
size_t lhSize;
|
||||||
ZSTD_customMem customMem;
|
ZSTD_customMem customMem;
|
||||||
}; /* typedef'd to ZBUFF_DCtx within "zstd_buffered.h" */
|
}; /* typedef'd to ZBUFF_DCtx within "zbuff.h" */
|
||||||
|
|
||||||
|
|
||||||
ZBUFF_DCtx* ZBUFF_createDCtx(void)
|
ZBUFF_DCtx* ZBUFF_createDCtx(void)
|
||||||
|
|||||||
+471
-247
@@ -1,33 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
zstd - standard compression library
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) 2014-2016, Yann Collet.
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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
|
* Tuning parameters
|
||||||
@@ -49,12 +28,20 @@
|
|||||||
# define ZSTD_LEGACY_SUPPORT 0
|
# define ZSTD_LEGACY_SUPPORT 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* MAXWINDOWSIZE_DEFAULT :
|
||||||
|
* maximum window size accepted by DStream, by default.
|
||||||
|
* Frames requiring more memory will be rejected.
|
||||||
|
*/
|
||||||
|
#ifndef ZSTD_MAXWINDOWSIZE_DEFAULT
|
||||||
|
# define ZSTD_MAXWINDOWSIZE_DEFAULT (257 << 20) /* 257 MB */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*-*******************************************************
|
/*-*******************************************************
|
||||||
* Dependencies
|
* Dependencies
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
#include <string.h> /* memcpy, memmove, memset */
|
#include <string.h> /* memcpy, memmove, memset */
|
||||||
#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 */
|
#define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
|
||||||
#include "xxhash.h" /* XXH64_* */
|
#include "xxhash.h" /* XXH64_* */
|
||||||
@@ -69,24 +56,6 @@
|
|||||||
#endif
|
#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 */
|
|
||||||
# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */
|
|
||||||
#else
|
|
||||||
# ifdef __GNUC__
|
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
|
||||||
# else
|
|
||||||
# define FORCE_INLINE static inline
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Macros
|
* Macros
|
||||||
***************************************/
|
***************************************/
|
||||||
@@ -111,8 +80,12 @@ typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
|
|||||||
|
|
||||||
struct ZSTD_DCtx_s
|
struct ZSTD_DCtx_s
|
||||||
{
|
{
|
||||||
|
const FSE_DTable* LLTptr;
|
||||||
|
const FSE_DTable* MLTptr;
|
||||||
|
const FSE_DTable* OFTptr;
|
||||||
|
const HUF_DTable* HUFptr;
|
||||||
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 OFTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
|
||||||
FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
|
FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
|
||||||
HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */
|
HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */
|
||||||
const void* previousDstEnd;
|
const void* previousDstEnd;
|
||||||
@@ -136,25 +109,29 @@ struct ZSTD_DCtx_s
|
|||||||
size_t rleSize;
|
size_t rleSize;
|
||||||
BYTE litBuffer[ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH];
|
BYTE litBuffer[ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH];
|
||||||
BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
|
BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
|
||||||
}; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
|
}; /* typedef'd to ZSTD_DCtx within "zstd.h" */
|
||||||
|
|
||||||
size_t ZSTD_sizeofDCtx (const ZSTD_DCtx* dctx) { return sizeof(*dctx); }
|
size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx) { if (dctx==NULL) return 0; return sizeof(ZSTD_DCtx); } /* support sizeof on NULL */
|
||||||
|
|
||||||
size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); }
|
size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); }
|
||||||
|
|
||||||
size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
|
size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
|
||||||
{
|
{
|
||||||
dctx->expected = ZSTD_frameHeaderSize_min;
|
dctx->expected = ZSTD_frameHeaderSize_prefix;
|
||||||
dctx->stage = ZSTDds_getFrameHeaderSize;
|
dctx->stage = ZSTDds_getFrameHeaderSize;
|
||||||
dctx->previousDstEnd = NULL;
|
dctx->previousDstEnd = NULL;
|
||||||
dctx->base = NULL;
|
dctx->base = NULL;
|
||||||
dctx->vBase = NULL;
|
dctx->vBase = NULL;
|
||||||
dctx->dictEnd = NULL;
|
dctx->dictEnd = NULL;
|
||||||
dctx->hufTable[0] = (HUF_DTable)((HufLog)*0x1000001);
|
dctx->hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
|
||||||
dctx->litEntropy = dctx->fseEntropy = 0;
|
dctx->litEntropy = dctx->fseEntropy = 0;
|
||||||
dctx->dictID = 0;
|
dctx->dictID = 0;
|
||||||
MEM_STATIC_ASSERT(sizeof(dctx->rep)==sizeof(repStartValue));
|
MEM_STATIC_ASSERT(sizeof(dctx->rep) == sizeof(repStartValue));
|
||||||
memcpy(dctx->rep, repStartValue, sizeof(repStartValue));
|
memcpy(dctx->rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
|
||||||
|
dctx->LLTptr = dctx->LLTable;
|
||||||
|
dctx->MLTptr = dctx->MLTable;
|
||||||
|
dctx->OFTptr = dctx->OFTable;
|
||||||
|
dctx->HUFptr = dctx->hufTable;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,7 +142,7 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
|
|||||||
if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
|
if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
|
||||||
if (!customMem.customAlloc || !customMem.customFree) return NULL;
|
if (!customMem.customAlloc || !customMem.customFree) return NULL;
|
||||||
|
|
||||||
dctx = (ZSTD_DCtx*) customMem.customAlloc(customMem.opaque, sizeof(ZSTD_DCtx));
|
dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(ZSTD_DCtx), customMem);
|
||||||
if (!dctx) return NULL;
|
if (!dctx) return NULL;
|
||||||
memcpy(&dctx->customMem, &customMem, sizeof(customMem));
|
memcpy(&dctx->customMem, &customMem, sizeof(customMem));
|
||||||
ZSTD_decompressBegin(dctx);
|
ZSTD_decompressBegin(dctx);
|
||||||
@@ -180,7 +157,7 @@ ZSTD_DCtx* ZSTD_createDCtx(void)
|
|||||||
size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
|
size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
|
||||||
{
|
{
|
||||||
if (dctx==NULL) return 0; /* support free on NULL */
|
if (dctx==NULL) return 0; /* support free on NULL */
|
||||||
dctx->customMem.customFree(dctx->customMem.opaque, dctx);
|
ZSTD_free(dctx, dctx->customMem);
|
||||||
return 0; /* reserved as a potential error code in the future */
|
return 0; /* reserved as a potential error code in the future */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,6 +167,25 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
|
|||||||
memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize); /* no need to copy workspace */
|
memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize); /* no need to copy workspace */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ZSTD_refDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
|
||||||
|
{
|
||||||
|
ZSTD_decompressBegin(dstDCtx); /* init */
|
||||||
|
dstDCtx->dictEnd = srcDCtx->dictEnd;
|
||||||
|
dstDCtx->vBase = srcDCtx->vBase;
|
||||||
|
dstDCtx->base = srcDCtx->base;
|
||||||
|
dstDCtx->previousDstEnd = srcDCtx->previousDstEnd;
|
||||||
|
dstDCtx->dictID = srcDCtx->dictID;
|
||||||
|
dstDCtx->litEntropy = srcDCtx->litEntropy;
|
||||||
|
dstDCtx->fseEntropy = srcDCtx->fseEntropy;
|
||||||
|
dstDCtx->LLTptr = srcDCtx->LLTable;
|
||||||
|
dstDCtx->MLTptr = srcDCtx->MLTable;
|
||||||
|
dstDCtx->OFTptr = srcDCtx->OFTable;
|
||||||
|
dstDCtx->HUFptr = srcDCtx->hufTable;
|
||||||
|
dstDCtx->rep[0] = srcDCtx->rep[0];
|
||||||
|
dstDCtx->rep[1] = srcDCtx->rep[1];
|
||||||
|
dstDCtx->rep[2] = srcDCtx->rep[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************************************
|
/*-*************************************************************
|
||||||
* Decompression section
|
* Decompression section
|
||||||
@@ -198,16 +194,16 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
|
|||||||
/* See compression format details in : zstd_compression_format.md */
|
/* See compression format details in : zstd_compression_format.md */
|
||||||
|
|
||||||
/** ZSTD_frameHeaderSize() :
|
/** ZSTD_frameHeaderSize() :
|
||||||
* srcSize must be >= ZSTD_frameHeaderSize_min.
|
* srcSize must be >= ZSTD_frameHeaderSize_prefix.
|
||||||
* @return : size of the Frame Header */
|
* @return : size of the Frame Header */
|
||||||
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_prefix) return ERROR(srcSize_wrong);
|
||||||
{ BYTE const fhd = ((const BYTE*)src)[4];
|
{ BYTE const fhd = ((const BYTE*)src)[4];
|
||||||
U32 const dictID= fhd & 3;
|
U32 const dictID= fhd & 3;
|
||||||
U32 const singleSegment = (fhd >> 5) & 1;
|
U32 const singleSegment = (fhd >> 5) & 1;
|
||||||
U32 const fcsId = fhd >> 6;
|
U32 const fcsId = fhd >> 6;
|
||||||
return ZSTD_frameHeaderSize_min + !singleSegment + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
|
return ZSTD_frameHeaderSize_prefix + !singleSegment + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
|
||||||
+ (singleSegment && !fcsId);
|
+ (singleSegment && !fcsId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,7 +218,7 @@ 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_prefix) return ZSTD_frameHeaderSize_prefix;
|
||||||
if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) {
|
if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) {
|
||||||
if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
|
if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
|
||||||
if (srcSize < ZSTD_skippableHeaderSize) return ZSTD_skippableHeaderSize; /* magic number + skippable frame length */
|
if (srcSize < ZSTD_skippableHeaderSize) return ZSTD_skippableHeaderSize; /* magic number + skippable frame length */
|
||||||
@@ -381,34 +377,31 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|||||||
{
|
{
|
||||||
case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */
|
case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */
|
||||||
/* 2 - 2 - 10 - 10 */
|
/* 2 - 2 - 10 - 10 */
|
||||||
{ singleStream = !lhlCode;
|
singleStream = !lhlCode;
|
||||||
lhSize = 3;
|
lhSize = 3;
|
||||||
litSize = (lhc >> 4) & 0x3FF;
|
litSize = (lhc >> 4) & 0x3FF;
|
||||||
litCSize = (lhc >> 14) & 0x3FF;
|
litCSize = (lhc >> 14) & 0x3FF;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case 2:
|
case 2:
|
||||||
/* 2 - 2 - 14 - 14 */
|
/* 2 - 2 - 14 - 14 */
|
||||||
{ lhSize = 4;
|
lhSize = 4;
|
||||||
litSize = (lhc >> 4) & 0x3FFF;
|
litSize = (lhc >> 4) & 0x3FFF;
|
||||||
litCSize = lhc >> 18;
|
litCSize = lhc >> 18;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case 3:
|
case 3:
|
||||||
/* 2 - 2 - 18 - 18 */
|
/* 2 - 2 - 18 - 18 */
|
||||||
{ lhSize = 5;
|
lhSize = 5;
|
||||||
litSize = (lhc >> 4) & 0x3FFFF;
|
litSize = (lhc >> 4) & 0x3FFFF;
|
||||||
litCSize = (lhc >> 22) + (istart[4] << 10);
|
litCSize = (lhc >> 22) + (istart[4] << 10);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
|
if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
|
||||||
if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
|
if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
|
||||||
|
|
||||||
if (HUF_isError((litEncType==set_repeat) ?
|
if (HUF_isError((litEncType==set_repeat) ?
|
||||||
( singleStream ?
|
( singleStream ?
|
||||||
HUF_decompress1X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTable) :
|
HUF_decompress1X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr) :
|
||||||
HUF_decompress4X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTable) ) :
|
HUF_decompress4X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr) ) :
|
||||||
( singleStream ?
|
( singleStream ?
|
||||||
HUF_decompress1X2_DCtx(dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) :
|
HUF_decompress1X2_DCtx(dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) :
|
||||||
HUF_decompress4X_hufOnly (dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize)) ))
|
HUF_decompress4X_hufOnly (dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize)) ))
|
||||||
@@ -418,6 +411,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|||||||
dctx->litBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH;
|
dctx->litBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH;
|
||||||
dctx->litSize = litSize;
|
dctx->litSize = litSize;
|
||||||
dctx->litEntropy = 1;
|
dctx->litEntropy = 1;
|
||||||
|
if (litEncType==set_compressed) dctx->HUFptr = dctx->hufTable;
|
||||||
return litCSize + lhSize;
|
return litCSize + lhSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,28 +478,207 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|||||||
default:
|
default:
|
||||||
return ERROR(corruption_detected); /* impossible */
|
return ERROR(corruption_detected); /* impossible */
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
FSE_decode_t realData;
|
||||||
|
U32 alignedBy4;
|
||||||
|
} FSE_decode_t4;
|
||||||
|
|
||||||
|
static const FSE_decode_t4 LL_defaultDTable[(1<<LL_DEFAULTNORMLOG)+1] = {
|
||||||
|
{ { LL_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
|
||||||
|
{ { 0, 0, 4 } }, /* 0 : base, symbol, bits */
|
||||||
|
{ { 16, 0, 4 } },
|
||||||
|
{ { 32, 1, 5 } },
|
||||||
|
{ { 0, 3, 5 } },
|
||||||
|
{ { 0, 4, 5 } },
|
||||||
|
{ { 0, 6, 5 } },
|
||||||
|
{ { 0, 7, 5 } },
|
||||||
|
{ { 0, 9, 5 } },
|
||||||
|
{ { 0, 10, 5 } },
|
||||||
|
{ { 0, 12, 5 } },
|
||||||
|
{ { 0, 14, 6 } },
|
||||||
|
{ { 0, 16, 5 } },
|
||||||
|
{ { 0, 18, 5 } },
|
||||||
|
{ { 0, 19, 5 } },
|
||||||
|
{ { 0, 21, 5 } },
|
||||||
|
{ { 0, 22, 5 } },
|
||||||
|
{ { 0, 24, 5 } },
|
||||||
|
{ { 32, 25, 5 } },
|
||||||
|
{ { 0, 26, 5 } },
|
||||||
|
{ { 0, 27, 6 } },
|
||||||
|
{ { 0, 29, 6 } },
|
||||||
|
{ { 0, 31, 6 } },
|
||||||
|
{ { 32, 0, 4 } },
|
||||||
|
{ { 0, 1, 4 } },
|
||||||
|
{ { 0, 2, 5 } },
|
||||||
|
{ { 32, 4, 5 } },
|
||||||
|
{ { 0, 5, 5 } },
|
||||||
|
{ { 32, 7, 5 } },
|
||||||
|
{ { 0, 8, 5 } },
|
||||||
|
{ { 32, 10, 5 } },
|
||||||
|
{ { 0, 11, 5 } },
|
||||||
|
{ { 0, 13, 6 } },
|
||||||
|
{ { 32, 16, 5 } },
|
||||||
|
{ { 0, 17, 5 } },
|
||||||
|
{ { 32, 19, 5 } },
|
||||||
|
{ { 0, 20, 5 } },
|
||||||
|
{ { 32, 22, 5 } },
|
||||||
|
{ { 0, 23, 5 } },
|
||||||
|
{ { 0, 25, 4 } },
|
||||||
|
{ { 16, 25, 4 } },
|
||||||
|
{ { 32, 26, 5 } },
|
||||||
|
{ { 0, 28, 6 } },
|
||||||
|
{ { 0, 30, 6 } },
|
||||||
|
{ { 48, 0, 4 } },
|
||||||
|
{ { 16, 1, 4 } },
|
||||||
|
{ { 32, 2, 5 } },
|
||||||
|
{ { 32, 3, 5 } },
|
||||||
|
{ { 32, 5, 5 } },
|
||||||
|
{ { 32, 6, 5 } },
|
||||||
|
{ { 32, 8, 5 } },
|
||||||
|
{ { 32, 9, 5 } },
|
||||||
|
{ { 32, 11, 5 } },
|
||||||
|
{ { 32, 12, 5 } },
|
||||||
|
{ { 0, 15, 6 } },
|
||||||
|
{ { 32, 17, 5 } },
|
||||||
|
{ { 32, 18, 5 } },
|
||||||
|
{ { 32, 20, 5 } },
|
||||||
|
{ { 32, 21, 5 } },
|
||||||
|
{ { 32, 23, 5 } },
|
||||||
|
{ { 32, 24, 5 } },
|
||||||
|
{ { 0, 35, 6 } },
|
||||||
|
{ { 0, 34, 6 } },
|
||||||
|
{ { 0, 33, 6 } },
|
||||||
|
{ { 0, 32, 6 } },
|
||||||
|
}; /* LL_defaultDTable */
|
||||||
|
|
||||||
|
static const FSE_decode_t4 ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = {
|
||||||
|
{ { ML_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
|
||||||
|
{ { 0, 0, 6 } }, /* 0 : base, symbol, bits */
|
||||||
|
{ { 0, 1, 4 } },
|
||||||
|
{ { 32, 2, 5 } },
|
||||||
|
{ { 0, 3, 5 } },
|
||||||
|
{ { 0, 5, 5 } },
|
||||||
|
{ { 0, 6, 5 } },
|
||||||
|
{ { 0, 8, 5 } },
|
||||||
|
{ { 0, 10, 6 } },
|
||||||
|
{ { 0, 13, 6 } },
|
||||||
|
{ { 0, 16, 6 } },
|
||||||
|
{ { 0, 19, 6 } },
|
||||||
|
{ { 0, 22, 6 } },
|
||||||
|
{ { 0, 25, 6 } },
|
||||||
|
{ { 0, 28, 6 } },
|
||||||
|
{ { 0, 31, 6 } },
|
||||||
|
{ { 0, 33, 6 } },
|
||||||
|
{ { 0, 35, 6 } },
|
||||||
|
{ { 0, 37, 6 } },
|
||||||
|
{ { 0, 39, 6 } },
|
||||||
|
{ { 0, 41, 6 } },
|
||||||
|
{ { 0, 43, 6 } },
|
||||||
|
{ { 0, 45, 6 } },
|
||||||
|
{ { 16, 1, 4 } },
|
||||||
|
{ { 0, 2, 4 } },
|
||||||
|
{ { 32, 3, 5 } },
|
||||||
|
{ { 0, 4, 5 } },
|
||||||
|
{ { 32, 6, 5 } },
|
||||||
|
{ { 0, 7, 5 } },
|
||||||
|
{ { 0, 9, 6 } },
|
||||||
|
{ { 0, 12, 6 } },
|
||||||
|
{ { 0, 15, 6 } },
|
||||||
|
{ { 0, 18, 6 } },
|
||||||
|
{ { 0, 21, 6 } },
|
||||||
|
{ { 0, 24, 6 } },
|
||||||
|
{ { 0, 27, 6 } },
|
||||||
|
{ { 0, 30, 6 } },
|
||||||
|
{ { 0, 32, 6 } },
|
||||||
|
{ { 0, 34, 6 } },
|
||||||
|
{ { 0, 36, 6 } },
|
||||||
|
{ { 0, 38, 6 } },
|
||||||
|
{ { 0, 40, 6 } },
|
||||||
|
{ { 0, 42, 6 } },
|
||||||
|
{ { 0, 44, 6 } },
|
||||||
|
{ { 32, 1, 4 } },
|
||||||
|
{ { 48, 1, 4 } },
|
||||||
|
{ { 16, 2, 4 } },
|
||||||
|
{ { 32, 4, 5 } },
|
||||||
|
{ { 32, 5, 5 } },
|
||||||
|
{ { 32, 7, 5 } },
|
||||||
|
{ { 32, 8, 5 } },
|
||||||
|
{ { 0, 11, 6 } },
|
||||||
|
{ { 0, 14, 6 } },
|
||||||
|
{ { 0, 17, 6 } },
|
||||||
|
{ { 0, 20, 6 } },
|
||||||
|
{ { 0, 23, 6 } },
|
||||||
|
{ { 0, 26, 6 } },
|
||||||
|
{ { 0, 29, 6 } },
|
||||||
|
{ { 0, 52, 6 } },
|
||||||
|
{ { 0, 51, 6 } },
|
||||||
|
{ { 0, 50, 6 } },
|
||||||
|
{ { 0, 49, 6 } },
|
||||||
|
{ { 0, 48, 6 } },
|
||||||
|
{ { 0, 47, 6 } },
|
||||||
|
{ { 0, 46, 6 } },
|
||||||
|
}; /* ML_defaultDTable */
|
||||||
|
|
||||||
|
static const FSE_decode_t4 OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = {
|
||||||
|
{ { OF_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
|
||||||
|
{ { 0, 0, 5 } }, /* 0 : base, symbol, bits */
|
||||||
|
{ { 0, 6, 4 } },
|
||||||
|
{ { 0, 9, 5 } },
|
||||||
|
{ { 0, 15, 5 } },
|
||||||
|
{ { 0, 21, 5 } },
|
||||||
|
{ { 0, 3, 5 } },
|
||||||
|
{ { 0, 7, 4 } },
|
||||||
|
{ { 0, 12, 5 } },
|
||||||
|
{ { 0, 18, 5 } },
|
||||||
|
{ { 0, 23, 5 } },
|
||||||
|
{ { 0, 5, 5 } },
|
||||||
|
{ { 0, 8, 4 } },
|
||||||
|
{ { 0, 14, 5 } },
|
||||||
|
{ { 0, 20, 5 } },
|
||||||
|
{ { 0, 2, 5 } },
|
||||||
|
{ { 16, 7, 4 } },
|
||||||
|
{ { 0, 11, 5 } },
|
||||||
|
{ { 0, 17, 5 } },
|
||||||
|
{ { 0, 22, 5 } },
|
||||||
|
{ { 0, 4, 5 } },
|
||||||
|
{ { 16, 8, 4 } },
|
||||||
|
{ { 0, 13, 5 } },
|
||||||
|
{ { 0, 19, 5 } },
|
||||||
|
{ { 0, 1, 5 } },
|
||||||
|
{ { 16, 6, 4 } },
|
||||||
|
{ { 0, 10, 5 } },
|
||||||
|
{ { 0, 16, 5 } },
|
||||||
|
{ { 0, 28, 5 } },
|
||||||
|
{ { 0, 27, 5 } },
|
||||||
|
{ { 0, 26, 5 } },
|
||||||
|
{ { 0, 25, 5 } },
|
||||||
|
{ { 0, 24, 5 } },
|
||||||
|
}; /* OF_defaultDTable */
|
||||||
|
|
||||||
/*! ZSTD_buildSeqTable() :
|
/*! ZSTD_buildSeqTable() :
|
||||||
@return : nb bytes read from src,
|
@return : nb bytes read from src,
|
||||||
or an error code if it fails, testable with ZSTD_isError()
|
or an error code if it fails, testable with ZSTD_isError()
|
||||||
*/
|
*/
|
||||||
FORCE_INLINE size_t ZSTD_buildSeqTable(FSE_DTable* DTable, symbolEncodingType_e type, U32 max, U32 maxLog,
|
static size_t ZSTD_buildSeqTable(FSE_DTable* DTableSpace, const FSE_DTable** DTablePtr,
|
||||||
|
symbolEncodingType_e type, U32 max, U32 maxLog,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
const S16* defaultNorm, U32 defaultLog, U32 flagRepeatTable)
|
const FSE_decode_t4* defaultTable, U32 flagRepeatTable)
|
||||||
{
|
{
|
||||||
|
const void* const tmpPtr = defaultTable; /* bypass strict aliasing */
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case set_rle :
|
case set_rle :
|
||||||
if (!srcSize) return ERROR(srcSize_wrong);
|
if (!srcSize) return ERROR(srcSize_wrong);
|
||||||
if ( (*(const BYTE*)src) > max) return ERROR(corruption_detected);
|
if ( (*(const BYTE*)src) > max) return ERROR(corruption_detected);
|
||||||
FSE_buildDTable_rle(DTable, *(const BYTE*)src); /* if *src > max, data is corrupted */
|
FSE_buildDTable_rle(DTableSpace, *(const BYTE*)src);
|
||||||
|
*DTablePtr = DTableSpace;
|
||||||
return 1;
|
return 1;
|
||||||
case set_basic :
|
case set_basic :
|
||||||
FSE_buildDTable(DTable, defaultNorm, max, defaultLog);
|
*DTablePtr = (const FSE_DTable*)tmpPtr;
|
||||||
return 0;
|
return 0;
|
||||||
case set_repeat:
|
case set_repeat:
|
||||||
if (!flagRepeatTable) return ERROR(corruption_detected);
|
if (!flagRepeatTable) return ERROR(corruption_detected);
|
||||||
@@ -517,14 +690,13 @@ FORCE_INLINE size_t ZSTD_buildSeqTable(FSE_DTable* DTable, symbolEncodingType_e
|
|||||||
size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
|
size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
|
||||||
if (FSE_isError(headerSize)) return ERROR(corruption_detected);
|
if (FSE_isError(headerSize)) return ERROR(corruption_detected);
|
||||||
if (tableLog > maxLog) return ERROR(corruption_detected);
|
if (tableLog > maxLog) return ERROR(corruption_detected);
|
||||||
FSE_buildDTable(DTable, norm, max, tableLog);
|
FSE_buildDTable(DTableSpace, norm, max, tableLog);
|
||||||
|
*DTablePtr = DTableSpace;
|
||||||
return headerSize;
|
return headerSize;
|
||||||
} }
|
} }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
|
||||||
size_t ZSTD_decodeSeqHeaders(int* nbSeqPtr,
|
|
||||||
FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb, U32 flagRepeatTable,
|
|
||||||
const void* src, size_t srcSize)
|
const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
const BYTE* const istart = (const BYTE* const)src;
|
const BYTE* const istart = (const BYTE* const)src;
|
||||||
@@ -554,18 +726,25 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeqPtr,
|
|||||||
ip++;
|
ip++;
|
||||||
|
|
||||||
/* Build DTables */
|
/* Build DTables */
|
||||||
{ size_t const llhSize = ZSTD_buildSeqTable(DTableLL, LLtype, MaxLL, LLFSELog, ip, iend-ip, LL_defaultNorm, LL_defaultNormLog, flagRepeatTable);
|
{ size_t const llhSize = ZSTD_buildSeqTable(dctx->LLTable, &dctx->LLTptr,
|
||||||
|
LLtype, MaxLL, LLFSELog,
|
||||||
|
ip, iend-ip, LL_defaultDTable, dctx->fseEntropy);
|
||||||
if (ZSTD_isError(llhSize)) return ERROR(corruption_detected);
|
if (ZSTD_isError(llhSize)) return ERROR(corruption_detected);
|
||||||
ip += llhSize;
|
ip += llhSize;
|
||||||
}
|
}
|
||||||
{ size_t const ofhSize = ZSTD_buildSeqTable(DTableOffb, OFtype, MaxOff, OffFSELog, ip, iend-ip, OF_defaultNorm, OF_defaultNormLog, flagRepeatTable);
|
{ size_t const ofhSize = ZSTD_buildSeqTable(dctx->OFTable, &dctx->OFTptr,
|
||||||
|
OFtype, MaxOff, OffFSELog,
|
||||||
|
ip, iend-ip, OF_defaultDTable, dctx->fseEntropy);
|
||||||
if (ZSTD_isError(ofhSize)) return ERROR(corruption_detected);
|
if (ZSTD_isError(ofhSize)) return ERROR(corruption_detected);
|
||||||
ip += ofhSize;
|
ip += ofhSize;
|
||||||
}
|
}
|
||||||
{ size_t const mlhSize = ZSTD_buildSeqTable(DTableML, MLtype, MaxML, MLFSELog, ip, iend-ip, ML_defaultNorm, ML_defaultNormLog, flagRepeatTable);
|
{ size_t const mlhSize = ZSTD_buildSeqTable(dctx->MLTable, &dctx->MLTptr,
|
||||||
|
MLtype, MaxML, MLFSELog,
|
||||||
|
ip, iend-ip, ML_defaultDTable, dctx->fseEntropy);
|
||||||
if (ZSTD_isError(mlhSize)) return ERROR(corruption_detected);
|
if (ZSTD_isError(mlhSize)) return ERROR(corruption_detected);
|
||||||
ip += mlhSize;
|
ip += mlhSize;
|
||||||
} }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ip-istart;
|
return ip-istart;
|
||||||
}
|
}
|
||||||
@@ -590,9 +769,9 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
|
|||||||
{
|
{
|
||||||
seq_t seq;
|
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 */
|
||||||
|
|
||||||
U32 const llBits = LL_bits[llCode];
|
U32 const llBits = LL_bits[llCode];
|
||||||
U32 const mlBits = ML_bits[mlCode];
|
U32 const mlBits = ML_bits[mlCode];
|
||||||
@@ -621,8 +800,8 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
|
|||||||
if (!ofCode)
|
if (!ofCode)
|
||||||
offset = 0;
|
offset = 0;
|
||||||
else {
|
else {
|
||||||
offset = OF_base[ofCode] + BIT_readBits(&(seqState->DStream), ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
|
offset = OF_base[ofCode] + BIT_readBits(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
|
||||||
if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
|
if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ofCode <= 1) {
|
if (ofCode <= 1) {
|
||||||
@@ -643,18 +822,18 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
|
|||||||
seq.offset = offset;
|
seq.offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBits(&(seqState->DStream), mlBits) : 0); /* <= 16 bits */
|
seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_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);
|
||||||
|
|
||||||
/* ANS state update */
|
/* ANS state update */
|
||||||
FSE_updateState(&(seqState->stateLL), &(seqState->DStream)); /* <= 9 bits */
|
FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
|
||||||
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;
|
return seq;
|
||||||
}
|
}
|
||||||
@@ -678,7 +857,9 @@ size_t ZSTD_execSequence(BYTE* op,
|
|||||||
if (iLitEnd > litLimit_w) return ERROR(corruption_detected); /* over-read beyond lit buffer */
|
if (iLitEnd > litLimit_w) return ERROR(corruption_detected); /* over-read beyond lit buffer */
|
||||||
|
|
||||||
/* copy Literals */
|
/* copy Literals */
|
||||||
ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
|
ZSTD_copy8(op, *litPtr);
|
||||||
|
if (sequence.litLength > 8)
|
||||||
|
ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
|
||||||
op = oLitEnd;
|
op = oLitEnd;
|
||||||
*litPtr = iLitEnd; /* update for next sequence */
|
*litPtr = iLitEnd; /* update for next sequence */
|
||||||
|
|
||||||
@@ -744,16 +925,13 @@ static size_t ZSTD_decompressSequences(
|
|||||||
const BYTE* litPtr = dctx->litPtr;
|
const BYTE* litPtr = dctx->litPtr;
|
||||||
const BYTE* const litLimit_w = litPtr + dctx->litBufSize - WILDCOPY_OVERLENGTH;
|
const BYTE* const litLimit_w = litPtr + dctx->litBufSize - WILDCOPY_OVERLENGTH;
|
||||||
const BYTE* const litEnd = litPtr + dctx->litSize;
|
const BYTE* const litEnd = litPtr + dctx->litSize;
|
||||||
FSE_DTable* DTableLL = dctx->LLTable;
|
|
||||||
FSE_DTable* DTableML = dctx->MLTable;
|
|
||||||
FSE_DTable* DTableOffb = dctx->OffTable;
|
|
||||||
const BYTE* const base = (const BYTE*) (dctx->base);
|
const BYTE* const base = (const BYTE*) (dctx->base);
|
||||||
const BYTE* const vBase = (const BYTE*) (dctx->vBase);
|
const BYTE* const vBase = (const BYTE*) (dctx->vBase);
|
||||||
const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
|
const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
|
||||||
int nbSeq;
|
int nbSeq;
|
||||||
|
|
||||||
/* Build Decoding Tables */
|
/* Build Decoding Tables */
|
||||||
{ size_t const seqHSize = ZSTD_decodeSeqHeaders(&nbSeq, DTableLL, DTableML, DTableOffb, dctx->fseEntropy, ip, seqSize);
|
{ size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
|
||||||
if (ZSTD_isError(seqHSize)) return seqHSize;
|
if (ZSTD_isError(seqHSize)) return seqHSize;
|
||||||
ip += seqHSize;
|
ip += seqHSize;
|
||||||
}
|
}
|
||||||
@@ -763,11 +941,10 @@ static size_t ZSTD_decompressSequences(
|
|||||||
seqState_t seqState;
|
seqState_t seqState;
|
||||||
dctx->fseEntropy = 1;
|
dctx->fseEntropy = 1;
|
||||||
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->rep[i]; }
|
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->rep[i]; }
|
||||||
{ size_t const errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
|
CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected);
|
||||||
if (ERR_isError(errorCode)) return ERROR(corruption_detected); }
|
FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
|
||||||
FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
|
FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
|
||||||
FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
|
FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
|
||||||
FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
|
|
||||||
|
|
||||||
for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
|
for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
|
||||||
nbSeq--;
|
nbSeq--;
|
||||||
@@ -869,12 +1046,10 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|||||||
if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
|
if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
|
||||||
|
|
||||||
/* Frame Header */
|
/* Frame Header */
|
||||||
{ size_t const frameHeaderSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
|
{ size_t const frameHeaderSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_prefix);
|
||||||
size_t result;
|
|
||||||
if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
|
if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
|
||||||
if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
|
if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
|
||||||
result = ZSTD_decodeFrameHeader(dctx, src, frameHeaderSize);
|
CHECK_F(ZSTD_decodeFrameHeader(dctx, src, frameHeaderSize));
|
||||||
if (ZSTD_isError(result)) return result;
|
|
||||||
ip += frameHeaderSize; remainingSize -= frameHeaderSize;
|
ip += frameHeaderSize; remainingSize -= frameHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -927,25 +1102,10 @@ 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,
|
|
||||||
void* dst, size_t dstCapacity,
|
|
||||||
const void* src, size_t srcSize)
|
|
||||||
{
|
|
||||||
ZSTD_copyDCtx(dctx, refDCtx);
|
|
||||||
ZSTD_checkContinuity(dctx, dst);
|
|
||||||
return ZSTD_decompressFrame(dctx, dst, dstCapacity, src, srcSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
|
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)
|
||||||
{
|
{
|
||||||
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
||||||
if (ZSTD_isLegacy(src, srcSize)) return ZSTD_decompressLegacy(dst, dstCapacity, src, srcSize, dict, dictSize);
|
if (ZSTD_isLegacy(src, srcSize)) return ZSTD_decompressLegacy(dst, dstCapacity, src, srcSize, dict, dictSize);
|
||||||
@@ -978,9 +1138,10 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-**********************************
|
/*-**************************************
|
||||||
* Streaming Decompression API
|
* Advanced Streaming Decompression API
|
||||||
************************************/
|
* Bufferless and synchronous
|
||||||
|
****************************************/
|
||||||
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
|
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
|
||||||
|
|
||||||
ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
|
ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
|
||||||
@@ -1018,32 +1179,30 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|||||||
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_prefix) return ERROR(srcSize_wrong); /* impossible */
|
||||||
if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
|
if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
|
||||||
memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
|
memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix);
|
||||||
dctx->expected = ZSTD_skippableHeaderSize - ZSTD_frameHeaderSize_min; /* magic number + skippable frame length */
|
dctx->expected = ZSTD_skippableHeaderSize - ZSTD_frameHeaderSize_prefix; /* magic number + skippable frame length */
|
||||||
dctx->stage = ZSTDds_decodeSkippableHeader;
|
dctx->stage = ZSTDds_decodeSkippableHeader;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
|
dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_prefix);
|
||||||
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_prefix);
|
||||||
if (dctx->headerSize > ZSTD_frameHeaderSize_min) {
|
if (dctx->headerSize > ZSTD_frameHeaderSize_prefix) {
|
||||||
dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
|
dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_prefix;
|
||||||
dctx->stage = ZSTDds_decodeFrameHeader;
|
dctx->stage = ZSTDds_decodeFrameHeader;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
dctx->expected = 0; /* not necessary to copy more */
|
dctx->expected = 0; /* not necessary to copy more */
|
||||||
|
|
||||||
case ZSTDds_decodeFrameHeader:
|
case ZSTDds_decodeFrameHeader:
|
||||||
{ size_t result;
|
memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
|
||||||
memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
|
CHECK_F(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize));
|
||||||
result = ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize);
|
dctx->expected = ZSTD_blockHeaderSize;
|
||||||
if (ZSTD_isError(result)) return result;
|
dctx->stage = ZSTDds_decodeBlockHeader;
|
||||||
dctx->expected = ZSTD_blockHeaderSize;
|
return 0;
|
||||||
dctx->stage = ZSTDds_decodeBlockHeader;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
case ZSTDds_decodeBlockHeader:
|
case ZSTDds_decodeBlockHeader:
|
||||||
{ blockProperties_t bp;
|
{ blockProperties_t bp;
|
||||||
size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
|
size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
|
||||||
@@ -1115,7 +1274,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case ZSTDds_decodeSkippableHeader:
|
case ZSTDds_decodeSkippableHeader:
|
||||||
{ memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
|
{ memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
|
||||||
dctx->expected = MEM_readLE32(dctx->headerBuffer + 4);
|
dctx->expected = MEM_readLE32(dctx->headerBuffer + 4);
|
||||||
dctx->stage = ZSTDds_skipFrame;
|
dctx->stage = ZSTDds_skipFrame;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1154,8 +1313,7 @@ static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* const dict, size_t c
|
|||||||
U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
|
U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
|
||||||
size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
|
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);
|
CHECK_E(FSE_buildDTable(dctx->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted);
|
||||||
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
|
||||||
dictPtr += offcodeHeaderSize;
|
dictPtr += offcodeHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1163,8 +1321,7 @@ static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* const dict, size_t c
|
|||||||
unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
|
unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
|
||||||
size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
|
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);
|
CHECK_E(FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted);
|
||||||
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
|
||||||
dictPtr += matchlengthHeaderSize;
|
dictPtr += matchlengthHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1172,8 +1329,7 @@ static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* const dict, size_t c
|
|||||||
unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
|
unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
|
||||||
size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
|
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);
|
CHECK_E(FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted);
|
||||||
if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
|
|
||||||
dictPtr += litlengthHeaderSize;
|
dictPtr += litlengthHeaderSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1209,52 +1365,44 @@ static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict
|
|||||||
return ZSTD_refDictContent(dctx, dict, dictSize);
|
return ZSTD_refDictContent(dctx, dict, dictSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
|
size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
|
||||||
{
|
{
|
||||||
{ size_t const errorCode = ZSTD_decompressBegin(dctx);
|
CHECK_F(ZSTD_decompressBegin(dctx));
|
||||||
if (ZSTD_isError(errorCode)) return errorCode; }
|
if (dict && dictSize) CHECK_E(ZSTD_decompress_insertDictionary(dctx, dict, dictSize), dictionary_corrupted);
|
||||||
|
|
||||||
if (dict && dictSize) {
|
|
||||||
size_t const errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
|
|
||||||
if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ====== ZSTD_DDict ====== */
|
||||||
|
|
||||||
struct ZSTD_DDict_s {
|
struct ZSTD_DDict_s {
|
||||||
void* dict;
|
void* dict;
|
||||||
size_t dictSize;
|
size_t dictSize;
|
||||||
ZSTD_DCtx* refContext;
|
ZSTD_DCtx* refContext;
|
||||||
}; /* typedef'd tp ZSTD_CDict within zstd.h */
|
}; /* typedef'd to ZSTD_DDict within "zstd.h" */
|
||||||
|
|
||||||
ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, ZSTD_customMem customMem)
|
ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, ZSTD_customMem customMem)
|
||||||
{
|
{
|
||||||
if (!customMem.customAlloc && !customMem.customFree)
|
if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
|
||||||
customMem = defaultCustomMem;
|
if (!customMem.customAlloc || !customMem.customFree) return NULL;
|
||||||
|
|
||||||
if (!customMem.customAlloc || !customMem.customFree)
|
{ ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem);
|
||||||
return NULL;
|
void* const dictContent = ZSTD_malloc(dictSize, customMem);
|
||||||
|
|
||||||
{ 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);
|
ZSTD_DCtx* const dctx = ZSTD_createDCtx_advanced(customMem);
|
||||||
|
|
||||||
if (!dictContent || !ddict || !dctx) {
|
if (!dictContent || !ddict || !dctx) {
|
||||||
customMem.customFree(customMem.opaque, dictContent);
|
ZSTD_free(dictContent, customMem);
|
||||||
customMem.customFree(customMem.opaque, ddict);
|
ZSTD_free(ddict, customMem);
|
||||||
customMem.customFree(customMem.opaque, dctx);
|
ZSTD_free(dctx, customMem);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(dictContent, dict, dictSize);
|
memcpy(dictContent, dict, dictSize);
|
||||||
{ size_t const errorCode = ZSTD_decompressBegin_usingDict(dctx, dictContent, dictSize);
|
{ size_t const errorCode = ZSTD_decompressBegin_usingDict(dctx, dictContent, dictSize);
|
||||||
if (ZSTD_isError(errorCode)) {
|
if (ZSTD_isError(errorCode)) {
|
||||||
customMem.customFree(customMem.opaque, dictContent);
|
ZSTD_free(dictContent, customMem);
|
||||||
customMem.customFree(customMem.opaque, ddict);
|
ZSTD_free(ddict, customMem);
|
||||||
customMem.customFree(customMem.opaque, dctx);
|
ZSTD_free(dctx, customMem);
|
||||||
return NULL;
|
return NULL;
|
||||||
} }
|
} }
|
||||||
|
|
||||||
@@ -1276,28 +1424,36 @@ ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)
|
|||||||
|
|
||||||
size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
|
size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
|
||||||
{
|
{
|
||||||
ZSTD_freeFunction const cFree = ddict->refContext->customMem.customFree;
|
if (ddict==NULL) return 0; /* support free on NULL */
|
||||||
void* const opaque = ddict->refContext->customMem.opaque;
|
{ ZSTD_customMem const cMem = ddict->refContext->customMem;
|
||||||
ZSTD_freeDCtx(ddict->refContext);
|
ZSTD_freeDCtx(ddict->refContext);
|
||||||
cFree(opaque, ddict->dict);
|
ZSTD_free(ddict->dict, cMem);
|
||||||
cFree(opaque, ddict);
|
ZSTD_free(ddict, cMem);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict)
|
||||||
|
{
|
||||||
|
if (ddict==NULL) return 0; /* support sizeof on NULL */
|
||||||
|
return sizeof(*ddict) + sizeof(ddict->refContext) + ddict->dictSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! ZSTD_decompress_usingDDict() :
|
/*! ZSTD_decompress_usingDDict() :
|
||||||
* Decompression using a pre-digested Dictionary
|
* Decompression using a pre-digested Dictionary
|
||||||
* Use dictionary without significant overhead. */
|
* Use dictionary without significant overhead. */
|
||||||
ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
|
size_t ZSTD_decompress_usingDDict(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 ZSTD_DDict* ddict)
|
const ZSTD_DDict* ddict)
|
||||||
{
|
{
|
||||||
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
|
||||||
if (ZSTD_isLegacy(src, srcSize)) return ZSTD_decompressLegacy(dst, dstCapacity, src, srcSize, ddict->dict, ddict->dictSize);
|
if (ZSTD_isLegacy(src, srcSize)) return ZSTD_decompressLegacy(dst, dstCapacity, src, srcSize, ddict->dict, ddict->dictSize);
|
||||||
#endif
|
#endif
|
||||||
return ZSTD_decompress_usingPreparedDCtx(dctx, ddict->refContext,
|
ZSTD_refDCtx(dctx, ddict->refContext);
|
||||||
dst, dstCapacity,
|
ZSTD_checkContinuity(dctx, dst);
|
||||||
src, srcSize);
|
return ZSTD_decompressFrame(dctx, dst, dstCapacity, src, srcSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1310,20 +1466,26 @@ typedef enum { zdss_init, zdss_loadHeader,
|
|||||||
|
|
||||||
/* *** Resource management *** */
|
/* *** Resource management *** */
|
||||||
struct ZSTD_DStream_s {
|
struct ZSTD_DStream_s {
|
||||||
ZSTD_DCtx* zd;
|
ZSTD_DCtx* dctx;
|
||||||
|
ZSTD_DDict* ddict;
|
||||||
ZSTD_frameParams fParams;
|
ZSTD_frameParams fParams;
|
||||||
ZSTD_dStreamStage stage;
|
ZSTD_dStreamStage stage;
|
||||||
char* inBuff;
|
char* inBuff;
|
||||||
size_t inBuffSize;
|
size_t inBuffSize;
|
||||||
size_t inPos;
|
size_t inPos;
|
||||||
|
size_t maxWindowSize;
|
||||||
char* outBuff;
|
char* outBuff;
|
||||||
size_t outBuffSize;
|
size_t outBuffSize;
|
||||||
size_t outStart;
|
size_t outStart;
|
||||||
size_t outEnd;
|
size_t outEnd;
|
||||||
size_t blockSize;
|
size_t blockSize;
|
||||||
BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
|
BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; /* tmp buffer to store frame header */
|
||||||
size_t lhSize;
|
size_t lhSize;
|
||||||
ZSTD_customMem customMem;
|
ZSTD_customMem customMem;
|
||||||
|
void* legacyContext;
|
||||||
|
U32 previousLegacyVersion;
|
||||||
|
U32 legacyVersion;
|
||||||
|
U32 hostageByte;
|
||||||
}; /* typedef'd to ZSTD_DStream within "zstd.h" */
|
}; /* typedef'd to ZSTD_DStream within "zstd.h" */
|
||||||
|
|
||||||
|
|
||||||
@@ -1336,30 +1498,35 @@ ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem)
|
|||||||
{
|
{
|
||||||
ZSTD_DStream* zds;
|
ZSTD_DStream* zds;
|
||||||
|
|
||||||
if (!customMem.customAlloc && !customMem.customFree)
|
if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
|
||||||
customMem = defaultCustomMem;
|
if (!customMem.customAlloc || !customMem.customFree) return NULL;
|
||||||
|
|
||||||
if (!customMem.customAlloc || !customMem.customFree)
|
zds = (ZSTD_DStream*) ZSTD_malloc(sizeof(ZSTD_DStream), customMem);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
zds = (ZSTD_DStream*)customMem.customAlloc(customMem.opaque, sizeof(ZSTD_DStream));
|
|
||||||
if (zds==NULL) return NULL;
|
if (zds==NULL) return NULL;
|
||||||
memset(zds, 0, sizeof(ZSTD_DStream));
|
memset(zds, 0, sizeof(ZSTD_DStream));
|
||||||
memcpy(&zds->customMem, &customMem, sizeof(ZSTD_customMem));
|
memcpy(&zds->customMem, &customMem, sizeof(ZSTD_customMem));
|
||||||
zds->zd = ZSTD_createDCtx_advanced(customMem);
|
zds->dctx = ZSTD_createDCtx_advanced(customMem);
|
||||||
if (zds->zd == NULL) { ZSTD_freeDStream(zds); return NULL; }
|
if (zds->dctx == NULL) { ZSTD_freeDStream(zds); return NULL; }
|
||||||
zds->stage = zdss_init;
|
zds->stage = zdss_init;
|
||||||
|
zds->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
|
||||||
return zds;
|
return zds;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZSTD_freeDStream(ZSTD_DStream* zds)
|
size_t ZSTD_freeDStream(ZSTD_DStream* zds)
|
||||||
{
|
{
|
||||||
if (zds==NULL) return 0; /* support free on null */
|
if (zds==NULL) return 0; /* support free on null */
|
||||||
ZSTD_freeDCtx(zds->zd);
|
{ ZSTD_customMem const cMem = zds->customMem;
|
||||||
if (zds->inBuff) zds->customMem.customFree(zds->customMem.opaque, zds->inBuff);
|
ZSTD_freeDCtx(zds->dctx);
|
||||||
if (zds->outBuff) zds->customMem.customFree(zds->customMem.opaque, zds->outBuff);
|
ZSTD_freeDDict(zds->ddict);
|
||||||
zds->customMem.customFree(zds->customMem.opaque, zds);
|
ZSTD_free(zds->inBuff, cMem);
|
||||||
return 0;
|
ZSTD_free(zds->outBuff, cMem);
|
||||||
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
|
||||||
|
if (zds->legacyContext)
|
||||||
|
ZSTD_freeLegacyStreamContext(zds->legacyContext, zds->previousLegacyVersion);
|
||||||
|
#endif
|
||||||
|
ZSTD_free(zds, cMem);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1372,7 +1539,12 @@ size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t di
|
|||||||
{
|
{
|
||||||
zds->stage = zdss_loadHeader;
|
zds->stage = zdss_loadHeader;
|
||||||
zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
|
zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
|
||||||
return ZSTD_decompressBegin_usingDict(zds->zd, dict, dictSize);
|
ZSTD_freeDDict(zds->ddict);
|
||||||
|
zds->ddict = ZSTD_createDDict(dict, dictSize);
|
||||||
|
if (zds->ddict == NULL) return ERROR(memory_allocation);
|
||||||
|
zds->legacyVersion = 0;
|
||||||
|
zds->hostageByte = 0;
|
||||||
|
return ZSTD_frameHeaderSize_prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZSTD_initDStream(ZSTD_DStream* zds)
|
size_t ZSTD_initDStream(ZSTD_DStream* zds)
|
||||||
@@ -1380,8 +1552,36 @@ size_t ZSTD_initDStream(ZSTD_DStream* zds)
|
|||||||
return ZSTD_initDStream_usingDict(zds, NULL, 0);
|
return ZSTD_initDStream_usingDict(zds, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t ZSTD_resetDStream(ZSTD_DStream* zds)
|
||||||
|
{
|
||||||
|
if (zds->ddict == NULL) return ERROR(stage_wrong); /* must be init at least once */
|
||||||
|
zds->stage = zdss_loadHeader;
|
||||||
|
zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
|
||||||
|
zds->legacyVersion = 0;
|
||||||
|
zds->hostageByte = 0;
|
||||||
|
return ZSTD_frameHeaderSize_prefix;
|
||||||
|
}
|
||||||
|
|
||||||
/* *** Decompression *** */
|
size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds,
|
||||||
|
ZSTD_DStreamParameter_e paramType, unsigned paramValue)
|
||||||
|
{
|
||||||
|
switch(paramType)
|
||||||
|
{
|
||||||
|
default : return ERROR(parameter_unknown);
|
||||||
|
case ZSTDdsp_maxWindowSize : zds->maxWindowSize = paramValue; break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds)
|
||||||
|
{
|
||||||
|
if (zds==NULL) return 0; /* support sizeof on NULL */
|
||||||
|
return sizeof(*zds) + ZSTD_sizeof_DCtx(zds->dctx) + ZSTD_sizeof_DDict(zds->ddict) + zds->inBuffSize + zds->outBuffSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ***** Decompression ***** */
|
||||||
|
|
||||||
MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
@@ -1401,6 +1601,11 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|||||||
char* op = ostart;
|
char* op = ostart;
|
||||||
U32 someMoreWork = 1;
|
U32 someMoreWork = 1;
|
||||||
|
|
||||||
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
|
||||||
|
if (zds->legacyVersion)
|
||||||
|
return ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
|
||||||
|
#endif
|
||||||
|
|
||||||
while (someMoreWork) {
|
while (someMoreWork) {
|
||||||
switch(zds->stage)
|
switch(zds->stage)
|
||||||
{
|
{
|
||||||
@@ -1408,67 +1613,79 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|||||||
return ERROR(init_missing);
|
return ERROR(init_missing);
|
||||||
|
|
||||||
case zdss_loadHeader :
|
case zdss_loadHeader :
|
||||||
{ size_t const hSize = ZSTD_getFrameParams(&(zds->fParams), zds->headerBuffer, zds->lhSize);
|
{ size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize);
|
||||||
if (ZSTD_isError(hSize)) return hSize;
|
if (ZSTD_isError(hSize))
|
||||||
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
|
||||||
|
{ U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
|
||||||
|
if (legacyVersion) {
|
||||||
|
CHECK_F(ZSTD_initLegacyStream(&zds->legacyContext, zds->previousLegacyVersion, legacyVersion,
|
||||||
|
zds->ddict->dict, zds->ddict->dictSize));
|
||||||
|
zds->legacyVersion = zds->previousLegacyVersion = legacyVersion;
|
||||||
|
return ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
|
||||||
|
} else {
|
||||||
|
return hSize; /* error */
|
||||||
|
} }
|
||||||
|
#else
|
||||||
|
return hSize;
|
||||||
|
#endif
|
||||||
if (hSize != 0) { /* need more input */
|
if (hSize != 0) { /* need more input */
|
||||||
size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */
|
size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */
|
||||||
if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */
|
if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */
|
||||||
memcpy(zds->headerBuffer + zds->lhSize, ip, iend-ip);
|
memcpy(zds->headerBuffer + zds->lhSize, ip, iend-ip);
|
||||||
zds->lhSize += iend-ip;
|
zds->lhSize += iend-ip;
|
||||||
input->pos = input->size;
|
input->pos = input->size;
|
||||||
return (hSize - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */
|
return (MAX(ZSTD_frameHeaderSize_min, hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */
|
||||||
}
|
}
|
||||||
memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad;
|
memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad;
|
||||||
break;
|
break;
|
||||||
} }
|
} }
|
||||||
|
|
||||||
/* Consume header */
|
/* Consume header */
|
||||||
{ size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->zd); /* == ZSTD_frameHeaderSize_min */
|
ZSTD_refDCtx(zds->dctx, zds->ddict->refContext);
|
||||||
size_t const h1Result = ZSTD_decompressContinue(zds->zd, NULL, 0, zds->headerBuffer, h1Size);
|
{ size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx); /* == ZSTD_frameHeaderSize_prefix */
|
||||||
if (ZSTD_isError(h1Result)) return h1Result; /* should not happen : already checked */
|
CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size));
|
||||||
if (h1Size < zds->lhSize) { /* long header */
|
{ size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
|
||||||
size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->zd);
|
CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer+h1Size, h2Size));
|
||||||
size_t const h2Result = ZSTD_decompressContinue(zds->zd, NULL, 0, zds->headerBuffer+h1Size, h2Size);
|
|
||||||
if (ZSTD_isError(h2Result)) return h2Result;
|
|
||||||
} }
|
} }
|
||||||
|
|
||||||
zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
|
zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
|
||||||
|
if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_unsupported);
|
||||||
|
|
||||||
/* Frame header instruct buffer sizes */
|
/* Adapt buffer sizes to frame header instructions */
|
||||||
{ size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
|
{ size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
|
||||||
size_t const neededOutSize = zds->fParams.windowSize + blockSize;
|
size_t const neededOutSize = zds->fParams.windowSize + blockSize;
|
||||||
zds->blockSize = blockSize;
|
zds->blockSize = blockSize;
|
||||||
if (zds->inBuffSize < blockSize) {
|
if (zds->inBuffSize < blockSize) {
|
||||||
zds->customMem.customFree(zds->customMem.opaque, zds->inBuff);
|
ZSTD_free(zds->inBuff, zds->customMem);
|
||||||
zds->inBuffSize = blockSize;
|
zds->inBuffSize = blockSize;
|
||||||
zds->inBuff = (char*)zds->customMem.customAlloc(zds->customMem.opaque, blockSize);
|
zds->inBuff = (char*)ZSTD_malloc(blockSize, zds->customMem);
|
||||||
if (zds->inBuff == NULL) return ERROR(memory_allocation);
|
if (zds->inBuff == NULL) return ERROR(memory_allocation);
|
||||||
}
|
}
|
||||||
if (zds->outBuffSize < neededOutSize) {
|
if (zds->outBuffSize < neededOutSize) {
|
||||||
zds->customMem.customFree(zds->customMem.opaque, zds->outBuff);
|
ZSTD_free(zds->outBuff, zds->customMem);
|
||||||
zds->outBuffSize = neededOutSize;
|
zds->outBuffSize = neededOutSize;
|
||||||
zds->outBuff = (char*)zds->customMem.customAlloc(zds->customMem.opaque, neededOutSize);
|
zds->outBuff = (char*)ZSTD_malloc(neededOutSize, zds->customMem);
|
||||||
if (zds->outBuff == NULL) return ERROR(memory_allocation);
|
if (zds->outBuff == NULL) return ERROR(memory_allocation);
|
||||||
} }
|
} }
|
||||||
zds->stage = zdss_read;
|
zds->stage = zdss_read;
|
||||||
/* pass-through */
|
/* pass-through */
|
||||||
|
|
||||||
case zdss_read:
|
case zdss_read:
|
||||||
{ size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->zd);
|
{ size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
|
||||||
if (neededInSize==0) { /* end of frame */
|
if (neededInSize==0) { /* end of frame */
|
||||||
zds->stage = zdss_init;
|
zds->stage = zdss_init;
|
||||||
someMoreWork = 0;
|
someMoreWork = 0;
|
||||||
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(zds->zd);
|
const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
|
||||||
size_t const decodedSize = ZSTD_decompressContinue(zds->zd,
|
size_t const decodedSize = ZSTD_decompressContinue(zds->dctx,
|
||||||
zds->outBuff + zds->outStart, (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart),
|
zds->outBuff + zds->outStart, (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart),
|
||||||
ip, neededInSize);
|
ip, neededInSize);
|
||||||
if (ZSTD_isError(decodedSize)) return decodedSize;
|
if (ZSTD_isError(decodedSize)) return decodedSize;
|
||||||
ip += neededInSize;
|
ip += neededInSize;
|
||||||
if (!decodedSize && !isSkipFrame) break; /* this was just a header */
|
if (!decodedSize && !isSkipFrame) break; /* this was just a header */
|
||||||
zds->outEnd = zds->outStart + decodedSize;
|
zds->outEnd = zds->outStart + decodedSize;
|
||||||
zds->stage = zdss_flush;
|
zds->stage = zdss_flush;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1478,7 +1695,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|||||||
}
|
}
|
||||||
|
|
||||||
case zdss_load:
|
case zdss_load:
|
||||||
{ size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->zd);
|
{ size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
|
||||||
size_t const toLoad = neededInSize - zds->inPos; /* should always be <= remaining space within inBuff */
|
size_t const toLoad = neededInSize - zds->inPos; /* should always be <= remaining space within inBuff */
|
||||||
size_t loadedSize;
|
size_t loadedSize;
|
||||||
if (toLoad > zds->inBuffSize - zds->inPos) return ERROR(corruption_detected); /* should never happen */
|
if (toLoad > zds->inBuffSize - zds->inPos) return ERROR(corruption_detected); /* should never happen */
|
||||||
@@ -1488,8 +1705,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|||||||
if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */
|
if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */
|
||||||
|
|
||||||
/* decode loaded input */
|
/* decode loaded input */
|
||||||
{ const int isSkipFrame = ZSTD_isSkipFrame(zds->zd);
|
{ const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
|
||||||
size_t const decodedSize = ZSTD_decompressContinue(zds->zd,
|
size_t const decodedSize = ZSTD_decompressContinue(zds->dctx,
|
||||||
zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart,
|
zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart,
|
||||||
zds->inBuff, neededInSize);
|
zds->inBuff, neededInSize);
|
||||||
if (ZSTD_isError(decodedSize)) return decodedSize;
|
if (ZSTD_isError(decodedSize)) return decodedSize;
|
||||||
@@ -1511,7 +1728,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|||||||
zds->outStart = zds->outEnd = 0;
|
zds->outStart = zds->outEnd = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* cannot flush everything */
|
/* cannot complete flush */
|
||||||
someMoreWork = 0;
|
someMoreWork = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1521,17 +1738,24 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|||||||
/* result */
|
/* result */
|
||||||
input->pos += (size_t)(ip-istart);
|
input->pos += (size_t)(ip-istart);
|
||||||
output->pos += (size_t)(op-ostart);
|
output->pos += (size_t)(op-ostart);
|
||||||
{ size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->zd);
|
{ size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->dctx);
|
||||||
if (!nextSrcSizeHint) return (zds->outEnd != zds->outStart); /* return 0 only if fully flushed too */
|
if (!nextSrcSizeHint) { /* frame fully decoded */
|
||||||
nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds->zd) == ZSTDnit_block);
|
if (zds->outEnd == zds->outStart) { /* output fully flushed */
|
||||||
|
if (zds->hostageByte) {
|
||||||
|
if (input->pos >= input->size) { zds->stage = zdss_read; return 1; } /* can't release hostage (not present) */
|
||||||
|
input->pos++; /* release hostage */
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */
|
||||||
|
input->pos--; /* note : pos > 0, otherwise, impossible to finish reading last block */
|
||||||
|
zds->hostageByte=1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds->dctx) == ZSTDnit_block); /* preload header of next block */
|
||||||
if (zds->inPos > nextSrcSizeHint) return ERROR(GENERIC); /* should never happen */
|
if (zds->inPos > nextSrcSizeHint) return ERROR(GENERIC); /* should never happen */
|
||||||
nextSrcSizeHint -= zds->inPos; /* already loaded*/
|
nextSrcSizeHint -= zds->inPos; /* already loaded*/
|
||||||
return nextSrcSizeHint;
|
return nextSrcSizeHint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ extern "C" {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the suffix array of a given string.
|
* Constructs the suffix array of a given string.
|
||||||
* @param T[0..n-1] The input string.
|
* @param T [0..n-1] The input string.
|
||||||
* @param SA[0..n-1] The output array of suffixes.
|
* @param SA [0..n-1] The output array of suffixes.
|
||||||
* @param n The length of the given string.
|
* @param n The length of the given string.
|
||||||
* @param openMP enables OpenMP optimization.
|
* @param openMP enables OpenMP optimization.
|
||||||
* @return 0 if no error occurred, -1 or -2 otherwise.
|
* @return 0 if no error occurred, -1 or -2 otherwise.
|
||||||
@@ -47,9 +47,9 @@ divsufsort(const unsigned char *T, int *SA, int n, int openMP);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the burrows-wheeler transformed string of a given string.
|
* Constructs the burrows-wheeler transformed string of a given string.
|
||||||
* @param T[0..n-1] The input string.
|
* @param T [0..n-1] The input string.
|
||||||
* @param U[0..n-1] The output string. (can be T)
|
* @param U [0..n-1] The output string. (can be T)
|
||||||
* @param A[0..n-1] The temporary array. (can be NULL)
|
* @param A [0..n-1] The temporary array. (can be NULL)
|
||||||
* @param n The length of the given string.
|
* @param n The length of the given string.
|
||||||
* @param num_indexes The length of secondary indexes array. (can be NULL)
|
* @param num_indexes The length of secondary indexes array. (can be NULL)
|
||||||
* @param indexes The secondary indexes array. (can be NULL)
|
* @param indexes The secondary indexes array. (can be NULL)
|
||||||
|
|||||||
+67
-80
@@ -1,40 +1,18 @@
|
|||||||
/*
|
/**
|
||||||
dictBuilder - dictionary builder for zstd
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2016
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-**************************************
|
/*-**************************************
|
||||||
* Tuning parameters
|
* Tuning parameters
|
||||||
****************************************/
|
****************************************/
|
||||||
#define ZDICT_MAX_SAMPLES_SIZE (2000U << 20)
|
#define ZDICT_MAX_SAMPLES_SIZE (2000U << 20)
|
||||||
|
#define ZDICT_MIN_SAMPLES_SIZE 512
|
||||||
|
|
||||||
|
|
||||||
/*-**************************************
|
/*-**************************************
|
||||||
@@ -78,11 +56,9 @@
|
|||||||
#define MB *(1 <<20)
|
#define MB *(1 <<20)
|
||||||
#define GB *(1U<<30)
|
#define GB *(1U<<30)
|
||||||
|
|
||||||
#define DICTLISTSIZE 10000
|
#define DICTLISTSIZE_DEFAULT 10000
|
||||||
|
|
||||||
#define NOISELENGTH 32
|
#define NOISELENGTH 32
|
||||||
#define PRIME1 2654435761U
|
|
||||||
#define PRIME2 2246822519U
|
|
||||||
|
|
||||||
#define MINRATIO 4
|
#define MINRATIO 4
|
||||||
static const int g_compressionLevel_default = 5;
|
static const int g_compressionLevel_default = 5;
|
||||||
@@ -95,26 +71,18 @@ static const size_t g_min_fast_dictContent = 192;
|
|||||||
* Console display
|
* Console display
|
||||||
***************************************/
|
***************************************/
|
||||||
#define DISPLAY(...) { fprintf(stderr, __VA_ARGS__); fflush( stderr ); }
|
#define DISPLAY(...) { fprintf(stderr, __VA_ARGS__); fflush( stderr ); }
|
||||||
#define DISPLAYLEVEL(l, ...) if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); }
|
#define DISPLAYLEVEL(l, ...) if (notificationLevel>=l) { DISPLAY(__VA_ARGS__); } /* 0 : no display; 1: errors; 2: default; 3: details; 4: debug */
|
||||||
static unsigned g_displayLevel = 0; /* 0 : no display; 1: errors; 2: default; 4: full information */
|
|
||||||
|
|
||||||
#define DISPLAYUPDATE(l, ...) if (g_displayLevel>=l) { \
|
|
||||||
if (ZDICT_clockSpan(g_time) > refreshRate) \
|
|
||||||
{ g_time = clock(); DISPLAY(__VA_ARGS__); \
|
|
||||||
if (g_displayLevel>=4) fflush(stdout); } }
|
|
||||||
static const clock_t refreshRate = CLOCKS_PER_SEC * 3 / 10;
|
|
||||||
static clock_t g_time = 0;
|
|
||||||
|
|
||||||
static clock_t ZDICT_clockSpan(clock_t nPrevious) { return clock() - nPrevious; }
|
static clock_t ZDICT_clockSpan(clock_t nPrevious) { return clock() - nPrevious; }
|
||||||
|
|
||||||
static void ZDICT_printHex(U32 dlevel, const void* ptr, size_t length)
|
static void ZDICT_printHex(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);
|
DISPLAY("%c", c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,6 +94,13 @@ unsigned ZDICT_isError(size_t errorCode) { return ERR_isError(errorCode); }
|
|||||||
|
|
||||||
const char* ZDICT_getErrorName(size_t errorCode) { return ERR_getErrorName(errorCode); }
|
const char* ZDICT_getErrorName(size_t errorCode) { return ERR_getErrorName(errorCode); }
|
||||||
|
|
||||||
|
unsigned ZDICT_getDictID(const void* dictBuffer, size_t dictSize)
|
||||||
|
{
|
||||||
|
if (dictSize < 8) return 0;
|
||||||
|
if (MEM_readLE32(dictBuffer) != ZSTD_DICT_MAGIC) return 0;
|
||||||
|
return MEM_readLE32((const char*)dictBuffer + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-********************************************************
|
/*-********************************************************
|
||||||
* Dictionary training functions
|
* Dictionary training functions
|
||||||
@@ -228,7 +203,7 @@ static void ZDICT_initDictItem(dictItem* d)
|
|||||||
static dictItem ZDICT_analyzePos(
|
static dictItem ZDICT_analyzePos(
|
||||||
BYTE* doneMarks,
|
BYTE* doneMarks,
|
||||||
const int* suffix, U32 start,
|
const int* suffix, U32 start,
|
||||||
const void* buffer, U32 minRatio)
|
const void* buffer, U32 minRatio, U32 notificationLevel)
|
||||||
{
|
{
|
||||||
U32 lengthList[LLIMIT] = {0};
|
U32 lengthList[LLIMIT] = {0};
|
||||||
U32 cumulLength[LLIMIT] = {0};
|
U32 cumulLength[LLIMIT] = {0};
|
||||||
@@ -490,7 +465,7 @@ static U32 ZDICT_dictSize(const dictItem* dictList)
|
|||||||
static size_t ZDICT_trainBuffer(dictItem* dictList, U32 dictListSize,
|
static size_t ZDICT_trainBuffer(dictItem* dictList, U32 dictListSize,
|
||||||
const void* const buffer, size_t bufferSize, /* buffer must end with noisy guard band */
|
const void* const buffer, size_t bufferSize, /* buffer must end with noisy guard band */
|
||||||
const size_t* fileSizes, unsigned nbFiles,
|
const size_t* fileSizes, unsigned nbFiles,
|
||||||
U32 minRatio)
|
U32 minRatio, U32 notificationLevel)
|
||||||
{
|
{
|
||||||
int* const suffix0 = (int*)malloc((bufferSize+2)*sizeof(*suffix0));
|
int* const suffix0 = (int*)malloc((bufferSize+2)*sizeof(*suffix0));
|
||||||
int* const suffix = suffix0+1;
|
int* const suffix = suffix0+1;
|
||||||
@@ -498,6 +473,13 @@ static size_t ZDICT_trainBuffer(dictItem* dictList, U32 dictListSize,
|
|||||||
BYTE* doneMarks = (BYTE*)malloc((bufferSize+16)*sizeof(*doneMarks)); /* +16 for overflow security */
|
BYTE* doneMarks = (BYTE*)malloc((bufferSize+16)*sizeof(*doneMarks)); /* +16 for overflow security */
|
||||||
U32* filePos = (U32*)malloc(nbFiles * sizeof(*filePos));
|
U32* filePos = (U32*)malloc(nbFiles * sizeof(*filePos));
|
||||||
size_t result = 0;
|
size_t result = 0;
|
||||||
|
clock_t displayClock = 0;
|
||||||
|
clock_t const refreshRate = CLOCKS_PER_SEC * 3 / 10;
|
||||||
|
|
||||||
|
# define DISPLAYUPDATE(l, ...) if (notificationLevel>=l) { \
|
||||||
|
if (ZDICT_clockSpan(displayClock) > refreshRate) \
|
||||||
|
{ displayClock = clock(); DISPLAY(__VA_ARGS__); \
|
||||||
|
if (notificationLevel>=4) fflush(stdout); } }
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
DISPLAYLEVEL(2, "\r%70s\r", ""); /* clean display line */
|
DISPLAYLEVEL(2, "\r%70s\r", ""); /* clean display line */
|
||||||
@@ -523,7 +505,8 @@ static size_t ZDICT_trainBuffer(dictItem* dictList, U32 dictListSize,
|
|||||||
{ size_t pos;
|
{ size_t pos;
|
||||||
for (pos=0; pos < bufferSize; pos++)
|
for (pos=0; pos < bufferSize; pos++)
|
||||||
reverseSuffix[suffix[pos]] = (U32)pos;
|
reverseSuffix[suffix[pos]] = (U32)pos;
|
||||||
/* build file pos */
|
/* note filePos tracks borders between samples.
|
||||||
|
It's not used at this stage, but planned to become useful in a later update */
|
||||||
filePos[0] = 0;
|
filePos[0] = 0;
|
||||||
for (pos=1; pos<nbFiles; pos++)
|
for (pos=1; pos<nbFiles; pos++)
|
||||||
filePos[pos] = (U32)(filePos[pos-1] + fileSizes[pos-1]);
|
filePos[pos] = (U32)(filePos[pos-1] + fileSizes[pos-1]);
|
||||||
@@ -535,7 +518,7 @@ static size_t ZDICT_trainBuffer(dictItem* dictList, U32 dictListSize,
|
|||||||
{ 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, notificationLevel);
|
||||||
if (solution.length==0) { cursor++; continue; }
|
if (solution.length==0) { cursor++; continue; }
|
||||||
ZDICT_insertDictItem(dictList, dictListSize, solution);
|
ZDICT_insertDictItem(dictList, dictListSize, solution);
|
||||||
cursor += solution.length;
|
cursor += solution.length;
|
||||||
@@ -553,10 +536,12 @@ _cleanup:
|
|||||||
|
|
||||||
static void ZDICT_fillNoise(void* buffer, size_t length)
|
static void ZDICT_fillNoise(void* buffer, size_t length)
|
||||||
{
|
{
|
||||||
unsigned acc = PRIME1;
|
unsigned const prime1 = 2654435761U;
|
||||||
|
unsigned const prime2 = 2246822519U;
|
||||||
|
unsigned acc = prime1;
|
||||||
size_t p=0;;
|
size_t p=0;;
|
||||||
for (p=0; p<length; p++) {
|
for (p=0; p<length; p++) {
|
||||||
acc *= PRIME2;
|
acc *= prime2;
|
||||||
((unsigned char*)buffer)[p] = (unsigned char)(acc >> 21);
|
((unsigned char*)buffer)[p] = (unsigned char)(acc >> 21);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -573,15 +558,15 @@ typedef struct
|
|||||||
|
|
||||||
static void ZDICT_countEStats(EStats_ress_t esr, ZSTD_parameters params,
|
static void ZDICT_countEStats(EStats_ress_t esr, ZSTD_parameters params,
|
||||||
U32* countLit, U32* offsetcodeCount, U32* matchlengthCount, U32* litlengthCount, U32* repOffsets,
|
U32* countLit, U32* offsetcodeCount, U32* matchlengthCount, U32* litlengthCount, U32* repOffsets,
|
||||||
const void* src, size_t srcSize)
|
const void* src, size_t srcSize, U32 notificationLevel)
|
||||||
{
|
{
|
||||||
size_t const blockSizeMax = MIN (ZSTD_BLOCKSIZE_ABSOLUTEMAX, 1 << params.cParams.windowLog);
|
size_t const blockSizeMax = MIN (ZSTD_BLOCKSIZE_ABSOLUTEMAX, 1 << params.cParams.windowLog);
|
||||||
size_t cSize;
|
size_t cSize;
|
||||||
|
|
||||||
if (srcSize > blockSizeMax) srcSize = blockSizeMax; /* protection vs large samples */
|
if (srcSize > blockSizeMax) srcSize = blockSizeMax; /* protection vs large samples */
|
||||||
{ size_t const errorCode = ZSTD_copyCCtx(esr.zc, esr.ref);
|
{ size_t const errorCode = ZSTD_copyCCtx(esr.zc, esr.ref, 0);
|
||||||
if (ZSTD_isError(errorCode)) { DISPLAYLEVEL(1, "warning : ZSTD_copyCCtx failed \n"); return; }
|
if (ZSTD_isError(errorCode)) { DISPLAYLEVEL(1, "warning : ZSTD_copyCCtx failed \n"); return; }
|
||||||
}
|
}
|
||||||
cSize = ZSTD_compressBlock(esr.zc, esr.workPlace, ZSTD_BLOCKSIZE_ABSOLUTEMAX, src, srcSize);
|
cSize = ZSTD_compressBlock(esr.zc, esr.workPlace, ZSTD_BLOCKSIZE_ABSOLUTEMAX, src, srcSize);
|
||||||
if (ZSTD_isError(cSize)) { DISPLAYLEVEL(1, "warning : could not compress sample size %u \n", (U32)srcSize); return; }
|
if (ZSTD_isError(cSize)) { DISPLAYLEVEL(1, "warning : could not compress sample size %u \n", (U32)srcSize); return; }
|
||||||
|
|
||||||
@@ -662,9 +647,10 @@ static void ZDICT_insertSortCount(offsetCount_t table[ZSTD_REP_NUM+1], U32 val,
|
|||||||
|
|
||||||
#define OFFCODE_MAX 30 /* only applicable to first block */
|
#define OFFCODE_MAX 30 /* 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,
|
||||||
const void* srcBuffer, const size_t* fileSizes, unsigned nbFiles,
|
const void* srcBuffer, const size_t* fileSizes, unsigned nbFiles,
|
||||||
const void* dictBuffer, size_t dictBufferSize)
|
const void* dictBuffer, size_t dictBufferSize,
|
||||||
|
unsigned notificationLevel)
|
||||||
{
|
{
|
||||||
U32 countLit[256];
|
U32 countLit[256];
|
||||||
HUF_CREATE_STATIC_CTABLE(hufTable, 255);
|
HUF_CREATE_STATIC_CTABLE(hufTable, 255);
|
||||||
@@ -705,18 +691,19 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
|
|||||||
memset(bestRepOffset, 0, sizeof(bestRepOffset));
|
memset(bestRepOffset, 0, sizeof(bestRepOffset));
|
||||||
if (compressionLevel==0) compressionLevel=g_compressionLevel_default;
|
if (compressionLevel==0) compressionLevel=g_compressionLevel_default;
|
||||||
params = ZSTD_getParams(compressionLevel, averageSampleSize, dictBufferSize);
|
params = ZSTD_getParams(compressionLevel, averageSampleSize, dictBufferSize);
|
||||||
{ size_t const beginResult = ZSTD_compressBegin_advanced(esr.ref, dictBuffer, dictBufferSize, params, 0);
|
{ size_t const beginResult = ZSTD_compressBegin_advanced(esr.ref, dictBuffer, dictBufferSize, params, 0);
|
||||||
if (ZSTD_isError(beginResult)) {
|
if (ZSTD_isError(beginResult)) {
|
||||||
eSize = ERROR(GENERIC);
|
eSize = ERROR(GENERIC);
|
||||||
DISPLAYLEVEL(1, "error : ZSTD_compressBegin_advanced failed \n");
|
DISPLAYLEVEL(1, "error : ZSTD_compressBegin_advanced failed \n");
|
||||||
goto _cleanup;
|
goto _cleanup;
|
||||||
} }
|
} }
|
||||||
|
|
||||||
/* 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, params,
|
ZDICT_countEStats(esr, params,
|
||||||
countLit, offcodeCount, matchLengthCount, litLengthCount, repOffset,
|
countLit, offcodeCount, matchLengthCount, litLengthCount, repOffset,
|
||||||
(const char*)srcBuffer + pos, fileSizes[u]);
|
(const char*)srcBuffer + pos, fileSizes[u],
|
||||||
|
notificationLevel);
|
||||||
pos += fileSizes[u];
|
pos += fileSizes[u];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -763,7 +750,6 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
|
|||||||
}
|
}
|
||||||
llLog = (U32)errorCode;
|
llLog = (U32)errorCode;
|
||||||
|
|
||||||
|
|
||||||
/* write result to buffer */
|
/* write result to buffer */
|
||||||
{ size_t const hhSize = HUF_writeCTable(dstPtr, maxDstSize, hufTable, 255, huffLog);
|
{ size_t const hhSize = HUF_writeCTable(dstPtr, maxDstSize, hufTable, 255, huffLog);
|
||||||
if (HUF_isError(hhSize)) {
|
if (HUF_isError(hhSize)) {
|
||||||
@@ -843,6 +829,7 @@ size_t ZDICT_addEntropyTablesFromBuffer_advanced(void* dictBuffer, size_t dictCo
|
|||||||
{
|
{
|
||||||
size_t hSize;
|
size_t hSize;
|
||||||
int const compressionLevel = (params.compressionLevel <= 0) ? g_compressionLevel_default : params.compressionLevel;
|
int const compressionLevel = (params.compressionLevel <= 0) ? g_compressionLevel_default : params.compressionLevel;
|
||||||
|
U32 const notificationLevel = params.notificationLevel;
|
||||||
|
|
||||||
/* dictionary header */
|
/* dictionary header */
|
||||||
MEM_writeLE32(dictBuffer, ZSTD_DICT_MAGIC);
|
MEM_writeLE32(dictBuffer, ZSTD_DICT_MAGIC);
|
||||||
@@ -859,7 +846,8 @@ size_t ZDICT_addEntropyTablesFromBuffer_advanced(void* dictBuffer, size_t dictCo
|
|||||||
{ size_t const eSize = ZDICT_analyzeEntropy((char*)dictBuffer+hSize, dictBufferCapacity-hSize,
|
{ size_t const eSize = ZDICT_analyzeEntropy((char*)dictBuffer+hSize, dictBufferCapacity-hSize,
|
||||||
compressionLevel,
|
compressionLevel,
|
||||||
samplesBuffer, samplesSizes, nbSamples,
|
samplesBuffer, samplesSizes, nbSamples,
|
||||||
(char*)dictBuffer + dictBufferCapacity - dictContentSize, dictContentSize);
|
(char*)dictBuffer + dictBufferCapacity - dictContentSize, dictContentSize,
|
||||||
|
notificationLevel);
|
||||||
if (ZDICT_isError(eSize)) return eSize;
|
if (ZDICT_isError(eSize)) return eSize;
|
||||||
hSize += eSize;
|
hSize += eSize;
|
||||||
}
|
}
|
||||||
@@ -871,7 +859,6 @@ size_t ZDICT_addEntropyTablesFromBuffer_advanced(void* dictBuffer, size_t dictCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define DIB_MINSAMPLESSIZE 512
|
|
||||||
/*! ZDICT_trainFromBuffer_unsafe() :
|
/*! ZDICT_trainFromBuffer_unsafe() :
|
||||||
* Warning : `samplesBuffer` must be followed by noisy guard band.
|
* Warning : `samplesBuffer` must be followed by noisy guard band.
|
||||||
* @return : size of dictionary, or an error code which can be tested with ZDICT_isError()
|
* @return : size of dictionary, or an error code which can be tested with ZDICT_isError()
|
||||||
@@ -881,31 +868,31 @@ size_t ZDICT_trainFromBuffer_unsafe(
|
|||||||
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)
|
||||||
{
|
{
|
||||||
U32 const dictListSize = MAX(MAX(DICTLISTSIZE, nbSamples), (U32)(maxDictSize/16));
|
U32 const dictListSize = MAX(MAX(DICTLISTSIZE_DEFAULT, nbSamples), (U32)(maxDictSize/16));
|
||||||
dictItem* const dictList = (dictItem*)malloc(dictListSize * sizeof(*dictList));
|
dictItem* const dictList = (dictItem*)malloc(dictListSize * sizeof(*dictList));
|
||||||
unsigned const selectivity = params.selectivityLevel == 0 ? g_selectivity_default : params.selectivityLevel;
|
unsigned const selectivity = params.selectivityLevel == 0 ? g_selectivity_default : params.selectivityLevel;
|
||||||
unsigned const minRep = (selectivity > 30) ? MINRATIO : nbSamples >> selectivity;
|
unsigned const minRep = (selectivity > 30) ? MINRATIO : nbSamples >> selectivity;
|
||||||
size_t const targetDictSize = maxDictSize;
|
size_t const targetDictSize = maxDictSize;
|
||||||
size_t const samplesBuffSize = ZDICT_totalSampleSize(samplesSizes, nbSamples);
|
size_t const samplesBuffSize = ZDICT_totalSampleSize(samplesSizes, nbSamples);
|
||||||
size_t dictSize = 0;
|
size_t dictSize = 0;
|
||||||
|
U32 const notificationLevel = params.notificationLevel;
|
||||||
|
|
||||||
/* checks */
|
/* checks */
|
||||||
if (!dictList) return ERROR(memory_allocation);
|
if (!dictList) return ERROR(memory_allocation);
|
||||||
if (maxDictSize <= g_provision_entropySize + g_min_fast_dictContent) { free(dictList); return ERROR(dstSize_tooSmall); }
|
if (maxDictSize <= g_provision_entropySize + g_min_fast_dictContent) { free(dictList); return ERROR(dstSize_tooSmall); }
|
||||||
if (samplesBuffSize < DIB_MINSAMPLESSIZE) { free(dictList); return 0; } /* not enough source to create dictionary */
|
if (samplesBuffSize < ZDICT_MIN_SAMPLES_SIZE) { free(dictList); return 0; } /* not enough source to create dictionary */
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
ZDICT_initDictItem(dictList);
|
ZDICT_initDictItem(dictList);
|
||||||
g_displayLevel = params.notificationLevel;
|
|
||||||
|
|
||||||
/* build dictionary */
|
/* build dictionary */
|
||||||
ZDICT_trainBuffer(dictList, dictListSize,
|
ZDICT_trainBuffer(dictList, dictListSize,
|
||||||
samplesBuffer, samplesBuffSize,
|
samplesBuffer, samplesBuffSize,
|
||||||
samplesSizes, nbSamples,
|
samplesSizes, nbSamples,
|
||||||
minRep);
|
minRep, notificationLevel);
|
||||||
|
|
||||||
/* display best matches */
|
/* display best matches */
|
||||||
if (g_displayLevel>= 3) {
|
if (params.notificationLevel>= 3) {
|
||||||
U32 const nb = MIN(25, dictList[0].pos);
|
U32 const nb = MIN(25, dictList[0].pos);
|
||||||
U32 const dictContentSize = ZDICT_dictSize(dictList);
|
U32 const dictContentSize = ZDICT_dictSize(dictList);
|
||||||
U32 u;
|
U32 u;
|
||||||
@@ -917,14 +904,14 @@ size_t ZDICT_trainFromBuffer_unsafe(
|
|||||||
U32 printedLength = MIN(40, length);
|
U32 printedLength = MIN(40, length);
|
||||||
DISPLAYLEVEL(3, "%3u:%3u bytes at pos %8u, savings %7u bytes |",
|
DISPLAYLEVEL(3, "%3u:%3u bytes at pos %8u, savings %7u bytes |",
|
||||||
u, length, pos, dictList[u].savings);
|
u, length, pos, dictList[u].savings);
|
||||||
ZDICT_printHex(3, (const char*)samplesBuffer+pos, printedLength);
|
ZDICT_printHex((const char*)samplesBuffer+pos, printedLength);
|
||||||
DISPLAYLEVEL(3, "| \n");
|
DISPLAYLEVEL(3, "| \n");
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
|
||||||
/* create dictionary */
|
/* create dictionary */
|
||||||
{ U32 dictContentSize = ZDICT_dictSize(dictList);
|
{ U32 dictContentSize = ZDICT_dictSize(dictList);
|
||||||
if (dictContentSize < targetDictSize/2) {
|
if (dictContentSize < targetDictSize/3) {
|
||||||
DISPLAYLEVEL(2, "! warning : selected content significantly smaller than requested (%u < %u) \n", dictContentSize, (U32)maxDictSize);
|
DISPLAYLEVEL(2, "! warning : selected content significantly smaller than requested (%u < %u) \n", dictContentSize, (U32)maxDictSize);
|
||||||
if (minRep > MINRATIO) {
|
if (minRep > MINRATIO) {
|
||||||
DISPLAYLEVEL(2, "! consider increasing selectivity to produce larger dictionary (-s%u) \n", selectivity+1);
|
DISPLAYLEVEL(2, "! consider increasing selectivity to produce larger dictionary (-s%u) \n", selectivity+1);
|
||||||
@@ -934,12 +921,12 @@ size_t ZDICT_trainFromBuffer_unsafe(
|
|||||||
DISPLAYLEVEL(2, "! consider increasing the number of samples (total size : %u MB)\n", (U32)(samplesBuffSize>>20));
|
DISPLAYLEVEL(2, "! consider increasing the number of samples (total size : %u MB)\n", (U32)(samplesBuffSize>>20));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dictContentSize > targetDictSize*2) && (nbSamples > 2*MINRATIO) && (selectivity>1)) {
|
if ((dictContentSize > targetDictSize*3) && (nbSamples > 2*MINRATIO) && (selectivity>1)) {
|
||||||
U32 proposedSelectivity = selectivity-1;
|
U32 proposedSelectivity = selectivity-1;
|
||||||
while ((nbSamples >> proposedSelectivity) <= MINRATIO) { proposedSelectivity--; }
|
while ((nbSamples >> proposedSelectivity) <= MINRATIO) { proposedSelectivity--; }
|
||||||
DISPLAYLEVEL(2, "! note : calculated dictionary significantly larger than requested (%u > %u) \n", dictContentSize, (U32)maxDictSize);
|
DISPLAYLEVEL(2, "! note : calculated dictionary significantly larger than requested (%u > %u) \n", dictContentSize, (U32)maxDictSize);
|
||||||
DISPLAYLEVEL(2, "! you may consider decreasing selectivity to produce denser dictionary (-s%u) \n", proposedSelectivity);
|
DISPLAYLEVEL(2, "! consider increasing dictionary size, or produce denser dictionary (-s%u) \n", proposedSelectivity);
|
||||||
DISPLAYLEVEL(2, "! but test its efficiency on samples \n");
|
DISPLAYLEVEL(2, "! always test dictionary efficiency on samples \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* limit dictionary size */
|
/* limit dictionary size */
|
||||||
@@ -983,7 +970,7 @@ size_t ZDICT_trainFromBuffer_advanced(void* dictBuffer, size_t dictBufferCapacit
|
|||||||
size_t result;
|
size_t result;
|
||||||
void* newBuff;
|
void* newBuff;
|
||||||
size_t const sBuffSize = ZDICT_totalSampleSize(samplesSizes, nbSamples);
|
size_t const sBuffSize = ZDICT_totalSampleSize(samplesSizes, nbSamples);
|
||||||
if (sBuffSize < DIB_MINSAMPLESSIZE) return 0; /* not enough content => no dictionary */
|
if (sBuffSize < ZDICT_MIN_SAMPLES_SIZE) return 0; /* not enough content => no dictionary */
|
||||||
|
|
||||||
newBuff = malloc(sBuffSize + NOISELENGTH);
|
newBuff = malloc(sBuffSize + NOISELENGTH);
|
||||||
if (!newBuff) return ERROR(memory_allocation);
|
if (!newBuff) return ERROR(memory_allocation);
|
||||||
|
|||||||
+14
-33
@@ -1,35 +1,11 @@
|
|||||||
/*
|
/**
|
||||||
dictBuilder header file
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2016
|
* All rights reserved.
|
||||||
|
*
|
||||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
Redistribution and use in source and binary forms, with or without
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DICTBUILDER_H_001
|
#ifndef DICTBUILDER_H_001
|
||||||
#define DICTBUILDER_H_001
|
#define DICTBUILDER_H_001
|
||||||
@@ -39,6 +15,10 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*====== Dependencies ======*/
|
||||||
|
#include <stddef.h> /* size_t */
|
||||||
|
|
||||||
|
|
||||||
/*====== Export for Windows ======*/
|
/*====== Export for Windows ======*/
|
||||||
/*!
|
/*!
|
||||||
* ZSTD_DLL_EXPORT :
|
* ZSTD_DLL_EXPORT :
|
||||||
@@ -68,6 +48,7 @@ ZDICTLIB_API size_t ZDICT_trainFromBuffer(void* dictBuffer, size_t dictBufferCap
|
|||||||
|
|
||||||
|
|
||||||
/*====== Helper functions ======*/
|
/*====== Helper functions ======*/
|
||||||
|
ZDICTLIB_API unsigned ZDICT_getDictID(const void* dictBuffer, size_t dictSize); /**< extracts dictID; @return zero if error (not a valid dictionary) */
|
||||||
ZDICTLIB_API unsigned ZDICT_isError(size_t errorCode);
|
ZDICTLIB_API unsigned ZDICT_isError(size_t errorCode);
|
||||||
ZDICTLIB_API const char* ZDICT_getErrorName(size_t errorCode);
|
ZDICTLIB_API const char* ZDICT_getErrorName(size_t errorCode);
|
||||||
|
|
||||||
@@ -87,7 +68,7 @@ typedef struct {
|
|||||||
int compressionLevel; /* 0 means default; target a specific zstd compression level */
|
int 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 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 dictID; /* 0 means auto mode (32-bits random value); other : force dictID value */
|
||||||
unsigned reserved[2]; /* space for future parameters */
|
unsigned reserved[2]; /* reserved space for future parameters */
|
||||||
} ZDICT_params_t;
|
} ZDICT_params_t;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+157
-54
@@ -1,35 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
zstd_legacy - decoder for legacy format
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Header File
|
* All rights reserved.
|
||||||
Copyright (C) 2015-2016, Yann Collet.
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
You can contact the author at :
|
|
||||||
- zstd source repository : https://github.com/Cyan4973/zstd
|
|
||||||
- ztsd public forum : https://groups.google.com/forum/#!forum/lz4c
|
|
||||||
*/
|
|
||||||
#ifndef ZSTD_LEGACY_H
|
#ifndef ZSTD_LEGACY_H
|
||||||
#define ZSTD_LEGACY_H
|
#define ZSTD_LEGACY_H
|
||||||
|
|
||||||
@@ -42,6 +19,7 @@ extern "C" {
|
|||||||
***************************************/
|
***************************************/
|
||||||
#include "mem.h" /* MEM_STATIC */
|
#include "mem.h" /* MEM_STATIC */
|
||||||
#include "error_private.h" /* ERROR */
|
#include "error_private.h" /* ERROR */
|
||||||
|
#include "zstd.h" /* ZSTD_inBuffer, ZSTD_outBuffer */
|
||||||
#include "zstd_v01.h"
|
#include "zstd_v01.h"
|
||||||
#include "zstd_v02.h"
|
#include "zstd_v02.h"
|
||||||
#include "zstd_v03.h"
|
#include "zstd_v03.h"
|
||||||
@@ -76,32 +54,30 @@ MEM_STATIC unsigned ZSTD_isLegacy(const void* src, size_t srcSize)
|
|||||||
|
|
||||||
MEM_STATIC unsigned long long ZSTD_getDecompressedSize_legacy(const void* src, size_t srcSize)
|
MEM_STATIC unsigned long long ZSTD_getDecompressedSize_legacy(const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
if (srcSize < 4) return 0;
|
U32 const version = ZSTD_isLegacy(src, srcSize);
|
||||||
|
if (version < 5) return 0; /* no decompressed size in frame header, or not a legacy format */
|
||||||
{ U32 const version = ZSTD_isLegacy(src, srcSize);
|
if (version==5) {
|
||||||
if (version < 5) return 0; /* no decompressed size in frame header, or not a legacy format */
|
ZSTDv05_parameters fParams;
|
||||||
if (version==5) {
|
size_t const frResult = ZSTDv05_getFrameParams(&fParams, src, srcSize);
|
||||||
ZSTDv05_parameters fParams;
|
if (frResult != 0) return 0;
|
||||||
size_t const frResult = ZSTDv05_getFrameParams(&fParams, src, srcSize);
|
return fParams.srcSize;
|
||||||
if (frResult != 0) return 0;
|
|
||||||
return fParams.srcSize;
|
|
||||||
}
|
|
||||||
if (version==6) {
|
|
||||||
ZSTDv06_frameParams fParams;
|
|
||||||
size_t const frResult = ZSTDv06_getFrameParams(&fParams, src, srcSize);
|
|
||||||
if (frResult != 0) return 0;
|
|
||||||
return fParams.frameContentSize;
|
|
||||||
}
|
|
||||||
if (version==7) {
|
|
||||||
ZSTDv07_frameParams fParams;
|
|
||||||
size_t const frResult = ZSTDv07_getFrameParams(&fParams, src, srcSize);
|
|
||||||
if (frResult != 0) return 0;
|
|
||||||
return fParams.frameContentSize;
|
|
||||||
}
|
|
||||||
return 0; /* should not be possible */
|
|
||||||
}
|
}
|
||||||
|
if (version==6) {
|
||||||
|
ZSTDv06_frameParams fParams;
|
||||||
|
size_t const frResult = ZSTDv06_getFrameParams(&fParams, src, srcSize);
|
||||||
|
if (frResult != 0) return 0;
|
||||||
|
return fParams.frameContentSize;
|
||||||
|
}
|
||||||
|
if (version==7) {
|
||||||
|
ZSTDv07_frameParams fParams;
|
||||||
|
size_t const frResult = ZSTDv07_getFrameParams(&fParams, src, srcSize);
|
||||||
|
if (frResult != 0) return 0;
|
||||||
|
return fParams.frameContentSize;
|
||||||
|
}
|
||||||
|
return 0; /* should not be possible */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MEM_STATIC size_t ZSTD_decompressLegacy(
|
MEM_STATIC size_t ZSTD_decompressLegacy(
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t compressedSize,
|
const void* src, size_t compressedSize,
|
||||||
@@ -148,6 +124,133 @@ MEM_STATIC size_t ZSTD_decompressLegacy(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MEM_STATIC size_t ZSTD_freeLegacyStreamContext(void* legacyContext, U32 version)
|
||||||
|
{
|
||||||
|
switch(version)
|
||||||
|
{
|
||||||
|
default :
|
||||||
|
case 1 :
|
||||||
|
case 2 :
|
||||||
|
case 3 :
|
||||||
|
return ERROR(version_unsupported);
|
||||||
|
case 4 : return ZBUFFv04_freeDCtx((ZBUFFv04_DCtx*)legacyContext);
|
||||||
|
case 5 : return ZBUFFv05_freeDCtx((ZBUFFv05_DCtx*)legacyContext);
|
||||||
|
case 6 : return ZBUFFv06_freeDCtx((ZBUFFv06_DCtx*)legacyContext);
|
||||||
|
case 7 : return ZBUFFv07_freeDCtx((ZBUFFv07_DCtx*)legacyContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MEM_STATIC size_t ZSTD_initLegacyStream(void** legacyContext, U32 prevVersion, U32 newVersion,
|
||||||
|
const void* dict, size_t dictSize)
|
||||||
|
{
|
||||||
|
if (prevVersion != newVersion) ZSTD_freeLegacyStreamContext(*legacyContext, prevVersion);
|
||||||
|
switch(newVersion)
|
||||||
|
{
|
||||||
|
default :
|
||||||
|
case 1 :
|
||||||
|
case 2 :
|
||||||
|
case 3 :
|
||||||
|
return 0;
|
||||||
|
case 4 :
|
||||||
|
{
|
||||||
|
ZBUFFv04_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv04_createDCtx() : (ZBUFFv04_DCtx*)*legacyContext;
|
||||||
|
if (dctx==NULL) return ERROR(memory_allocation);
|
||||||
|
ZBUFFv04_decompressInit(dctx);
|
||||||
|
ZBUFFv04_decompressWithDictionary(dctx, dict, dictSize);
|
||||||
|
*legacyContext = dctx;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case 5 :
|
||||||
|
{
|
||||||
|
ZBUFFv05_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv05_createDCtx() : (ZBUFFv05_DCtx*)*legacyContext;
|
||||||
|
if (dctx==NULL) return ERROR(memory_allocation);
|
||||||
|
ZBUFFv05_decompressInitDictionary(dctx, dict, dictSize);
|
||||||
|
*legacyContext = dctx;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case 6 :
|
||||||
|
{
|
||||||
|
ZBUFFv06_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv06_createDCtx() : (ZBUFFv06_DCtx*)*legacyContext;
|
||||||
|
if (dctx==NULL) return ERROR(memory_allocation);
|
||||||
|
ZBUFFv06_decompressInitDictionary(dctx, dict, dictSize);
|
||||||
|
*legacyContext = dctx;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case 7 :
|
||||||
|
{
|
||||||
|
ZBUFFv07_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv07_createDCtx() : (ZBUFFv07_DCtx*)*legacyContext;
|
||||||
|
if (dctx==NULL) return ERROR(memory_allocation);
|
||||||
|
ZBUFFv07_decompressInitDictionary(dctx, dict, dictSize);
|
||||||
|
*legacyContext = dctx;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MEM_STATIC size_t ZSTD_decompressLegacyStream(void* legacyContext, U32 version,
|
||||||
|
ZSTD_outBuffer* output, ZSTD_inBuffer* input)
|
||||||
|
{
|
||||||
|
switch(version)
|
||||||
|
{
|
||||||
|
default :
|
||||||
|
case 1 :
|
||||||
|
case 2 :
|
||||||
|
case 3 :
|
||||||
|
return ERROR(version_unsupported);
|
||||||
|
case 4 :
|
||||||
|
{
|
||||||
|
ZBUFFv04_DCtx* dctx = (ZBUFFv04_DCtx*) legacyContext;
|
||||||
|
const void* src = (const char*)input->src + input->pos;
|
||||||
|
size_t readSize = input->size - input->pos;
|
||||||
|
void* dst = (char*)output->dst + output->pos;
|
||||||
|
size_t decodedSize = output->size - output->pos;
|
||||||
|
size_t const hintSize = ZBUFFv04_decompressContinue(dctx, dst, &decodedSize, src, &readSize);
|
||||||
|
output->pos += decodedSize;
|
||||||
|
input->pos += readSize;
|
||||||
|
return hintSize;
|
||||||
|
}
|
||||||
|
case 5 :
|
||||||
|
{
|
||||||
|
ZBUFFv05_DCtx* dctx = (ZBUFFv05_DCtx*) legacyContext;
|
||||||
|
const void* src = (const char*)input->src + input->pos;
|
||||||
|
size_t readSize = input->size - input->pos;
|
||||||
|
void* dst = (char*)output->dst + output->pos;
|
||||||
|
size_t decodedSize = output->size - output->pos;
|
||||||
|
size_t const hintSize = ZBUFFv05_decompressContinue(dctx, dst, &decodedSize, src, &readSize);
|
||||||
|
output->pos += decodedSize;
|
||||||
|
input->pos += readSize;
|
||||||
|
return hintSize;
|
||||||
|
}
|
||||||
|
case 6 :
|
||||||
|
{
|
||||||
|
ZBUFFv06_DCtx* dctx = (ZBUFFv06_DCtx*) legacyContext;
|
||||||
|
const void* src = (const char*)input->src + input->pos;
|
||||||
|
size_t readSize = input->size - input->pos;
|
||||||
|
void* dst = (char*)output->dst + output->pos;
|
||||||
|
size_t decodedSize = output->size - output->pos;
|
||||||
|
size_t const hintSize = ZBUFFv06_decompressContinue(dctx, dst, &decodedSize, src, &readSize);
|
||||||
|
output->pos += decodedSize;
|
||||||
|
input->pos += readSize;
|
||||||
|
return hintSize;
|
||||||
|
}
|
||||||
|
case 7 :
|
||||||
|
{
|
||||||
|
ZBUFFv07_DCtx* dctx = (ZBUFFv07_DCtx*) legacyContext;
|
||||||
|
const void* src = (const char*)input->src + input->pos;
|
||||||
|
size_t readSize = input->size - input->pos;
|
||||||
|
void* dst = (char*)output->dst + output->pos;
|
||||||
|
size_t decodedSize = output->size - output->pos;
|
||||||
|
size_t const hintSize = ZBUFFv07_decompressContinue(dctx, dst, &decodedSize, src, &readSize);
|
||||||
|
output->pos += decodedSize;
|
||||||
|
input->pos += readSize;
|
||||||
|
return hintSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
|
|||||||
+87
-175
@@ -1,43 +1,19 @@
|
|||||||
/* ******************************************************************
|
/**
|
||||||
ZSTD_v01
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Zstandard decoder, compatible with v0.1.x format
|
* All rights reserved.
|
||||||
Copyright (C) 2013-2015, Yann Collet.
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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
|
|
||||||
****************************************************************** */
|
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
* Includes
|
* Includes
|
||||||
******************************************/
|
******************************************/
|
||||||
#include <stddef.h> /* size_t, ptrdiff_t */
|
#include <stddef.h> /* size_t, ptrdiff_t */
|
||||||
#include "zstd_v01.h"
|
#include "zstd_v01.h"
|
||||||
|
#include "error_private.h"
|
||||||
|
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
@@ -164,11 +140,15 @@ typedef struct
|
|||||||
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
||||||
#else
|
#else
|
||||||
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||||
# ifdef __GNUC__
|
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
# ifdef __GNUC__
|
||||||
|
# define FORCE_INLINE static inline __attribute__((always_inline))
|
||||||
|
# else
|
||||||
|
# define FORCE_INLINE static inline
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
# define FORCE_INLINE static inline
|
# define FORCE_INLINE static
|
||||||
# endif
|
# endif /* __STDC_VERSION__ */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -1196,57 +1176,6 @@ static size_t HUF_decompress (void* dst, size_t maxDstSize, const void* cSrc, si
|
|||||||
|
|
||||||
#endif /* FSE_COMMONDEFS_ONLY */
|
#endif /* FSE_COMMONDEFS_ONLY */
|
||||||
|
|
||||||
/*
|
|
||||||
zstd - standard compression library
|
|
||||||
Header File for static linking only
|
|
||||||
Copyright (C) 2014-2015, Yann Collet.
|
|
||||||
|
|
||||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
You can contact the author at :
|
|
||||||
- zstd source repository : https://github.com/Cyan4973/zstd
|
|
||||||
- ztsd public forum : https://groups.google.com/forum/#!forum/lz4c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
* Error management
|
|
||||||
**************************************/
|
|
||||||
#define ZSTD_LIST_ERRORS(ITEM) \
|
|
||||||
ITEM(ZSTD_OK_NoError) ITEM(ZSTD_ERROR_GENERIC) \
|
|
||||||
ITEM(ZSTD_ERROR_MagicNumber) \
|
|
||||||
ITEM(ZSTD_ERROR_SrcSize) ITEM(ZSTD_ERROR_maxDstSize_tooSmall) \
|
|
||||||
ITEM(ZSTD_ERROR_corruption) \
|
|
||||||
ITEM(ZSTD_ERROR_maxCode)
|
|
||||||
|
|
||||||
#define ZSTD_GENERATE_ENUM(ENUM) ENUM,
|
|
||||||
typedef enum { ZSTD_LIST_ERRORS(ZSTD_GENERATE_ENUM) } ZSTD_errorCodes; /* exposed list of errors; static linking only */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
zstd - standard compression library
|
zstd - standard compression library
|
||||||
Copyright (C) 2014-2015, Yann Collet.
|
Copyright (C) 2014-2015, Yann Collet.
|
||||||
@@ -1325,17 +1254,9 @@ typedef enum { ZSTD_LIST_ERRORS(ZSTD_GENERATE_ENUM) } ZSTD_errorCodes; /* expo
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER /* Visual Studio */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
# define FORCE_INLINE static __forceinline
|
|
||||||
# include <intrin.h> /* For Visual 2005 */
|
# include <intrin.h> /* For Visual 2005 */
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
|
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
|
||||||
#else
|
|
||||||
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
|
||||||
# ifdef __GNUC__
|
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
|
||||||
# else
|
|
||||||
# define FORCE_INLINE static inline
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -1516,11 +1437,8 @@ typedef struct ZSTD_Cctx_s
|
|||||||
/**************************************
|
/**************************************
|
||||||
* Error Management
|
* Error Management
|
||||||
**************************************/
|
**************************************/
|
||||||
/* tells if a return value is an error code */
|
|
||||||
static unsigned ZSTD_isError(size_t code) { return (code > (size_t)(-ZSTD_ERROR_maxCode)); }
|
|
||||||
|
|
||||||
/* published entry point */
|
/* published entry point */
|
||||||
unsigned ZSTDv01_isError(size_t code) { return ZSTD_isError(code); }
|
unsigned ZSTDv01_isError(size_t code) { return ERR_isError(code); }
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
/**************************************
|
||||||
@@ -1535,13 +1453,13 @@ unsigned ZSTDv01_isError(size_t code) { return ZSTD_isError(code); }
|
|||||||
* Decompression code
|
* Decompression code
|
||||||
**************************************************************/
|
**************************************************************/
|
||||||
|
|
||||||
static size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
|
size_t ZSTDv01_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
|
||||||
{
|
{
|
||||||
const BYTE* const in = (const BYTE* const)src;
|
const BYTE* const in = (const BYTE* const)src;
|
||||||
BYTE headerFlags;
|
BYTE headerFlags;
|
||||||
U32 cSize;
|
U32 cSize;
|
||||||
|
|
||||||
if (srcSize < 3) return (size_t)-ZSTD_ERROR_SrcSize;
|
if (srcSize < 3) return ERROR(srcSize_wrong);
|
||||||
|
|
||||||
headerFlags = *in;
|
headerFlags = *in;
|
||||||
cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
|
cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
|
||||||
@@ -1557,7 +1475,7 @@ static size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockPropertie
|
|||||||
|
|
||||||
static size_t ZSTD_copyUncompressedBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
static size_t ZSTD_copyUncompressedBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
if (srcSize > maxDstSize) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
|
||||||
memcpy(dst, src, srcSize);
|
memcpy(dst, src, srcSize);
|
||||||
return srcSize;
|
return srcSize;
|
||||||
}
|
}
|
||||||
@@ -1574,21 +1492,21 @@ static size_t ZSTD_decompressLiterals(void* ctx,
|
|||||||
size_t litSize;
|
size_t litSize;
|
||||||
|
|
||||||
/* check : minimum 2, for litSize, +1, for content */
|
/* check : minimum 2, for litSize, +1, for content */
|
||||||
if (srcSize <= 3) return (size_t)-ZSTD_ERROR_corruption;
|
if (srcSize <= 3) return ERROR(corruption_detected);
|
||||||
|
|
||||||
litSize = ip[1] + (ip[0]<<8);
|
litSize = ip[1] + (ip[0]<<8);
|
||||||
litSize += ((ip[-3] >> 3) & 7) << 16; // mmmmh....
|
litSize += ((ip[-3] >> 3) & 7) << 16; // mmmmh....
|
||||||
op = oend - litSize;
|
op = oend - litSize;
|
||||||
|
|
||||||
(void)ctx;
|
(void)ctx;
|
||||||
if (litSize > maxDstSize) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
if (litSize > maxDstSize) return ERROR(dstSize_tooSmall);
|
||||||
errorCode = HUF_decompress(op, litSize, ip+2, srcSize-2);
|
errorCode = HUF_decompress(op, litSize, ip+2, srcSize-2);
|
||||||
if (FSE_isError(errorCode)) return (size_t)-ZSTD_ERROR_GENERIC;
|
if (FSE_isError(errorCode)) return ERROR(GENERIC);
|
||||||
return litSize;
|
return litSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static size_t ZSTD_decodeLiteralsBlock(void* ctx,
|
size_t ZSTDv01_decodeLiteralsBlock(void* ctx,
|
||||||
void* dst, size_t maxDstSize,
|
void* dst, size_t maxDstSize,
|
||||||
const BYTE** litStart, size_t* litSize,
|
const BYTE** litStart, size_t* litSize,
|
||||||
const void* src, size_t srcSize)
|
const void* src, size_t srcSize)
|
||||||
@@ -1599,9 +1517,9 @@ static size_t ZSTD_decodeLiteralsBlock(void* ctx,
|
|||||||
BYTE* const oend = ostart + maxDstSize;
|
BYTE* const oend = ostart + maxDstSize;
|
||||||
blockProperties_t litbp;
|
blockProperties_t litbp;
|
||||||
|
|
||||||
size_t litcSize = ZSTD_getcBlockSize(src, srcSize, &litbp);
|
size_t litcSize = ZSTDv01_getcBlockSize(src, srcSize, &litbp);
|
||||||
if (ZSTD_isError(litcSize)) return litcSize;
|
if (ZSTDv01_isError(litcSize)) return litcSize;
|
||||||
if (litcSize > srcSize - ZSTD_blockHeaderSize) return (size_t)-ZSTD_ERROR_SrcSize;
|
if (litcSize > srcSize - ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
|
||||||
ip += ZSTD_blockHeaderSize;
|
ip += ZSTD_blockHeaderSize;
|
||||||
|
|
||||||
switch(litbp.blockType)
|
switch(litbp.blockType)
|
||||||
@@ -1614,7 +1532,7 @@ static size_t ZSTD_decodeLiteralsBlock(void* ctx,
|
|||||||
case bt_rle:
|
case bt_rle:
|
||||||
{
|
{
|
||||||
size_t rleSize = litbp.origSize;
|
size_t rleSize = litbp.origSize;
|
||||||
if (rleSize>maxDstSize) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
if (rleSize>maxDstSize) return ERROR(dstSize_tooSmall);
|
||||||
memset(oend - rleSize, *ip, rleSize);
|
memset(oend - rleSize, *ip, rleSize);
|
||||||
*litStart = oend - rleSize;
|
*litStart = oend - rleSize;
|
||||||
*litSize = rleSize;
|
*litSize = rleSize;
|
||||||
@@ -1624,7 +1542,7 @@ static size_t ZSTD_decodeLiteralsBlock(void* ctx,
|
|||||||
case bt_compressed:
|
case bt_compressed:
|
||||||
{
|
{
|
||||||
size_t decodedLitSize = ZSTD_decompressLiterals(ctx, dst, maxDstSize, ip, litcSize);
|
size_t decodedLitSize = ZSTD_decompressLiterals(ctx, dst, maxDstSize, ip, litcSize);
|
||||||
if (ZSTD_isError(decodedLitSize)) return decodedLitSize;
|
if (ZSTDv01_isError(decodedLitSize)) return decodedLitSize;
|
||||||
*litStart = oend - decodedLitSize;
|
*litStart = oend - decodedLitSize;
|
||||||
*litSize = decodedLitSize;
|
*litSize = decodedLitSize;
|
||||||
ip += litcSize;
|
ip += litcSize;
|
||||||
@@ -1632,14 +1550,14 @@ static size_t ZSTD_decodeLiteralsBlock(void* ctx,
|
|||||||
}
|
}
|
||||||
case bt_end:
|
case bt_end:
|
||||||
default:
|
default:
|
||||||
return (size_t)-ZSTD_ERROR_GENERIC;
|
return ERROR(GENERIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ip-istart;
|
return ip-istart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
|
size_t ZSTDv01_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
|
||||||
FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
|
FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
|
||||||
const void* src, size_t srcSize)
|
const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
@@ -1651,7 +1569,7 @@ static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* d
|
|||||||
size_t dumpsLength;
|
size_t dumpsLength;
|
||||||
|
|
||||||
/* check */
|
/* check */
|
||||||
if (srcSize < 5) return (size_t)-ZSTD_ERROR_SrcSize;
|
if (srcSize < 5) return ERROR(srcSize_wrong);
|
||||||
|
|
||||||
/* SeqHead */
|
/* SeqHead */
|
||||||
*nbSeq = ZSTD_readLE16(ip); ip+=2;
|
*nbSeq = ZSTD_readLE16(ip); ip+=2;
|
||||||
@@ -1675,7 +1593,7 @@ static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* d
|
|||||||
*dumpsLengthPtr = dumpsLength;
|
*dumpsLengthPtr = dumpsLength;
|
||||||
|
|
||||||
/* check */
|
/* check */
|
||||||
if (ip > iend-3) return (size_t)-ZSTD_ERROR_SrcSize; /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
|
if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
|
||||||
|
|
||||||
/* sequences */
|
/* sequences */
|
||||||
{
|
{
|
||||||
@@ -1685,7 +1603,6 @@ static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* d
|
|||||||
/* Build DTables */
|
/* Build DTables */
|
||||||
switch(LLtype)
|
switch(LLtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
|
||||||
case bt_rle :
|
case bt_rle :
|
||||||
LLlog = 0;
|
LLlog = 0;
|
||||||
FSE_buildDTable_rle(DTableLL, *ip++); break;
|
FSE_buildDTable_rle(DTableLL, *ip++); break;
|
||||||
@@ -1693,52 +1610,49 @@ static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* d
|
|||||||
LLlog = LLbits;
|
LLlog = LLbits;
|
||||||
FSE_buildDTable_raw(DTableLL, LLbits); break;
|
FSE_buildDTable_raw(DTableLL, LLbits); break;
|
||||||
default :
|
default :
|
||||||
max = MaxLL;
|
{ U32 max = MaxLL;
|
||||||
headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
|
headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
|
||||||
if (FSE_isError(headerSize)) return (size_t)-ZSTD_ERROR_GENERIC;
|
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
||||||
if (LLlog > LLFSELog) return (size_t)-ZSTD_ERROR_corruption;
|
if (LLlog > LLFSELog) return ERROR(corruption_detected);
|
||||||
ip += headerSize;
|
ip += headerSize;
|
||||||
FSE_buildDTable(DTableLL, norm, max, LLlog);
|
FSE_buildDTable(DTableLL, norm, max, LLlog);
|
||||||
}
|
} }
|
||||||
|
|
||||||
switch(Offtype)
|
switch(Offtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
|
||||||
case bt_rle :
|
case bt_rle :
|
||||||
Offlog = 0;
|
Offlog = 0;
|
||||||
if (ip > iend-2) return (size_t)-ZSTD_ERROR_SrcSize; /* min : "raw", hence no header, but at least xxLog bits */
|
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
||||||
FSE_buildDTable_rle(DTableOffb, *ip++); break;
|
FSE_buildDTable_rle(DTableOffb, *ip++); break;
|
||||||
case bt_raw :
|
case bt_raw :
|
||||||
Offlog = Offbits;
|
Offlog = Offbits;
|
||||||
FSE_buildDTable_raw(DTableOffb, Offbits); break;
|
FSE_buildDTable_raw(DTableOffb, Offbits); break;
|
||||||
default :
|
default :
|
||||||
max = MaxOff;
|
{ U32 max = MaxOff;
|
||||||
headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
|
headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
|
||||||
if (FSE_isError(headerSize)) return (size_t)-ZSTD_ERROR_GENERIC;
|
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
||||||
if (Offlog > OffFSELog) return (size_t)-ZSTD_ERROR_corruption;
|
if (Offlog > OffFSELog) return ERROR(corruption_detected);
|
||||||
ip += headerSize;
|
ip += headerSize;
|
||||||
FSE_buildDTable(DTableOffb, norm, max, Offlog);
|
FSE_buildDTable(DTableOffb, norm, max, Offlog);
|
||||||
}
|
} }
|
||||||
|
|
||||||
switch(MLtype)
|
switch(MLtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
|
||||||
case bt_rle :
|
case bt_rle :
|
||||||
MLlog = 0;
|
MLlog = 0;
|
||||||
if (ip > iend-2) return (size_t)-ZSTD_ERROR_SrcSize; /* min : "raw", hence no header, but at least xxLog bits */
|
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
||||||
FSE_buildDTable_rle(DTableML, *ip++); break;
|
FSE_buildDTable_rle(DTableML, *ip++); break;
|
||||||
case bt_raw :
|
case bt_raw :
|
||||||
MLlog = MLbits;
|
MLlog = MLbits;
|
||||||
FSE_buildDTable_raw(DTableML, MLbits); break;
|
FSE_buildDTable_raw(DTableML, MLbits); break;
|
||||||
default :
|
default :
|
||||||
max = MaxML;
|
{ U32 max = MaxML;
|
||||||
headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
|
headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
|
||||||
if (FSE_isError(headerSize)) return (size_t)-ZSTD_ERROR_GENERIC;
|
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
||||||
if (MLlog > MLFSELog) return (size_t)-ZSTD_ERROR_corruption;
|
if (MLlog > MLFSELog) return ERROR(corruption_detected);
|
||||||
ip += headerSize;
|
ip += headerSize;
|
||||||
FSE_buildDTable(DTableML, norm, max, MLlog);
|
FSE_buildDTable(DTableML, norm, max, MLlog);
|
||||||
}
|
} } }
|
||||||
}
|
|
||||||
|
|
||||||
return ip-istart;
|
return ip-istart;
|
||||||
}
|
}
|
||||||
@@ -1838,9 +1752,9 @@ static size_t ZSTD_execSequence(BYTE* op,
|
|||||||
const BYTE* const litEnd = *litPtr + litLength;
|
const BYTE* const litEnd = *litPtr + litLength;
|
||||||
|
|
||||||
/* check */
|
/* check */
|
||||||
if (endMatch > oend) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; /* overwrite beyond dst buffer */
|
if (endMatch > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
|
||||||
if (litEnd > litLimit) return (size_t)-ZSTD_ERROR_corruption;
|
if (litEnd > litLimit) return ERROR(corruption_detected);
|
||||||
if (sequence.matchLength > (size_t)(*litPtr-op)) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; /* overwrite literal segment */
|
if (sequence.matchLength > (size_t)(*litPtr-op)) return ERROR(dstSize_tooSmall); /* overwrite literal segment */
|
||||||
|
|
||||||
/* copy Literals */
|
/* copy Literals */
|
||||||
if (((size_t)(*litPtr - op) < 8) || ((size_t)(oend-litEnd) < 8) || (op+litLength > oend-8))
|
if (((size_t)(*litPtr - op) < 8) || ((size_t)(oend-litEnd) < 8) || (op+litLength > oend-8))
|
||||||
@@ -1851,7 +1765,7 @@ static size_t ZSTD_execSequence(BYTE* op,
|
|||||||
*litPtr = litEnd; /* update for next sequence */
|
*litPtr = litEnd; /* update for next sequence */
|
||||||
|
|
||||||
/* check : last match must be at a minimum distance of 8 from end of dest buffer */
|
/* check : last match must be at a minimum distance of 8 from end of dest buffer */
|
||||||
if (oend-op < 8) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
if (oend-op < 8) return ERROR(dstSize_tooSmall);
|
||||||
|
|
||||||
/* copy Match */
|
/* copy Match */
|
||||||
{
|
{
|
||||||
@@ -1861,8 +1775,8 @@ static size_t ZSTD_execSequence(BYTE* op,
|
|||||||
U64 saved[2];
|
U64 saved[2];
|
||||||
|
|
||||||
/* check */
|
/* check */
|
||||||
if (match < base) return (size_t)-ZSTD_ERROR_corruption;
|
if (match < base) return ERROR(corruption_detected);
|
||||||
if (sequence.offset > (size_t)base) return (size_t)-ZSTD_ERROR_corruption;
|
if (sequence.offset > (size_t)base) return ERROR(corruption_detected);
|
||||||
|
|
||||||
/* save beginning of literal sequence, in case of write overlap */
|
/* save beginning of literal sequence, in case of write overlap */
|
||||||
if (overlapRisk)
|
if (overlapRisk)
|
||||||
@@ -1940,10 +1854,10 @@ static size_t ZSTD_decompressSequences(
|
|||||||
BYTE* const base = (BYTE*) (dctx->base);
|
BYTE* const base = (BYTE*) (dctx->base);
|
||||||
|
|
||||||
/* Build Decoding Tables */
|
/* Build Decoding Tables */
|
||||||
errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
|
errorCode = ZSTDv01_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
|
||||||
DTableLL, DTableML, DTableOffb,
|
DTableLL, DTableML, DTableOffb,
|
||||||
ip, iend-ip);
|
ip, iend-ip);
|
||||||
if (ZSTD_isError(errorCode)) return errorCode;
|
if (ZSTDv01_isError(errorCode)) return errorCode;
|
||||||
ip += errorCode;
|
ip += errorCode;
|
||||||
|
|
||||||
/* Regen sequences */
|
/* Regen sequences */
|
||||||
@@ -1956,7 +1870,7 @@ static size_t ZSTD_decompressSequences(
|
|||||||
seqState.dumpsEnd = dumps + dumpsLength;
|
seqState.dumpsEnd = dumps + dumpsLength;
|
||||||
seqState.prevOffset = 1;
|
seqState.prevOffset = 1;
|
||||||
errorCode = FSE_initDStream(&(seqState.DStream), ip, iend-ip);
|
errorCode = FSE_initDStream(&(seqState.DStream), ip, iend-ip);
|
||||||
if (FSE_isError(errorCode)) return (size_t)-ZSTD_ERROR_corruption;
|
if (FSE_isError(errorCode)) return ERROR(corruption_detected);
|
||||||
FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
|
FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
|
||||||
FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
|
FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
|
||||||
FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
|
FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
|
||||||
@@ -1967,18 +1881,18 @@ static size_t ZSTD_decompressSequences(
|
|||||||
nbSeq--;
|
nbSeq--;
|
||||||
ZSTD_decodeSequence(&sequence, &seqState);
|
ZSTD_decodeSequence(&sequence, &seqState);
|
||||||
oneSeqSize = ZSTD_execSequence(op, sequence, &litPtr, litEnd, base, oend);
|
oneSeqSize = ZSTD_execSequence(op, sequence, &litPtr, litEnd, base, oend);
|
||||||
if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
|
if (ZSTDv01_isError(oneSeqSize)) return oneSeqSize;
|
||||||
op += oneSeqSize;
|
op += oneSeqSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if reached exact end */
|
/* check if reached exact end */
|
||||||
if ( !FSE_endOfDStream(&(seqState.DStream)) ) return (size_t)-ZSTD_ERROR_corruption; /* requested too much : data is corrupted */
|
if ( !FSE_endOfDStream(&(seqState.DStream)) ) return ERROR(corruption_detected); /* requested too much : data is corrupted */
|
||||||
if (nbSeq<0) return (size_t)-ZSTD_ERROR_corruption; /* requested too many sequences : data is corrupted */
|
if (nbSeq<0) return ERROR(corruption_detected); /* requested too many sequences : data is corrupted */
|
||||||
|
|
||||||
/* last literal segment */
|
/* last literal segment */
|
||||||
{
|
{
|
||||||
size_t lastLLSize = litEnd - litPtr;
|
size_t lastLLSize = litEnd - litPtr;
|
||||||
if (op+lastLLSize > oend) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
|
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
||||||
if (op != litPtr) memmove(op, litPtr, lastLLSize);
|
if (op != litPtr) memmove(op, litPtr, lastLLSize);
|
||||||
op += lastLLSize;
|
op += lastLLSize;
|
||||||
}
|
}
|
||||||
@@ -2000,8 +1914,8 @@ static size_t ZSTD_decompressBlock(
|
|||||||
size_t errorCode;
|
size_t errorCode;
|
||||||
|
|
||||||
/* Decode literals sub-block */
|
/* Decode literals sub-block */
|
||||||
errorCode = ZSTD_decodeLiteralsBlock(ctx, dst, maxDstSize, &litPtr, &litSize, src, srcSize);
|
errorCode = ZSTDv01_decodeLiteralsBlock(ctx, dst, maxDstSize, &litPtr, &litSize, src, srcSize);
|
||||||
if (ZSTD_isError(errorCode)) return errorCode;
|
if (ZSTDv01_isError(errorCode)) return errorCode;
|
||||||
ip += errorCode;
|
ip += errorCode;
|
||||||
srcSize -= errorCode;
|
srcSize -= errorCode;
|
||||||
|
|
||||||
@@ -2022,20 +1936,20 @@ size_t ZSTDv01_decompressDCtx(void* ctx, void* dst, size_t maxDstSize, const voi
|
|||||||
blockProperties_t blockProperties;
|
blockProperties_t blockProperties;
|
||||||
|
|
||||||
/* Frame Header */
|
/* Frame Header */
|
||||||
if (srcSize < ZSTD_frameHeaderSize+ZSTD_blockHeaderSize) return (size_t)-ZSTD_ERROR_SrcSize;
|
if (srcSize < ZSTD_frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
|
||||||
magicNumber = ZSTD_readBE32(src);
|
magicNumber = ZSTD_readBE32(src);
|
||||||
if (magicNumber != ZSTD_magicNumber) return (size_t)-ZSTD_ERROR_MagicNumber;
|
if (magicNumber != ZSTD_magicNumber) return ERROR(prefix_unknown);
|
||||||
ip += ZSTD_frameHeaderSize; remainingSize -= ZSTD_frameHeaderSize;
|
ip += ZSTD_frameHeaderSize; remainingSize -= ZSTD_frameHeaderSize;
|
||||||
|
|
||||||
/* Loop on each block */
|
/* Loop on each block */
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
size_t blockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
|
size_t blockSize = ZSTDv01_getcBlockSize(ip, iend-ip, &blockProperties);
|
||||||
if (ZSTD_isError(blockSize)) return blockSize;
|
if (ZSTDv01_isError(blockSize)) return blockSize;
|
||||||
|
|
||||||
ip += ZSTD_blockHeaderSize;
|
ip += ZSTD_blockHeaderSize;
|
||||||
remainingSize -= ZSTD_blockHeaderSize;
|
remainingSize -= ZSTD_blockHeaderSize;
|
||||||
if (blockSize > remainingSize) return (size_t)-ZSTD_ERROR_SrcSize;
|
if (blockSize > remainingSize) return ERROR(srcSize_wrong);
|
||||||
|
|
||||||
switch(blockProperties.blockType)
|
switch(blockProperties.blockType)
|
||||||
{
|
{
|
||||||
@@ -2046,18 +1960,18 @@ size_t ZSTDv01_decompressDCtx(void* ctx, void* dst, size_t maxDstSize, const voi
|
|||||||
errorCode = ZSTD_copyUncompressedBlock(op, oend-op, ip, blockSize);
|
errorCode = ZSTD_copyUncompressedBlock(op, oend-op, ip, blockSize);
|
||||||
break;
|
break;
|
||||||
case bt_rle :
|
case bt_rle :
|
||||||
return (size_t)-ZSTD_ERROR_GENERIC; /* not yet supported */
|
return ERROR(GENERIC); /* not yet supported */
|
||||||
break;
|
break;
|
||||||
case bt_end :
|
case bt_end :
|
||||||
/* end of frame */
|
/* end of frame */
|
||||||
if (remainingSize) return (size_t)-ZSTD_ERROR_SrcSize;
|
if (remainingSize) return ERROR(srcSize_wrong);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return (size_t)-ZSTD_ERROR_GENERIC;
|
return ERROR(GENERIC);
|
||||||
}
|
}
|
||||||
if (blockSize == 0) break; /* bt_end */
|
if (blockSize == 0) break; /* bt_end */
|
||||||
|
|
||||||
if (ZSTD_isError(errorCode)) return errorCode;
|
if (ZSTDv01_isError(errorCode)) return errorCode;
|
||||||
op += errorCode;
|
op += errorCode;
|
||||||
ip += blockSize;
|
ip += blockSize;
|
||||||
remainingSize -= blockSize;
|
remainingSize -= blockSize;
|
||||||
@@ -2111,7 +2025,7 @@ size_t ZSTDv01_decompressContinue(ZSTDv01_Dctx* dctx, void* dst, size_t maxDstSi
|
|||||||
dctx_t* ctx = (dctx_t*)dctx;
|
dctx_t* ctx = (dctx_t*)dctx;
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
if (srcSize != ctx->expected) return (size_t)-ZSTD_ERROR_SrcSize;
|
if (srcSize != ctx->expected) return ERROR(srcSize_wrong);
|
||||||
if (dst != ctx->previousDstEnd) /* not contiguous */
|
if (dst != ctx->previousDstEnd) /* not contiguous */
|
||||||
ctx->base = dst;
|
ctx->base = dst;
|
||||||
|
|
||||||
@@ -2120,7 +2034,7 @@ size_t ZSTDv01_decompressContinue(ZSTDv01_Dctx* dctx, void* dst, size_t maxDstSi
|
|||||||
{
|
{
|
||||||
/* Check frame magic header */
|
/* Check frame magic header */
|
||||||
U32 magicNumber = ZSTD_readBE32(src);
|
U32 magicNumber = ZSTD_readBE32(src);
|
||||||
if (magicNumber != ZSTD_magicNumber) return (size_t)-ZSTD_ERROR_MagicNumber;
|
if (magicNumber != ZSTD_magicNumber) return ERROR(prefix_unknown);
|
||||||
ctx->phase = 1;
|
ctx->phase = 1;
|
||||||
ctx->expected = ZSTD_blockHeaderSize;
|
ctx->expected = ZSTD_blockHeaderSize;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2130,8 +2044,8 @@ size_t ZSTDv01_decompressContinue(ZSTDv01_Dctx* dctx, void* dst, size_t maxDstSi
|
|||||||
if (ctx->phase == 1)
|
if (ctx->phase == 1)
|
||||||
{
|
{
|
||||||
blockProperties_t bp;
|
blockProperties_t bp;
|
||||||
size_t blockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
|
size_t blockSize = ZSTDv01_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
|
||||||
if (ZSTD_isError(blockSize)) return blockSize;
|
if (ZSTDv01_isError(blockSize)) return blockSize;
|
||||||
if (bp.blockType == bt_end)
|
if (bp.blockType == bt_end)
|
||||||
{
|
{
|
||||||
ctx->expected = 0;
|
ctx->expected = 0;
|
||||||
@@ -2159,13 +2073,13 @@ size_t ZSTDv01_decompressContinue(ZSTDv01_Dctx* dctx, void* dst, size_t maxDstSi
|
|||||||
rSize = ZSTD_copyUncompressedBlock(dst, maxDstSize, src, srcSize);
|
rSize = ZSTD_copyUncompressedBlock(dst, maxDstSize, src, srcSize);
|
||||||
break;
|
break;
|
||||||
case bt_rle :
|
case bt_rle :
|
||||||
return (size_t)-ZSTD_ERROR_GENERIC; /* not yet handled */
|
return ERROR(GENERIC); /* not yet handled */
|
||||||
break;
|
break;
|
||||||
case bt_end : /* should never happen (filtered at phase 1) */
|
case bt_end : /* should never happen (filtered at phase 1) */
|
||||||
rSize = 0;
|
rSize = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return (size_t)-ZSTD_ERROR_GENERIC;
|
return ERROR(GENERIC);
|
||||||
}
|
}
|
||||||
ctx->phase = 1;
|
ctx->phase = 1;
|
||||||
ctx->expected = ZSTD_blockHeaderSize;
|
ctx->expected = ZSTD_blockHeaderSize;
|
||||||
@@ -2174,5 +2088,3 @@ size_t ZSTDv01_decompressContinue(ZSTDv01_Dctx* dctx, void* dst, size_t maxDstSi
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+12
-32
@@ -1,36 +1,14 @@
|
|||||||
/*
|
/**
|
||||||
zstd - standard compression library
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Header File
|
* All rights reserved.
|
||||||
Copyright (C) 2014-2015, Yann Collet.
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
#ifndef ZSTD_V01_H_28739879432
|
||||||
|
#define ZSTD_V01_H_28739879432
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
You can contact the author at :
|
|
||||||
- zstd source repository : https://github.com/Cyan4973/zstd
|
|
||||||
- ztsd public forum : https://groups.google.com/forum/#!forum/lz4c
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -98,3 +76,5 @@ size_t ZSTDv01_decompressContinue(ZSTDv01_Dctx* dctx, void* dst, size_t maxDstSi
|
|||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* ZSTD_V01_H_28739879432 */
|
||||||
|
|||||||
+39
-124
@@ -1,45 +1,17 @@
|
|||||||
/* ******************************************************************
|
/**
|
||||||
Error codes and messages
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) 2013-2015, Yann Collet
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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 ERROR_H_MODULE
|
|
||||||
#define ERROR_H_MODULE
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stddef.h> /* size_t, ptrdiff_t */
|
#include <stddef.h> /* size_t, ptrdiff_t */
|
||||||
#include "zstd_v02.h"
|
#include "zstd_v02.h"
|
||||||
|
#include "error_private.h"
|
||||||
|
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
* Compiler-specific
|
* Compiler-specific
|
||||||
@@ -48,46 +20,6 @@ extern "C" {
|
|||||||
# include <stdlib.h> /* _byteswap_ulong */
|
# include <stdlib.h> /* _byteswap_ulong */
|
||||||
# include <intrin.h> /* _byteswap_* */
|
# include <intrin.h> /* _byteswap_* */
|
||||||
#endif
|
#endif
|
||||||
#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
|
||||||
# define ERR_STATIC static inline
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
# define ERR_STATIC static __inline
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
# define ERR_STATIC static __attribute__((unused))
|
|
||||||
#else
|
|
||||||
# define ERR_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************
|
|
||||||
* Error Management
|
|
||||||
******************************************/
|
|
||||||
#define PREFIX(name) ZSTD_error_##name
|
|
||||||
|
|
||||||
#define ERROR(name) (size_t)-PREFIX(name)
|
|
||||||
|
|
||||||
#define ERROR_LIST(ITEM) \
|
|
||||||
ITEM(PREFIX(No_Error)) ITEM(PREFIX(GENERIC)) \
|
|
||||||
ITEM(PREFIX(memory_allocation)) \
|
|
||||||
ITEM(PREFIX(dstSize_tooSmall)) ITEM(PREFIX(srcSize_wrong)) \
|
|
||||||
ITEM(PREFIX(prefix_unknown)) ITEM(PREFIX(corruption_detected)) \
|
|
||||||
ITEM(PREFIX(tableLog_tooLarge)) ITEM(PREFIX(maxSymbolValue_tooLarge)) ITEM(PREFIX(maxSymbolValue_tooSmall)) \
|
|
||||||
ITEM(PREFIX(maxCode))
|
|
||||||
|
|
||||||
#define ERROR_GENERATE_ENUM(ENUM) ENUM,
|
|
||||||
typedef enum { ERROR_LIST(ERROR_GENERATE_ENUM) } ERR_codes; /* enum is exposed, to detect & handle specific errors; compare function result to -enum value */
|
|
||||||
|
|
||||||
#define ERROR_CONVERTTOSTRING(STRING) #STRING,
|
|
||||||
#define ERROR_GENERATE_STRING(EXPR) ERROR_CONVERTTOSTRING(EXPR)
|
|
||||||
|
|
||||||
ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ERROR_H_MODULE */
|
|
||||||
|
|
||||||
|
|
||||||
/* ******************************************************************
|
/* ******************************************************************
|
||||||
@@ -1146,12 +1078,15 @@ typedef struct ZSTD_DCtx_s ZSTD_DCtx;
|
|||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
||||||
#else
|
#else
|
||||||
# ifdef __GNUC__
|
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
||||||
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
# ifdef __GNUC__
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
# define FORCE_INLINE static inline __attribute__((always_inline))
|
||||||
|
# else
|
||||||
|
# define FORCE_INLINE static inline
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
# define FORCE_INLINE static inline
|
# define FORCE_INLINE static
|
||||||
# endif
|
# endif /* __STDC_VERSION__ */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -1619,15 +1554,7 @@ static size_t FSE_decompress(void* dst, size_t maxDstSize, const void* cSrc, siz
|
|||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER /* Visual Studio */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
# define FORCE_INLINE static __forceinline
|
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
#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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -2814,17 +2741,9 @@ static size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER /* Visual Studio */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
# define FORCE_INLINE static __forceinline
|
|
||||||
# include <intrin.h> /* For Visual 2005 */
|
# include <intrin.h> /* For Visual 2005 */
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
|
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
|
||||||
#else
|
|
||||||
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
|
||||||
# ifdef __GNUC__
|
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
|
||||||
# else
|
|
||||||
# define FORCE_INLINE static inline
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -3100,7 +3019,6 @@ static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* d
|
|||||||
/* Build DTables */
|
/* Build DTables */
|
||||||
switch(LLtype)
|
switch(LLtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
|
||||||
case bt_rle :
|
case bt_rle :
|
||||||
LLlog = 0;
|
LLlog = 0;
|
||||||
FSE_buildDTable_rle(DTableLL, *ip++); break;
|
FSE_buildDTable_rle(DTableLL, *ip++); break;
|
||||||
@@ -3108,17 +3026,16 @@ static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* d
|
|||||||
LLlog = LLbits;
|
LLlog = LLbits;
|
||||||
FSE_buildDTable_raw(DTableLL, LLbits); break;
|
FSE_buildDTable_raw(DTableLL, LLbits); break;
|
||||||
default :
|
default :
|
||||||
max = MaxLL;
|
{ U32 max = MaxLL;
|
||||||
headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
|
headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
|
||||||
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
||||||
if (LLlog > LLFSELog) return ERROR(corruption_detected);
|
if (LLlog > LLFSELog) return ERROR(corruption_detected);
|
||||||
ip += headerSize;
|
ip += headerSize;
|
||||||
FSE_buildDTable(DTableLL, norm, max, LLlog);
|
FSE_buildDTable(DTableLL, norm, max, LLlog);
|
||||||
}
|
} }
|
||||||
|
|
||||||
switch(Offtype)
|
switch(Offtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
|
||||||
case bt_rle :
|
case bt_rle :
|
||||||
Offlog = 0;
|
Offlog = 0;
|
||||||
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
||||||
@@ -3128,17 +3045,16 @@ static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* d
|
|||||||
Offlog = Offbits;
|
Offlog = Offbits;
|
||||||
FSE_buildDTable_raw(DTableOffb, Offbits); break;
|
FSE_buildDTable_raw(DTableOffb, Offbits); break;
|
||||||
default :
|
default :
|
||||||
max = MaxOff;
|
{ U32 max = MaxOff;
|
||||||
headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
|
headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
|
||||||
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
||||||
if (Offlog > OffFSELog) return ERROR(corruption_detected);
|
if (Offlog > OffFSELog) return ERROR(corruption_detected);
|
||||||
ip += headerSize;
|
ip += headerSize;
|
||||||
FSE_buildDTable(DTableOffb, norm, max, Offlog);
|
FSE_buildDTable(DTableOffb, norm, max, Offlog);
|
||||||
}
|
} }
|
||||||
|
|
||||||
switch(MLtype)
|
switch(MLtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
|
||||||
case bt_rle :
|
case bt_rle :
|
||||||
MLlog = 0;
|
MLlog = 0;
|
||||||
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
||||||
@@ -3147,14 +3063,13 @@ static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* d
|
|||||||
MLlog = MLbits;
|
MLlog = MLbits;
|
||||||
FSE_buildDTable_raw(DTableML, MLbits); break;
|
FSE_buildDTable_raw(DTableML, MLbits); break;
|
||||||
default :
|
default :
|
||||||
max = MaxML;
|
{ U32 max = MaxML;
|
||||||
headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
|
headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
|
||||||
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
||||||
if (MLlog > MLFSELog) return ERROR(corruption_detected);
|
if (MLlog > MLFSELog) return ERROR(corruption_detected);
|
||||||
ip += headerSize;
|
ip += headerSize;
|
||||||
FSE_buildDTable(DTableML, norm, max, MLlog);
|
FSE_buildDTable(DTableML, norm, max, MLlog);
|
||||||
}
|
} } }
|
||||||
}
|
|
||||||
|
|
||||||
return ip-istart;
|
return ip-istart;
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-32
@@ -1,36 +1,14 @@
|
|||||||
/*
|
/**
|
||||||
zstd_v02 - decoder for 0.2 format
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Header File
|
* All rights reserved.
|
||||||
Copyright (C) 2015, Yann Collet.
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
#ifndef ZSTD_V02_H_4174539423
|
||||||
|
#define ZSTD_V02_H_4174539423
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
You can contact the author at :
|
|
||||||
- zstd source repository : https://github.com/Cyan4973/zstd
|
|
||||||
- ztsd public forum : https://groups.google.com/forum/#!forum/lz4c
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -97,3 +75,5 @@ size_t ZSTDv02_decompressContinue(ZSTDv02_Dctx* dctx, void* dst, size_t maxDstSi
|
|||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* ZSTD_V02_H_4174539423 */
|
||||||
|
|||||||
+40
-126
@@ -1,45 +1,17 @@
|
|||||||
/* ******************************************************************
|
/**
|
||||||
Error codes and messages
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) 2013-2015, Yann Collet
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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 ERROR_H_MODULE
|
|
||||||
#define ERROR_H_MODULE
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stddef.h> /* size_t, ptrdiff_t */
|
#include <stddef.h> /* size_t, ptrdiff_t */
|
||||||
#include "zstd_v03.h"
|
#include "zstd_v03.h"
|
||||||
|
#include "error_private.h"
|
||||||
|
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
* Compiler-specific
|
* Compiler-specific
|
||||||
@@ -48,47 +20,8 @@ extern "C" {
|
|||||||
# include <stdlib.h> /* _byteswap_ulong */
|
# include <stdlib.h> /* _byteswap_ulong */
|
||||||
# include <intrin.h> /* _byteswap_* */
|
# include <intrin.h> /* _byteswap_* */
|
||||||
#endif
|
#endif
|
||||||
#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
|
||||||
# define ERR_STATIC static inline
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
# define ERR_STATIC static __inline
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
# define ERR_STATIC static __attribute__((unused))
|
|
||||||
#else
|
|
||||||
# define ERR_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************
|
|
||||||
* Error Management
|
|
||||||
******************************************/
|
|
||||||
#define PREFIX(name) ZSTD_error_##name
|
|
||||||
|
|
||||||
#define ERROR(name) (size_t)-PREFIX(name)
|
|
||||||
|
|
||||||
#define ERROR_LIST(ITEM) \
|
|
||||||
ITEM(PREFIX(No_Error)) ITEM(PREFIX(GENERIC)) \
|
|
||||||
ITEM(PREFIX(memory_allocation)) \
|
|
||||||
ITEM(PREFIX(dstSize_tooSmall)) ITEM(PREFIX(srcSize_wrong)) \
|
|
||||||
ITEM(PREFIX(prefix_unknown)) ITEM(PREFIX(corruption_detected)) \
|
|
||||||
ITEM(PREFIX(tableLog_tooLarge)) ITEM(PREFIX(maxSymbolValue_tooLarge)) ITEM(PREFIX(maxSymbolValue_tooSmall)) \
|
|
||||||
ITEM(PREFIX(maxCode))
|
|
||||||
|
|
||||||
#define ERROR_GENERATE_ENUM(ENUM) ENUM,
|
|
||||||
typedef enum { ERROR_LIST(ERROR_GENERATE_ENUM) } ERR_codes; /* enum is exposed, to detect & handle specific errors; compare function result to -enum value */
|
|
||||||
|
|
||||||
#define ERROR_CONVERTTOSTRING(STRING) #STRING,
|
|
||||||
#define ERROR_GENERATE_STRING(EXPR) ERROR_CONVERTTOSTRING(EXPR)
|
|
||||||
|
|
||||||
ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ERROR_H_MODULE */
|
|
||||||
|
|
||||||
|
|
||||||
/* ******************************************************************
|
/* ******************************************************************
|
||||||
mem.h
|
mem.h
|
||||||
@@ -1146,12 +1079,15 @@ typedef struct ZSTD_DCtx_s ZSTD_DCtx;
|
|||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
||||||
#else
|
#else
|
||||||
# ifdef __GNUC__
|
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
||||||
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
# ifdef __GNUC__
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
# define FORCE_INLINE static inline __attribute__((always_inline))
|
||||||
|
# else
|
||||||
|
# define FORCE_INLINE static inline
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
# define FORCE_INLINE static inline
|
# define FORCE_INLINE static
|
||||||
# endif
|
# endif /* __STDC_VERSION__ */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -1612,25 +1548,13 @@ static size_t FSE_decompress(void* dst, size_t maxDstSize, const void* cSrc, siz
|
|||||||
#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
||||||
/* inline is defined */
|
/* inline is defined */
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# define inline __inline
|
# define inline __inline
|
||||||
#else
|
#else
|
||||||
# define inline /* disable inline */
|
# define inline /* disable inline */
|
||||||
#endif
|
#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 GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
|
||||||
# else
|
|
||||||
# define FORCE_INLINE static inline
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
* Includes
|
* Includes
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
@@ -2456,17 +2380,11 @@ static size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER /* Visual Studio */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
# define FORCE_INLINE static __forceinline
|
|
||||||
# include <intrin.h> /* For Visual 2005 */
|
# include <intrin.h> /* For Visual 2005 */
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
|
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
|
||||||
#else
|
#else
|
||||||
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||||
# ifdef __GNUC__
|
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
|
||||||
# else
|
|
||||||
# define FORCE_INLINE static inline
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -2742,7 +2660,6 @@ static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* d
|
|||||||
/* Build DTables */
|
/* Build DTables */
|
||||||
switch(LLtype)
|
switch(LLtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
|
||||||
case bt_rle :
|
case bt_rle :
|
||||||
LLlog = 0;
|
LLlog = 0;
|
||||||
FSE_buildDTable_rle(DTableLL, *ip++); break;
|
FSE_buildDTable_rle(DTableLL, *ip++); break;
|
||||||
@@ -2750,17 +2667,16 @@ static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* d
|
|||||||
LLlog = LLbits;
|
LLlog = LLbits;
|
||||||
FSE_buildDTable_raw(DTableLL, LLbits); break;
|
FSE_buildDTable_raw(DTableLL, LLbits); break;
|
||||||
default :
|
default :
|
||||||
max = MaxLL;
|
{ U32 max = MaxLL;
|
||||||
headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
|
headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
|
||||||
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
||||||
if (LLlog > LLFSELog) return ERROR(corruption_detected);
|
if (LLlog > LLFSELog) return ERROR(corruption_detected);
|
||||||
ip += headerSize;
|
ip += headerSize;
|
||||||
FSE_buildDTable(DTableLL, norm, max, LLlog);
|
FSE_buildDTable(DTableLL, norm, max, LLlog);
|
||||||
}
|
} }
|
||||||
|
|
||||||
switch(Offtype)
|
switch(Offtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
|
||||||
case bt_rle :
|
case bt_rle :
|
||||||
Offlog = 0;
|
Offlog = 0;
|
||||||
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
||||||
@@ -2770,17 +2686,16 @@ static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* d
|
|||||||
Offlog = Offbits;
|
Offlog = Offbits;
|
||||||
FSE_buildDTable_raw(DTableOffb, Offbits); break;
|
FSE_buildDTable_raw(DTableOffb, Offbits); break;
|
||||||
default :
|
default :
|
||||||
max = MaxOff;
|
{ U32 max = MaxOff;
|
||||||
headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
|
headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
|
||||||
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
||||||
if (Offlog > OffFSELog) return ERROR(corruption_detected);
|
if (Offlog > OffFSELog) return ERROR(corruption_detected);
|
||||||
ip += headerSize;
|
ip += headerSize;
|
||||||
FSE_buildDTable(DTableOffb, norm, max, Offlog);
|
FSE_buildDTable(DTableOffb, norm, max, Offlog);
|
||||||
}
|
} }
|
||||||
|
|
||||||
switch(MLtype)
|
switch(MLtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
|
||||||
case bt_rle :
|
case bt_rle :
|
||||||
MLlog = 0;
|
MLlog = 0;
|
||||||
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
||||||
@@ -2789,14 +2704,13 @@ static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* d
|
|||||||
MLlog = MLbits;
|
MLlog = MLbits;
|
||||||
FSE_buildDTable_raw(DTableML, MLbits); break;
|
FSE_buildDTable_raw(DTableML, MLbits); break;
|
||||||
default :
|
default :
|
||||||
max = MaxML;
|
{ U32 max = MaxML;
|
||||||
headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
|
headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
|
||||||
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
||||||
if (MLlog > MLFSELog) return ERROR(corruption_detected);
|
if (MLlog > MLFSELog) return ERROR(corruption_detected);
|
||||||
ip += headerSize;
|
ip += headerSize;
|
||||||
FSE_buildDTable(DTableML, norm, max, MLlog);
|
FSE_buildDTable(DTableML, norm, max, MLlog);
|
||||||
}
|
} } }
|
||||||
}
|
|
||||||
|
|
||||||
return ip-istart;
|
return ip-istart;
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-32
@@ -1,36 +1,14 @@
|
|||||||
/*
|
/**
|
||||||
zstd_v03 - decoder for 0.3 format
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Header File
|
* All rights reserved.
|
||||||
Copyright (C) 2015, Yann Collet.
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
#ifndef ZSTD_V03_H_298734209782
|
||||||
|
#define ZSTD_V03_H_298734209782
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
You can contact the author at :
|
|
||||||
- zstd source repository : https://github.com/Cyan4973/zstd
|
|
||||||
- ztsd public forum : https://groups.google.com/forum/#!forum/lz4c
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -97,3 +75,5 @@ size_t ZSTDv03_decompressContinue(ZSTDv03_Dctx* dctx, void* dst, size_t maxDstSi
|
|||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* ZSTD_V03_H_298734209782 */
|
||||||
|
|||||||
+40
-262
@@ -1,39 +1,16 @@
|
|||||||
/* ******************************************************************
|
/**
|
||||||
zstd_v04.c
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Decompression module for ZSTD v0.4 legacy format
|
* All rights reserved.
|
||||||
Copyright (C) 2016, Yann Collet.
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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 -*/
|
/*- Dependencies -*/
|
||||||
#include "zstd_v04.h"
|
#include "zstd_v04.h"
|
||||||
|
#include "error_private.h"
|
||||||
|
|
||||||
|
|
||||||
/* ******************************************************************
|
/* ******************************************************************
|
||||||
@@ -274,79 +251,6 @@ MEM_STATIC size_t MEM_readLEST(const void* memPtr)
|
|||||||
|
|
||||||
#endif /* MEM_H_MODULE */
|
#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 :
|
|
||||||
- Source repository : https://github.com/Cyan4973/zstd
|
|
||||||
****************************************************************** */
|
|
||||||
#ifndef ERROR_PUBLIC_H_MODULE
|
|
||||||
#define ERROR_PUBLIC_H_MODULE
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ****************************************
|
|
||||||
* error list
|
|
||||||
******************************************/
|
|
||||||
enum {
|
|
||||||
ZSTD_error_No_Error,
|
|
||||||
ZSTD_error_GENERIC,
|
|
||||||
ZSTD_error_prefix_unknown,
|
|
||||||
ZSTD_error_frameParameter_unsupported,
|
|
||||||
ZSTD_error_frameParameter_unsupportedBy32bitsImplementation,
|
|
||||||
ZSTD_error_init_missing,
|
|
||||||
ZSTD_error_memory_allocation,
|
|
||||||
ZSTD_error_stage_wrong,
|
|
||||||
ZSTD_error_dstSize_tooSmall,
|
|
||||||
ZSTD_error_srcSize_wrong,
|
|
||||||
ZSTD_error_corruption_detected,
|
|
||||||
ZSTD_error_tableLog_tooLarge,
|
|
||||||
ZSTD_error_maxSymbolValue_tooLarge,
|
|
||||||
ZSTD_error_maxSymbolValue_tooSmall,
|
|
||||||
ZSTD_error_maxCode
|
|
||||||
};
|
|
||||||
|
|
||||||
/* note : functions provide error codes in reverse negative order,
|
|
||||||
so compare with (size_t)(0-enum) */
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ERROR_PUBLIC_H_MODULE */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
zstd - standard compression library
|
zstd - standard compression library
|
||||||
Header File for static linking only
|
Header File for static linking only
|
||||||
@@ -480,115 +384,6 @@ static size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstS
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ******************************************************************
|
|
||||||
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 :
|
|
||||||
- Source repository : https://github.com/Cyan4973/zstd
|
|
||||||
****************************************************************** */
|
|
||||||
/* 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
|
|
||||||
|
|
||||||
|
|
||||||
/* *****************************************
|
|
||||||
* Includes
|
|
||||||
******************************************/
|
|
||||||
#include <stddef.h> /* size_t, ptrdiff_t */
|
|
||||||
|
|
||||||
|
|
||||||
/* *****************************************
|
|
||||||
* 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
|
|
||||||
|
|
||||||
|
|
||||||
/* *****************************************
|
|
||||||
* Error Codes
|
|
||||||
******************************************/
|
|
||||||
#define PREFIX(name) ZSTD_error_##name
|
|
||||||
|
|
||||||
#ifdef ERROR
|
|
||||||
# undef ERROR /* reported already defined on VS 2015 by Rich Geldreich */
|
|
||||||
#endif
|
|
||||||
#define ERROR(name) (size_t)-PREFIX(name)
|
|
||||||
|
|
||||||
ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }
|
|
||||||
|
|
||||||
|
|
||||||
/* *****************************************
|
|
||||||
* Error Strings
|
|
||||||
******************************************/
|
|
||||||
|
|
||||||
ERR_STATIC const char* ERR_getErrorName(size_t code)
|
|
||||||
{
|
|
||||||
static const char* codeError = "Unspecified error code";
|
|
||||||
switch( (size_t)(0-code) )
|
|
||||||
{
|
|
||||||
case ZSTD_error_No_Error: return "No error detected";
|
|
||||||
case ZSTD_error_GENERIC: return "Error (generic)";
|
|
||||||
case ZSTD_error_prefix_unknown: return "Unknown frame descriptor";
|
|
||||||
case ZSTD_error_frameParameter_unsupported: return "Unsupported frame parameter";
|
|
||||||
case ZSTD_error_frameParameter_unsupportedBy32bitsImplementation: return "Frame parameter unsupported in 32-bits mode";
|
|
||||||
case ZSTD_error_init_missing: return "Context should be init first";
|
|
||||||
case ZSTD_error_memory_allocation: return "Allocation error : not enough memory";
|
|
||||||
case ZSTD_error_dstSize_tooSmall: return "Destination buffer is too small";
|
|
||||||
case ZSTD_error_srcSize_wrong: return "Src size incorrect";
|
|
||||||
case ZSTD_error_corruption_detected: return "Corrupted block detected";
|
|
||||||
case ZSTD_error_tableLog_tooLarge: return "tableLog requires too much memory";
|
|
||||||
case ZSTD_error_maxSymbolValue_tooLarge: return "Unsupported max possible Symbol Value : too large";
|
|
||||||
case ZSTD_error_maxSymbolValue_tooSmall: return "Specified maxSymbolValue is too small";
|
|
||||||
case ZSTD_error_maxCode:
|
|
||||||
default: return codeError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ERROR_H_MODULE */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* ZSTD_STATIC_H */
|
#endif /* ZSTD_STATIC_H */
|
||||||
|
|
||||||
@@ -1404,12 +1199,15 @@ MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
|
|||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
||||||
#else
|
#else
|
||||||
# ifdef __GNUC__
|
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
||||||
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
# ifdef __GNUC__
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
# define FORCE_INLINE static inline __attribute__((always_inline))
|
||||||
|
# else
|
||||||
|
# define FORCE_INLINE static inline
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
# define FORCE_INLINE static inline
|
# define FORCE_INLINE static
|
||||||
# endif
|
# endif /* __STDC_VERSION__ */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -2045,15 +1843,7 @@ static size_t HUF_decompress4X4_usingDTable(void* dst, size_t maxDstSize, const
|
|||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER /* Visual Studio */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
# define FORCE_INLINE static __forceinline
|
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
#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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -2861,17 +2651,9 @@ static size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_
|
|||||||
* Compiler specifics
|
* Compiler specifics
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
#ifdef _MSC_VER /* Visual Studio */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
# define FORCE_INLINE static __forceinline
|
|
||||||
# include <intrin.h> /* For Visual 2005 */
|
# include <intrin.h> /* For Visual 2005 */
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
|
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
|
||||||
#else
|
|
||||||
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
|
||||||
# ifdef __GNUC__
|
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
|
||||||
# else
|
|
||||||
# define FORCE_INLINE static inline
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -2992,7 +2774,7 @@ static size_t ZSTD_decodeFrameHeader_Part2(ZSTD_DCtx* zc, const void* src, size_
|
|||||||
size_t result;
|
size_t result;
|
||||||
if (srcSize != zc->headerSize) return ERROR(srcSize_wrong);
|
if (srcSize != zc->headerSize) return ERROR(srcSize_wrong);
|
||||||
result = ZSTD_getFrameParams(&(zc->params), src, srcSize);
|
result = ZSTD_getFrameParams(&(zc->params), src, srcSize);
|
||||||
if ((MEM_32bits()) && (zc->params.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bitsImplementation);
|
if ((MEM_32bits()) && (zc->params.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bits);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3145,7 +2927,6 @@ static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* d
|
|||||||
/* Build DTables */
|
/* Build DTables */
|
||||||
switch(LLtype)
|
switch(LLtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
|
||||||
case bt_rle :
|
case bt_rle :
|
||||||
LLlog = 0;
|
LLlog = 0;
|
||||||
FSE_buildDTable_rle(DTableLL, *ip++); break;
|
FSE_buildDTable_rle(DTableLL, *ip++); break;
|
||||||
@@ -3153,17 +2934,16 @@ static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* d
|
|||||||
LLlog = LLbits;
|
LLlog = LLbits;
|
||||||
FSE_buildDTable_raw(DTableLL, LLbits); break;
|
FSE_buildDTable_raw(DTableLL, LLbits); break;
|
||||||
default :
|
default :
|
||||||
max = MaxLL;
|
{ U32 max = MaxLL;
|
||||||
headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
|
headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
|
||||||
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
||||||
if (LLlog > LLFSELog) return ERROR(corruption_detected);
|
if (LLlog > LLFSELog) return ERROR(corruption_detected);
|
||||||
ip += headerSize;
|
ip += headerSize;
|
||||||
FSE_buildDTable(DTableLL, norm, max, LLlog);
|
FSE_buildDTable(DTableLL, norm, max, LLlog);
|
||||||
}
|
} }
|
||||||
|
|
||||||
switch(Offtype)
|
switch(Offtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
|
||||||
case bt_rle :
|
case bt_rle :
|
||||||
Offlog = 0;
|
Offlog = 0;
|
||||||
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
||||||
@@ -3173,17 +2953,16 @@ static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* d
|
|||||||
Offlog = Offbits;
|
Offlog = Offbits;
|
||||||
FSE_buildDTable_raw(DTableOffb, Offbits); break;
|
FSE_buildDTable_raw(DTableOffb, Offbits); break;
|
||||||
default :
|
default :
|
||||||
max = MaxOff;
|
{ U32 max = MaxOff;
|
||||||
headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
|
headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
|
||||||
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
||||||
if (Offlog > OffFSELog) return ERROR(corruption_detected);
|
if (Offlog > OffFSELog) return ERROR(corruption_detected);
|
||||||
ip += headerSize;
|
ip += headerSize;
|
||||||
FSE_buildDTable(DTableOffb, norm, max, Offlog);
|
FSE_buildDTable(DTableOffb, norm, max, Offlog);
|
||||||
}
|
} }
|
||||||
|
|
||||||
switch(MLtype)
|
switch(MLtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
|
||||||
case bt_rle :
|
case bt_rle :
|
||||||
MLlog = 0;
|
MLlog = 0;
|
||||||
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
||||||
@@ -3192,14 +2971,13 @@ static size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* d
|
|||||||
MLlog = MLbits;
|
MLlog = MLbits;
|
||||||
FSE_buildDTable_raw(DTableML, MLbits); break;
|
FSE_buildDTable_raw(DTableML, MLbits); break;
|
||||||
default :
|
default :
|
||||||
max = MaxML;
|
{ U32 max = MaxML;
|
||||||
headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
|
headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
|
||||||
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
||||||
if (MLlog > MLFSELog) return ERROR(corruption_detected);
|
if (MLlog > MLFSELog) return ERROR(corruption_detected);
|
||||||
ip += headerSize;
|
ip += headerSize;
|
||||||
FSE_buildDTable(DTableML, norm, max, MLlog);
|
FSE_buildDTable(DTableML, norm, max, MLlog);
|
||||||
}
|
} } }
|
||||||
}
|
|
||||||
|
|
||||||
return ip-istart;
|
return ip-istart;
|
||||||
}
|
}
|
||||||
@@ -3701,7 +3479,7 @@ static void ZSTD_decompress_insertDictionary(ZSTD_DCtx* ctx, const void* dict, s
|
|||||||
* The function will report how many bytes were read or written by modifying *srcSizePtr and *maxDstSizePtr.
|
* The function will report how many bytes were read or written by modifying *srcSizePtr and *maxDstSizePtr.
|
||||||
* Note that it may not consume the entire input, in which case it's up to the caller to call again the function with remaining input.
|
* Note that it may not consume the entire input, in which case it's up to the caller to call again the function with remaining input.
|
||||||
* The content of dst will be overwritten (up to *maxDstSizePtr) at each function call, so save its content if it matters or change dst .
|
* The content of dst will be overwritten (up to *maxDstSizePtr) 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 improve latency)
|
* return : a hint to preferred nb of bytes to use as input for next function call (it's only a hint, to improve latency)
|
||||||
* or 0 when a frame is completely decoded
|
* or 0 when a frame is completely decoded
|
||||||
* or an error code, which can be tested using ZBUFF_isError().
|
* or an error code, which can be tested using ZBUFF_isError().
|
||||||
*
|
*
|
||||||
|
|||||||
+12
-32
@@ -1,36 +1,14 @@
|
|||||||
/*
|
/**
|
||||||
zstd_v04 - decoder for 0.4 format
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Header File
|
* All rights reserved.
|
||||||
Copyright (C) 2016, Yann Collet.
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
#ifndef ZSTD_V04_H_91868324769238
|
||||||
|
#define ZSTD_V04_H_91868324769238
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
You can contact the author at :
|
|
||||||
- zstd source repository : https://github.com/Cyan4973/zstd
|
|
||||||
- ztsd public forum : https://groups.google.com/forum/#!forum/lz4c
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -146,3 +124,5 @@ size_t ZBUFFv04_recommendedDOutSize(void);
|
|||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* ZSTD_V04_H_91868324769238 */
|
||||||
|
|||||||
+45
-272
@@ -1,39 +1,16 @@
|
|||||||
/* ******************************************************************
|
/**
|
||||||
zstd_v05.c
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Decompression module for ZSTD v0.5 legacy format
|
* All rights reserved.
|
||||||
Copyright (C) 2016, Yann Collet.
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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 -*/
|
/*- Dependencies -*/
|
||||||
#include "zstd_v05.h"
|
#include "zstd_v05.h"
|
||||||
|
#include "error_private.h"
|
||||||
|
|
||||||
|
|
||||||
/* ******************************************************************
|
/* ******************************************************************
|
||||||
@@ -278,79 +255,6 @@ MEM_STATIC size_t MEM_readLEST(const void* memPtr)
|
|||||||
|
|
||||||
#endif /* MEM_H_MODULE */
|
#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 :
|
|
||||||
- Source repository : https://github.com/Cyan4973/zstd
|
|
||||||
****************************************************************** */
|
|
||||||
#ifndef ERROR_PUBLIC_H_MODULE
|
|
||||||
#define ERROR_PUBLIC_H_MODULE
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ****************************************
|
|
||||||
* error codes list
|
|
||||||
******************************************/
|
|
||||||
typedef enum {
|
|
||||||
ZSTDv05_error_no_error,
|
|
||||||
ZSTDv05_error_GENERIC,
|
|
||||||
ZSTDv05_error_prefix_unknown,
|
|
||||||
ZSTDv05_error_frameParameter_unsupported,
|
|
||||||
ZSTDv05_error_frameParameter_unsupportedBy32bits,
|
|
||||||
ZSTDv05_error_init_missing,
|
|
||||||
ZSTDv05_error_memory_allocation,
|
|
||||||
ZSTDv05_error_stage_wrong,
|
|
||||||
ZSTDv05_error_dstSize_tooSmall,
|
|
||||||
ZSTDv05_error_srcSize_wrong,
|
|
||||||
ZSTDv05_error_corruption_detected,
|
|
||||||
ZSTDv05_error_tableLog_tooLarge,
|
|
||||||
ZSTDv05_error_maxSymbolValue_tooLarge,
|
|
||||||
ZSTDv05_error_maxSymbolValue_tooSmall,
|
|
||||||
ZSTDv05_error_dictionary_corrupted,
|
|
||||||
ZSTDv05_error_maxCode
|
|
||||||
} ZSTDv05_ErrorCode;
|
|
||||||
|
|
||||||
/* note : functions provide error codes in reverse negative order,
|
|
||||||
so compare with (size_t)(0-enum) */
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ERROR_PUBLIC_H_MODULE */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
zstd - standard compression library
|
zstd - standard compression library
|
||||||
Header File for static linking only
|
Header File for static linking only
|
||||||
@@ -494,119 +398,6 @@ size_t ZSTDv05_decompressBlock(ZSTDv05_DCtx* dctx, void* dst, size_t dstCapacity
|
|||||||
#endif /* ZSTDv05_STATIC_H */
|
#endif /* ZSTDv05_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 :
|
|
||||||
- Source repository : https://github.com/Cyan4973/zstd
|
|
||||||
****************************************************************** */
|
|
||||||
/* 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
|
|
||||||
******************************************/
|
|
||||||
typedef ZSTDv05_ErrorCode ERR_enum;
|
|
||||||
#define PREFIX(name) ZSTDv05_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_getError(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); }
|
|
||||||
|
|
||||||
|
|
||||||
/*-****************************************
|
|
||||||
* Error Strings
|
|
||||||
******************************************/
|
|
||||||
|
|
||||||
ERR_STATIC const char* ERR_getErrorName(size_t code)
|
|
||||||
{
|
|
||||||
static const char* notErrorCode = "Unspecified error code";
|
|
||||||
switch( ERR_getError(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(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";
|
|
||||||
case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max possible 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; /* should be impossible, due to ERR_getError() */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ERROR_H_MODULE */
|
|
||||||
/*
|
/*
|
||||||
zstd_internal - common functions to include
|
zstd_internal - common functions to include
|
||||||
Header File for include
|
Header File for include
|
||||||
@@ -859,16 +650,16 @@ void FSEv05_freeDTable(FSEv05_DTable* dt);
|
|||||||
/*!
|
/*!
|
||||||
FSEv05_buildDTable():
|
FSEv05_buildDTable():
|
||||||
Builds 'dt', which must be already allocated, using FSEv05_createDTable()
|
Builds 'dt', which must be already allocated, using FSEv05_createDTable()
|
||||||
return : 0,
|
@return : 0,
|
||||||
or an errorCode, which can be tested using FSEv05_isError() */
|
or an errorCode, which can be tested using FSEv05_isError() */
|
||||||
size_t FSEv05_buildDTable (FSEv05_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
|
size_t FSEv05_buildDTable (FSEv05_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
FSEv05_decompress_usingDTable():
|
FSEv05_decompress_usingDTable():
|
||||||
Decompress compressed source @cSrc of size @cSrcSize using @dt
|
Decompress compressed source @cSrc of size @cSrcSize using `dt`
|
||||||
into @dst which must be already allocated.
|
into `dst` which must be already allocated.
|
||||||
return : size of regenerated data (necessarily <= @dstCapacity)
|
@return : size of regenerated data (necessarily <= @dstCapacity)
|
||||||
or an errorCode, which can be tested using FSEv05_isError() */
|
or an errorCode, which can be tested using FSEv05_isError() */
|
||||||
size_t FSEv05_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSEv05_DTable* dt);
|
size_t FSEv05_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSEv05_DTable* dt);
|
||||||
|
|
||||||
|
|
||||||
@@ -1404,12 +1195,15 @@ MEM_STATIC unsigned FSEv05_endOfDState(const FSEv05_DState_t* DStatePtr)
|
|||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
||||||
#else
|
#else
|
||||||
# ifdef __GNUC__
|
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
||||||
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
# ifdef __GNUC__
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
# define FORCE_INLINE static inline __attribute__((always_inline))
|
||||||
|
# else
|
||||||
|
# define FORCE_INLINE static inline
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
# define FORCE_INLINE static inline
|
# define FORCE_INLINE static
|
||||||
# endif
|
# endif /* __STDC_VERSION__ */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -2026,14 +1820,7 @@ size_t HUFv05_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void
|
|||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER /* Visual Studio */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
# define FORCE_INLINE static __forceinline
|
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# 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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -2882,17 +2669,9 @@ size_t HUFv05_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cS
|
|||||||
* Compiler specifics
|
* Compiler specifics
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
#ifdef _MSC_VER /* Visual Studio */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
# define FORCE_INLINE static __forceinline
|
|
||||||
# include <intrin.h> /* For Visual 2005 */
|
# include <intrin.h> /* For Visual 2005 */
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
|
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
|
||||||
#else
|
|
||||||
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
|
||||||
# ifdef __GNUC__
|
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
|
||||||
# else
|
|
||||||
# define FORCE_INLINE static inline
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -2919,9 +2698,6 @@ static void ZSTDv05_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
|
|||||||
* tells if a return value is an error code */
|
* tells if a return value is an error code */
|
||||||
unsigned ZSTDv05_isError(size_t code) { return ERR_isError(code); }
|
unsigned ZSTDv05_isError(size_t code) { return ERR_isError(code); }
|
||||||
|
|
||||||
/*! ZSTDv05_getError() :
|
|
||||||
* convert a `size_t` function result into a proper ZSTDv05_errorCode enum */
|
|
||||||
ZSTDv05_ErrorCode ZSTDv05_getError(size_t code) { return ERR_getError(code); }
|
|
||||||
|
|
||||||
/*! ZSTDv05_getErrorName() :
|
/*! ZSTDv05_getErrorName() :
|
||||||
* provides error code string (useful for debugging) */
|
* provides error code string (useful for debugging) */
|
||||||
@@ -3333,7 +3109,6 @@ size_t ZSTDv05_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumps
|
|||||||
/* Build DTables */
|
/* Build DTables */
|
||||||
switch(LLtype)
|
switch(LLtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
|
||||||
case FSEv05_ENCODING_RLE :
|
case FSEv05_ENCODING_RLE :
|
||||||
LLlog = 0;
|
LLlog = 0;
|
||||||
FSEv05_buildDTable_rle(DTableLL, *ip++);
|
FSEv05_buildDTable_rle(DTableLL, *ip++);
|
||||||
@@ -3346,17 +3121,16 @@ size_t ZSTDv05_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumps
|
|||||||
break;
|
break;
|
||||||
case FSEv05_ENCODING_DYNAMIC :
|
case FSEv05_ENCODING_DYNAMIC :
|
||||||
default : /* impossible */
|
default : /* impossible */
|
||||||
max = MaxLL;
|
{ U32 max = MaxLL;
|
||||||
headerSize = FSEv05_readNCount(norm, &max, &LLlog, ip, iend-ip);
|
headerSize = FSEv05_readNCount(norm, &max, &LLlog, ip, iend-ip);
|
||||||
if (FSEv05_isError(headerSize)) return ERROR(GENERIC);
|
if (FSEv05_isError(headerSize)) return ERROR(GENERIC);
|
||||||
if (LLlog > LLFSEv05Log) return ERROR(corruption_detected);
|
if (LLlog > LLFSEv05Log) return ERROR(corruption_detected);
|
||||||
ip += headerSize;
|
ip += headerSize;
|
||||||
FSEv05_buildDTable(DTableLL, norm, max, LLlog);
|
FSEv05_buildDTable(DTableLL, norm, max, LLlog);
|
||||||
}
|
} }
|
||||||
|
|
||||||
switch(Offtype)
|
switch(Offtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
|
||||||
case FSEv05_ENCODING_RLE :
|
case FSEv05_ENCODING_RLE :
|
||||||
Offlog = 0;
|
Offlog = 0;
|
||||||
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
||||||
@@ -3370,17 +3144,16 @@ size_t ZSTDv05_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumps
|
|||||||
break;
|
break;
|
||||||
case FSEv05_ENCODING_DYNAMIC :
|
case FSEv05_ENCODING_DYNAMIC :
|
||||||
default : /* impossible */
|
default : /* impossible */
|
||||||
max = MaxOff;
|
{ U32 max = MaxOff;
|
||||||
headerSize = FSEv05_readNCount(norm, &max, &Offlog, ip, iend-ip);
|
headerSize = FSEv05_readNCount(norm, &max, &Offlog, ip, iend-ip);
|
||||||
if (FSEv05_isError(headerSize)) return ERROR(GENERIC);
|
if (FSEv05_isError(headerSize)) return ERROR(GENERIC);
|
||||||
if (Offlog > OffFSEv05Log) return ERROR(corruption_detected);
|
if (Offlog > OffFSEv05Log) return ERROR(corruption_detected);
|
||||||
ip += headerSize;
|
ip += headerSize;
|
||||||
FSEv05_buildDTable(DTableOffb, norm, max, Offlog);
|
FSEv05_buildDTable(DTableOffb, norm, max, Offlog);
|
||||||
}
|
} }
|
||||||
|
|
||||||
switch(MLtype)
|
switch(MLtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
|
||||||
case FSEv05_ENCODING_RLE :
|
case FSEv05_ENCODING_RLE :
|
||||||
MLlog = 0;
|
MLlog = 0;
|
||||||
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
||||||
@@ -3394,13 +3167,13 @@ size_t ZSTDv05_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumps
|
|||||||
break;
|
break;
|
||||||
case FSEv05_ENCODING_DYNAMIC :
|
case FSEv05_ENCODING_DYNAMIC :
|
||||||
default : /* impossible */
|
default : /* impossible */
|
||||||
max = MaxML;
|
{ U32 max = MaxML;
|
||||||
headerSize = FSEv05_readNCount(norm, &max, &MLlog, ip, iend-ip);
|
headerSize = FSEv05_readNCount(norm, &max, &MLlog, ip, iend-ip);
|
||||||
if (FSEv05_isError(headerSize)) return ERROR(GENERIC);
|
if (FSEv05_isError(headerSize)) return ERROR(GENERIC);
|
||||||
if (MLlog > MLFSEv05Log) return ERROR(corruption_detected);
|
if (MLlog > MLFSEv05Log) return ERROR(corruption_detected);
|
||||||
ip += headerSize;
|
ip += headerSize;
|
||||||
FSEv05_buildDTable(DTableML, norm, max, MLlog);
|
FSEv05_buildDTable(DTableML, norm, max, MLlog);
|
||||||
} }
|
} } }
|
||||||
|
|
||||||
return ip-istart;
|
return ip-istart;
|
||||||
}
|
}
|
||||||
@@ -4030,7 +3803,7 @@ static size_t ZBUFFv05_limitCopy(void* dst, size_t maxDstSize, const void* src,
|
|||||||
* The function will report how many bytes were read or written by modifying *srcSizePtr and *maxDstSizePtr.
|
* The function will report how many bytes were read or written by modifying *srcSizePtr and *maxDstSizePtr.
|
||||||
* Note that it may not consume the entire input, in which case it's up to the caller to call again the function with remaining input.
|
* Note that it may not consume the entire input, in which case it's up to the caller to call again the function with remaining input.
|
||||||
* The content of dst will be overwritten (up to *maxDstSizePtr) at each function call, so save its content if it matters or change dst .
|
* The content of dst will be overwritten (up to *maxDstSizePtr) 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 improve latency)
|
* return : a hint to preferred nb of bytes to use as input for next function call (it's only a hint, to improve latency)
|
||||||
* or 0 when a frame is completely decoded
|
* or 0 when a frame is completely decoded
|
||||||
* or an error code, which can be tested using ZBUFFv05_isError().
|
* or an error code, which can be tested using ZBUFFv05_isError().
|
||||||
*
|
*
|
||||||
|
|||||||
+8
-30
@@ -1,34 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
zstd_v05 - decoder for 0.5 format
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Header File
|
* All rights reserved.
|
||||||
Copyright (C) 2014-2016, Yann Collet.
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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 ZSTDv05_H
|
#ifndef ZSTDv05_H
|
||||||
#define ZSTDv05_H
|
#define ZSTDv05_H
|
||||||
|
|
||||||
|
|||||||
+21
-272
@@ -1,42 +1,19 @@
|
|||||||
/* ******************************************************************
|
/**
|
||||||
zstd_v06.c
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Decompression module for ZSTD v0.6 legacy format
|
* All rights reserved.
|
||||||
Copyright (C) 2016, Yann Collet.
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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 -*/
|
/*- Dependencies -*/
|
||||||
#include "zstd_v06.h"
|
#include "zstd_v06.h"
|
||||||
#include <stddef.h> /* size_t, ptrdiff_t */
|
#include <stddef.h> /* size_t, ptrdiff_t */
|
||||||
#include <string.h> /* memcpy */
|
#include <string.h> /* memcpy */
|
||||||
#include <stdlib.h> /* malloc, free, qsort */
|
#include <stdlib.h> /* malloc, free, qsort */
|
||||||
|
#include "error_private.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -297,77 +274,6 @@ MEM_STATIC size_t MEM_readLEST(const void* memPtr)
|
|||||||
|
|
||||||
#endif /* MEM_H_MODULE */
|
#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
|
zstd - standard compression library
|
||||||
Header File for static linking only
|
Header File for static linking only
|
||||||
@@ -420,7 +326,7 @@ extern "C" {
|
|||||||
* It avoids reloading the dictionary each time.
|
* It avoids reloading the dictionary each time.
|
||||||
* `preparedDCtx` must have been properly initialized using ZSTDv06_decompressBegin_usingDict().
|
* `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) */
|
* 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(
|
ZSTDLIBv06_API size_t ZSTDv06_decompress_usingPreparedDCtx(
|
||||||
ZSTDv06_DCtx* dctx, const ZSTDv06_DCtx* preparedDCtx,
|
ZSTDv06_DCtx* dctx, const ZSTDv06_DCtx* preparedDCtx,
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t srcSize);
|
const void* src, size_t srcSize);
|
||||||
@@ -431,7 +337,7 @@ ZSTDLIB_API size_t ZSTDv06_decompress_usingPreparedDCtx(
|
|||||||
static const size_t ZSTDv06_frameHeaderSize_min = 5;
|
static const size_t ZSTDv06_frameHeaderSize_min = 5;
|
||||||
static const size_t ZSTDv06_frameHeaderSize_max = ZSTDv06_FRAMEHEADERSIZE_MAX;
|
static const size_t ZSTDv06_frameHeaderSize_max = ZSTDv06_FRAMEHEADERSIZE_MAX;
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZSTDv06_decompressBegin(ZSTDv06_DCtx* dctx);
|
ZSTDLIBv06_API size_t ZSTDv06_decompressBegin(ZSTDv06_DCtx* dctx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Streaming decompression, direct mode (bufferless)
|
Streaming decompression, direct mode (bufferless)
|
||||||
@@ -490,140 +396,15 @@ ZSTDLIB_API size_t ZSTDv06_decompressBegin(ZSTDv06_DCtx* dctx);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define ZSTDv06_BLOCKSIZE_MAX (128 * 1024) /* define, for static allocation */
|
#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);
|
ZSTDLIBv06_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)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* ZSTDv06_STATIC_H */
|
#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
|
zstd_internal - common functions to include
|
||||||
Header File for include
|
Header File for include
|
||||||
@@ -669,19 +450,6 @@ ERR_STATIC const char* ERR_getErrorName(size_t code)
|
|||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Common constants
|
* 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_DICT_MAGIC 0xEC30A436
|
||||||
|
|
||||||
#define ZSTDv06_REP_NUM 3
|
#define ZSTDv06_REP_NUM 3
|
||||||
@@ -1396,7 +1164,7 @@ static unsigned char FSEv06_decodeSymbolFast(FSEv06_DState_t* DStatePtr, BITv06_
|
|||||||
*******************************************/
|
*******************************************/
|
||||||
|
|
||||||
|
|
||||||
/*<===== Decompression =====>*/
|
/* ====== Decompression ====== */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
U16 tableLog;
|
U16 tableLog;
|
||||||
@@ -1702,12 +1470,15 @@ size_t FSEv06_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned
|
|||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
||||||
#else
|
#else
|
||||||
# ifdef __GNUC__
|
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
||||||
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
# ifdef __GNUC__
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
# define FORCE_INLINE static inline __attribute__((always_inline))
|
||||||
|
# else
|
||||||
|
# define FORCE_INLINE static inline
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
# define FORCE_INLINE static inline
|
# define FORCE_INLINE static
|
||||||
# endif
|
# endif /* __STDC_VERSION__ */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -2275,14 +2046,7 @@ MEM_STATIC size_t HUFv06_readStats(BYTE* huffWeight, size_t hwSize, U32* rankSta
|
|||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER /* Visual Studio */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
# define FORCE_INLINE static __forceinline
|
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# 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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -3027,14 +2791,6 @@ unsigned ZSTDv06_isError(size_t code) { return ERR_isError(code); }
|
|||||||
* provides error code string from function result (useful for debugging) */
|
* provides error code string from function result (useful for debugging) */
|
||||||
const char* ZSTDv06_getErrorName(size_t code) { return ERR_getErrorName(code); }
|
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
|
* ZBUFF Error Management
|
||||||
@@ -3091,16 +2847,9 @@ const char* ZBUFFv06_getErrorName(size_t errorCode) { return ERR_getErrorName(er
|
|||||||
* Compiler specifics
|
* Compiler specifics
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
#ifdef _MSC_VER /* Visual Studio */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
# define FORCE_INLINE static __forceinline
|
|
||||||
# include <intrin.h> /* For Visual 2005 */
|
# include <intrin.h> /* For Visual 2005 */
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
|
# 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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+40
-66
@@ -1,34 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
zstd_v06 - decoder for 0.6 format
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Header File
|
* All rights reserved.
|
||||||
Copyright (C) 2014-2016, Yann Collet.
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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
|
#ifndef ZSTDv06_H
|
||||||
#define ZSTDv06_H
|
#define ZSTDv06_H
|
||||||
|
|
||||||
@@ -36,23 +14,19 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-*************************************
|
/*====== Dependency ======*/
|
||||||
* Dependencies
|
|
||||||
***************************************/
|
|
||||||
#include <stddef.h> /* size_t */
|
#include <stddef.h> /* size_t */
|
||||||
|
|
||||||
|
|
||||||
/*-***************************************************************
|
/*====== Export for Windows ======*/
|
||||||
* Export parameters
|
|
||||||
*****************************************************************/
|
|
||||||
/*!
|
/*!
|
||||||
* ZSTDv06_DLL_EXPORT :
|
* ZSTDv06_DLL_EXPORT :
|
||||||
* Enable exporting of functions when building a Windows DLL
|
* Enable exporting of functions when building a Windows DLL
|
||||||
*/
|
*/
|
||||||
#if defined(_WIN32) && defined(ZSTDv06_DLL_EXPORT) && (ZSTDv06_DLL_EXPORT==1)
|
#if defined(_WIN32) && defined(ZSTDv06_DLL_EXPORT) && (ZSTDv06_DLL_EXPORT==1)
|
||||||
# define ZSTDLIB_API __declspec(dllexport)
|
# define ZSTDLIBv06_API __declspec(dllexport)
|
||||||
#else
|
#else
|
||||||
# define ZSTDLIB_API
|
# define ZSTDLIBv06_API
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -64,18 +38,18 @@ extern "C" {
|
|||||||
`dstCapacity` must be large enough, equal or larger than originalSize.
|
`dstCapacity` must be large enough, equal or larger than originalSize.
|
||||||
@return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
|
@return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
|
||||||
or an errorCode if it fails (which can be tested using ZSTDv06_isError()) */
|
or an errorCode if it fails (which can be tested using ZSTDv06_isError()) */
|
||||||
ZSTDLIB_API size_t ZSTDv06_decompress( void* dst, size_t dstCapacity,
|
ZSTDLIBv06_API size_t ZSTDv06_decompress( void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t compressedSize);
|
const void* src, size_t compressedSize);
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Helper functions
|
* Helper functions
|
||||||
***************************************/
|
***************************************/
|
||||||
ZSTDLIB_API size_t ZSTDv06_compressBound(size_t srcSize); /*!< maximum compressed size (worst case scenario) */
|
ZSTDLIBv06_API size_t ZSTDv06_compressBound(size_t srcSize); /*!< maximum compressed size (worst case scenario) */
|
||||||
|
|
||||||
/* Error Management */
|
/* Error Management */
|
||||||
ZSTDLIB_API unsigned ZSTDv06_isError(size_t code); /*!< tells if a `size_t` function result is an error code */
|
ZSTDLIBv06_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 */
|
ZSTDLIBv06_API const char* ZSTDv06_getErrorName(size_t code); /*!< provides readable string for an error code */
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
@@ -83,12 +57,12 @@ ZSTDLIB_API const char* ZSTDv06_getErrorName(size_t code); /*!< provides rea
|
|||||||
***************************************/
|
***************************************/
|
||||||
/** Decompression context */
|
/** Decompression context */
|
||||||
typedef struct ZSTDv06_DCtx_s ZSTDv06_DCtx;
|
typedef struct ZSTDv06_DCtx_s ZSTDv06_DCtx;
|
||||||
ZSTDLIB_API ZSTDv06_DCtx* ZSTDv06_createDCtx(void);
|
ZSTDLIBv06_API ZSTDv06_DCtx* ZSTDv06_createDCtx(void);
|
||||||
ZSTDLIB_API size_t ZSTDv06_freeDCtx(ZSTDv06_DCtx* dctx); /*!< @return : errorCode */
|
ZSTDLIBv06_API size_t ZSTDv06_freeDCtx(ZSTDv06_DCtx* dctx); /*!< @return : errorCode */
|
||||||
|
|
||||||
/** ZSTDv06_decompressDCtx() :
|
/** ZSTDv06_decompressDCtx() :
|
||||||
* Same as ZSTDv06_decompress(), but requires an already allocated ZSTDv06_DCtx (see ZSTDv06_createDCtx()) */
|
* 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);
|
ZSTDLIBv06_API size_t ZSTDv06_decompressDCtx(ZSTDv06_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
|
||||||
/*-***********************
|
/*-***********************
|
||||||
@@ -98,10 +72,10 @@ ZSTDLIB_API size_t ZSTDv06_decompressDCtx(ZSTDv06_DCtx* ctx, void* dst, size_t d
|
|||||||
* 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, otherwise regenerated data will be corrupted.
|
||||||
* Note : dict can be NULL, in which case, it's equivalent to ZSTDv06_decompressDCtx() */
|
* Note : dict can be NULL, in which case, it's equivalent to ZSTDv06_decompressDCtx() */
|
||||||
ZSTDLIB_API size_t ZSTDv06_decompress_usingDict(ZSTDv06_DCtx* dctx,
|
ZSTDLIBv06_API size_t ZSTDv06_decompress_usingDict(ZSTDv06_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);
|
||||||
|
|
||||||
|
|
||||||
/*-************************
|
/*-************************
|
||||||
@@ -110,12 +84,12 @@ ZSTDLIB_API size_t ZSTDv06_decompress_usingDict(ZSTDv06_DCtx* dctx,
|
|||||||
struct ZSTDv06_frameParams_s { unsigned long long frameContentSize; unsigned windowLog; };
|
struct ZSTDv06_frameParams_s { unsigned long long frameContentSize; unsigned windowLog; };
|
||||||
typedef struct ZSTDv06_frameParams_s ZSTDv06_frameParams;
|
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 */
|
ZSTDLIBv06_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);
|
ZSTDLIBv06_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);
|
ZSTDLIBv06_API void ZSTDv06_copyDCtx(ZSTDv06_DCtx* dctx, const ZSTDv06_DCtx* preparedDCtx);
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZSTDv06_nextSrcSizeToDecompress(ZSTDv06_DCtx* dctx);
|
ZSTDLIBv06_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);
|
ZSTDLIBv06_API size_t ZSTDv06_decompressContinue(ZSTDv06_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -124,15 +98,15 @@ ZSTDLIB_API size_t ZSTDv06_decompressContinue(ZSTDv06_DCtx* dctx, void* dst, siz
|
|||||||
***************************************/
|
***************************************/
|
||||||
|
|
||||||
typedef struct ZBUFFv06_DCtx_s ZBUFFv06_DCtx;
|
typedef struct ZBUFFv06_DCtx_s ZBUFFv06_DCtx;
|
||||||
ZSTDLIB_API ZBUFFv06_DCtx* ZBUFFv06_createDCtx(void);
|
ZSTDLIBv06_API ZBUFFv06_DCtx* ZBUFFv06_createDCtx(void);
|
||||||
ZSTDLIB_API size_t ZBUFFv06_freeDCtx(ZBUFFv06_DCtx* dctx);
|
ZSTDLIBv06_API size_t ZBUFFv06_freeDCtx(ZBUFFv06_DCtx* dctx);
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZBUFFv06_decompressInit(ZBUFFv06_DCtx* dctx);
|
ZSTDLIBv06_API size_t ZBUFFv06_decompressInit(ZBUFFv06_DCtx* dctx);
|
||||||
ZSTDLIB_API size_t ZBUFFv06_decompressInitDictionary(ZBUFFv06_DCtx* dctx, const void* dict, size_t dictSize);
|
ZSTDLIBv06_API size_t ZBUFFv06_decompressInitDictionary(ZBUFFv06_DCtx* dctx, const void* dict, size_t dictSize);
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* dctx,
|
ZSTDLIBv06_API size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* dctx,
|
||||||
void* dst, size_t* dstCapacityPtr,
|
void* dst, size_t* dstCapacityPtr,
|
||||||
const void* src, size_t* srcSizePtr);
|
const void* src, size_t* srcSizePtr);
|
||||||
|
|
||||||
/*-***************************************************************************
|
/*-***************************************************************************
|
||||||
* Streaming decompression howto
|
* Streaming decompression howto
|
||||||
@@ -162,13 +136,13 @@ ZSTDLIB_API size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* dctx,
|
|||||||
/* *************************************
|
/* *************************************
|
||||||
* Tool functions
|
* Tool functions
|
||||||
***************************************/
|
***************************************/
|
||||||
ZSTDLIB_API unsigned ZBUFFv06_isError(size_t errorCode);
|
ZSTDLIBv06_API unsigned ZBUFFv06_isError(size_t errorCode);
|
||||||
ZSTDLIB_API const char* ZBUFFv06_getErrorName(size_t errorCode);
|
ZSTDLIBv06_API const char* ZBUFFv06_getErrorName(size_t errorCode);
|
||||||
|
|
||||||
/** Functions below provide recommended buffer sizes for Compression or Decompression operations.
|
/** Functions below provide recommended buffer sizes for Compression or Decompression operations.
|
||||||
* These sizes are just hints, they tend to offer better latency */
|
* These sizes are just hints, they tend to offer better latency */
|
||||||
ZSTDLIB_API size_t ZBUFFv06_recommendedDInSize(void);
|
ZSTDLIBv06_API size_t ZBUFFv06_recommendedDInSize(void);
|
||||||
ZSTDLIB_API size_t ZBUFFv06_recommendedDOutSize(void);
|
ZSTDLIBv06_API size_t ZBUFFv06_recommendedDOutSize(void);
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
|
|||||||
+36
-286
@@ -1,36 +1,12 @@
|
|||||||
/* ******************************************************************
|
/**
|
||||||
zstd_v07.c
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Decompression module for ZSTD v0.7 legacy format
|
* All rights reserved.
|
||||||
Copyright (C) 2016, Yann Collet.
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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 -*/
|
/*- Dependencies -*/
|
||||||
#include <stddef.h> /* size_t, ptrdiff_t */
|
#include <stddef.h> /* size_t, ptrdiff_t */
|
||||||
@@ -45,6 +21,8 @@
|
|||||||
#define HUFv07_STATIC_LINKING_ONLY /* HUFv07_TABLELOG_ABSOLUTEMAX */
|
#define HUFv07_STATIC_LINKING_ONLY /* HUFv07_TABLELOG_ABSOLUTEMAX */
|
||||||
#define ZSTDv07_STATIC_LINKING_ONLY
|
#define ZSTDv07_STATIC_LINKING_ONLY
|
||||||
|
|
||||||
|
#include "error_private.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef ZSTDv07_STATIC_LINKING_ONLY
|
#ifdef ZSTDv07_STATIC_LINKING_ONLY
|
||||||
|
|
||||||
@@ -90,27 +68,27 @@ typedef struct { ZSTDv07_allocFunction customAlloc; ZSTDv07_freeFunction customF
|
|||||||
|
|
||||||
/*! ZSTDv07_estimateDCtxSize() :
|
/*! ZSTDv07_estimateDCtxSize() :
|
||||||
* Gives the potential amount of memory allocated to create a ZSTDv07_DCtx */
|
* Gives the potential amount of memory allocated to create a ZSTDv07_DCtx */
|
||||||
ZSTDLIB_API size_t ZSTDv07_estimateDCtxSize(void);
|
ZSTDLIBv07_API size_t ZSTDv07_estimateDCtxSize(void);
|
||||||
|
|
||||||
/*! ZSTDv07_createDCtx_advanced() :
|
/*! ZSTDv07_createDCtx_advanced() :
|
||||||
* Create a ZSTD decompression context using external alloc and free functions */
|
* Create a ZSTD decompression context using external alloc and free functions */
|
||||||
ZSTDLIB_API ZSTDv07_DCtx* ZSTDv07_createDCtx_advanced(ZSTDv07_customMem customMem);
|
ZSTDLIBv07_API ZSTDv07_DCtx* ZSTDv07_createDCtx_advanced(ZSTDv07_customMem customMem);
|
||||||
|
|
||||||
/*! ZSTDv07_sizeofDCtx() :
|
/*! ZSTDv07_sizeofDCtx() :
|
||||||
* Gives the amount of memory used by a given ZSTDv07_DCtx */
|
* Gives the amount of memory used by a given ZSTDv07_DCtx */
|
||||||
ZSTDLIB_API size_t ZSTDv07_sizeofDCtx(const ZSTDv07_DCtx* dctx);
|
ZSTDLIBv07_API size_t ZSTDv07_sizeofDCtx(const ZSTDv07_DCtx* dctx);
|
||||||
|
|
||||||
|
|
||||||
/* ******************************************************************
|
/* ******************************************************************
|
||||||
* Buffer-less streaming functions (synchronous mode)
|
* Buffer-less streaming functions (synchronous mode)
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZSTDv07_decompressBegin(ZSTDv07_DCtx* dctx);
|
ZSTDLIBv07_API size_t ZSTDv07_decompressBegin(ZSTDv07_DCtx* dctx);
|
||||||
ZSTDLIB_API size_t ZSTDv07_decompressBegin_usingDict(ZSTDv07_DCtx* dctx, const void* dict, size_t dictSize);
|
ZSTDLIBv07_API size_t ZSTDv07_decompressBegin_usingDict(ZSTDv07_DCtx* dctx, const void* dict, size_t dictSize);
|
||||||
ZSTDLIB_API void ZSTDv07_copyDCtx(ZSTDv07_DCtx* dctx, const ZSTDv07_DCtx* preparedDCtx);
|
ZSTDLIBv07_API void ZSTDv07_copyDCtx(ZSTDv07_DCtx* dctx, const ZSTDv07_DCtx* preparedDCtx);
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZSTDv07_nextSrcSizeToDecompress(ZSTDv07_DCtx* dctx);
|
ZSTDLIBv07_API size_t ZSTDv07_nextSrcSizeToDecompress(ZSTDv07_DCtx* dctx);
|
||||||
ZSTDLIB_API size_t ZSTDv07_decompressContinue(ZSTDv07_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
ZSTDLIBv07_API size_t ZSTDv07_decompressContinue(ZSTDv07_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Buffer-less streaming decompression (synchronous mode)
|
Buffer-less streaming decompression (synchronous mode)
|
||||||
@@ -191,8 +169,8 @@ ZSTDLIB_API size_t ZSTDv07_decompressContinue(ZSTDv07_DCtx* dctx, void* dst, siz
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define ZSTDv07_BLOCKSIZE_ABSOLUTEMAX (128 * 1024) /* define, for static allocation */
|
#define ZSTDv07_BLOCKSIZE_ABSOLUTEMAX (128 * 1024) /* define, for static allocation */
|
||||||
ZSTDLIB_API size_t ZSTDv07_decompressBlock(ZSTDv07_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
ZSTDLIBv07_API size_t ZSTDv07_decompressBlock(ZSTDv07_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
ZSTDLIB_API size_t ZSTDv07_insertBlock(ZSTDv07_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert block into `dctx` history. Useful for uncompressed blocks */
|
ZSTDLIBv07_API size_t ZSTDv07_insertBlock(ZSTDv07_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert block into `dctx` history. Useful for uncompressed blocks */
|
||||||
|
|
||||||
|
|
||||||
#endif /* ZSTDv07_STATIC_LINKING_ONLY */
|
#endif /* ZSTDv07_STATIC_LINKING_ONLY */
|
||||||
@@ -451,203 +429,6 @@ MEM_STATIC size_t MEM_readLEST(const void* memPtr)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* MEM_H_MODULE */
|
#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 {
|
|
||||||
ZSTDv07_error_no_error,
|
|
||||||
ZSTDv07_error_GENERIC,
|
|
||||||
ZSTDv07_error_prefix_unknown,
|
|
||||||
ZSTDv07_error_frameParameter_unsupported,
|
|
||||||
ZSTDv07_error_frameParameter_unsupportedBy32bits,
|
|
||||||
ZSTDv07_error_compressionParameter_unsupported,
|
|
||||||
ZSTDv07_error_init_missing,
|
|
||||||
ZSTDv07_error_memory_allocation,
|
|
||||||
ZSTDv07_error_stage_wrong,
|
|
||||||
ZSTDv07_error_dstSize_tooSmall,
|
|
||||||
ZSTDv07_error_srcSize_wrong,
|
|
||||||
ZSTDv07_error_corruption_detected,
|
|
||||||
ZSTDv07_error_checksum_wrong,
|
|
||||||
ZSTDv07_error_tableLog_tooLarge,
|
|
||||||
ZSTDv07_error_maxSymbolValue_tooLarge,
|
|
||||||
ZSTDv07_error_maxSymbolValue_tooSmall,
|
|
||||||
ZSTDv07_error_dictionary_corrupted,
|
|
||||||
ZSTDv07_error_dictionary_wrong,
|
|
||||||
ZSTDv07_error_maxCode
|
|
||||||
} ZSTDv07_ErrorCode;
|
|
||||||
|
|
||||||
/*! ZSTDv07_getErrorCode() :
|
|
||||||
convert a `size_t` function result into a `ZSTDv07_ErrorCode` enum type,
|
|
||||||
which can be used to compare directly with enum list published into "error_public.h" */
|
|
||||||
ZSTDv07_ErrorCode ZSTDv07_getErrorCode(size_t functionResult);
|
|
||||||
const char* ZSTDv07_getErrorString(ZSTDv07_ErrorCode code);
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ERROR_PUBLIC_H_MODULE */
|
|
||||||
/* ******************************************************************
|
|
||||||
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 ZSTDv07_ErrorCode ERR_enum;
|
|
||||||
#define PREFIX(name) ZSTDv07_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(checksum_wrong): return "Restored data doesn't match checksum";
|
|
||||||
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(dictionary_wrong): return "Dictionary mismatch";
|
|
||||||
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 */
|
|
||||||
/* ******************************************************************
|
/* ******************************************************************
|
||||||
bitstream
|
bitstream
|
||||||
Part of FSE library
|
Part of FSE library
|
||||||
@@ -869,8 +650,8 @@ MEM_STATIC size_t BITv07_readBitsFast(BITv07_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 BITv07_DStream_status BITv07_reloadDStream(BITv07_DStream_t* bitD)
|
MEM_STATIC BITv07_DStream_status BITv07_reloadDStream(BITv07_DStream_t* bitD)
|
||||||
{
|
{
|
||||||
if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should not happen => corruption detected */
|
if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should not happen => corruption detected */
|
||||||
return BITv07_DStream_overflow;
|
return BITv07_DStream_overflow;
|
||||||
|
|
||||||
if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) {
|
if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) {
|
||||||
bitD->ptr -= bitD->bitsConsumed >> 3;
|
bitD->ptr -= bitD->bitsConsumed >> 3;
|
||||||
@@ -1147,7 +928,7 @@ static unsigned char FSEv07_decodeSymbolFast(FSEv07_DState_t* DStatePtr, BITv07_
|
|||||||
/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */
|
/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */
|
||||||
|
|
||||||
|
|
||||||
/*<===== Decompression =====>*/
|
/* ====== Decompression ====== */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
U16 tableLog;
|
U16 tableLog;
|
||||||
@@ -1704,17 +1485,18 @@ size_t HUFv07_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
|
|||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
|
||||||
#else
|
#else
|
||||||
# ifdef __GNUC__
|
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
|
||||||
# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
# ifdef __GNUC__
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
# define FORCE_INLINE static inline __attribute__((always_inline))
|
||||||
|
# else
|
||||||
|
# define FORCE_INLINE static inline
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
# define FORCE_INLINE static inline
|
# define FORCE_INLINE static
|
||||||
# endif
|
# endif /* __STDC_VERSION__ */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* **************************************************************
|
/* **************************************************************
|
||||||
* Error Management
|
* Error Management
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
@@ -2030,14 +1812,7 @@ size_t FSEv07_decompress(void* dst, size_t maxDstSize, const void* cSrc, size_t
|
|||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER /* Visual Studio */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
# define FORCE_INLINE static __forceinline
|
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# 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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -2912,13 +2687,6 @@ unsigned ZSTDv07_isError(size_t code) { return ERR_isError(code); }
|
|||||||
* provides error code string from function result (useful for debugging) */
|
* provides error code string from function result (useful for debugging) */
|
||||||
const char* ZSTDv07_getErrorName(size_t code) { return ERR_getErrorName(code); }
|
const char* ZSTDv07_getErrorName(size_t code) { return ERR_getErrorName(code); }
|
||||||
|
|
||||||
/*! ZSTDv07_getError() :
|
|
||||||
* convert a `size_t` function result into a proper ZSTDv07_errorCode enum */
|
|
||||||
ZSTDv07_ErrorCode ZSTDv07_getErrorCode(size_t code) { return ERR_getErrorCode(code); }
|
|
||||||
|
|
||||||
/*! ZSTDv07_getErrorString() :
|
|
||||||
* provides error code string from enum */
|
|
||||||
const char* ZSTDv07_getErrorString(ZSTDv07_ErrorCode code) { return ERR_getErrorName(code); }
|
|
||||||
|
|
||||||
|
|
||||||
/* **************************************************************
|
/* **************************************************************
|
||||||
@@ -2989,18 +2757,6 @@ void ZSTDv07_defaultFreeFunction(void* opaque, void* address)
|
|||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Common constants
|
* Common constants
|
||||||
***************************************/
|
***************************************/
|
||||||
#define ZSTDv07_OPT_DEBUG 0 /* 3 = compression stats; 5 = check encoded sequences; 9 = full logs */
|
|
||||||
#include <stdio.h>
|
|
||||||
#if defined(ZSTDv07_OPT_DEBUG) && ZSTDv07_OPT_DEBUG>=9
|
|
||||||
#define ZSTDv07_LOG_PARSER(...) printf(__VA_ARGS__)
|
|
||||||
#define ZSTDv07_LOG_ENCODE(...) printf(__VA_ARGS__)
|
|
||||||
#define ZSTDv07_LOG_BLOCK(...) printf(__VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define ZSTDv07_LOG_PARSER(...)
|
|
||||||
#define ZSTDv07_LOG_ENCODE(...)
|
|
||||||
#define ZSTDv07_LOG_BLOCK(...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ZSTDv07_OPT_NUM (1<<12)
|
#define ZSTDv07_OPT_NUM (1<<12)
|
||||||
#define ZSTDv07_DICT_MAGIC 0xEC30A437 /* v0.7 */
|
#define ZSTDv07_DICT_MAGIC 0xEC30A437 /* v0.7 */
|
||||||
|
|
||||||
@@ -3212,17 +2968,10 @@ static const ZSTDv07_customMem defaultCustomMem = { ZSTDv07_defaultAllocFunction
|
|||||||
* Compiler specifics
|
* Compiler specifics
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
#ifdef _MSC_VER /* Visual Studio */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
# define FORCE_INLINE static __forceinline
|
|
||||||
# include <intrin.h> /* For Visual 2005 */
|
# include <intrin.h> /* For Visual 2005 */
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||||
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
|
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
|
||||||
# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */
|
# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */
|
||||||
#else
|
|
||||||
# ifdef __GNUC__
|
|
||||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
|
||||||
# else
|
|
||||||
# define FORCE_INLINE static inline
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -4082,7 +3831,7 @@ size_t ZSTDv07_decompressBlock(ZSTDv07_DCtx* dctx,
|
|||||||
|
|
||||||
/** ZSTDv07_insertBlock() :
|
/** ZSTDv07_insertBlock() :
|
||||||
insert `src` block into `dctx` history. Useful to track uncompressed blocks. */
|
insert `src` block into `dctx` history. Useful to track uncompressed blocks. */
|
||||||
ZSTDLIB_API size_t ZSTDv07_insertBlock(ZSTDv07_DCtx* dctx, const void* blockStart, size_t blockSize)
|
ZSTDLIBv07_API size_t ZSTDv07_insertBlock(ZSTDv07_DCtx* dctx, const void* blockStart, size_t blockSize)
|
||||||
{
|
{
|
||||||
ZSTDv07_checkContinuity(dctx, blockStart);
|
ZSTDv07_checkContinuity(dctx, blockStart);
|
||||||
dctx->previousDstEnd = (const char*)blockStart + blockSize;
|
dctx->previousDstEnd = (const char*)blockStart + blockSize;
|
||||||
@@ -4484,7 +4233,7 @@ size_t ZSTDv07_freeDDict(ZSTDv07_DDict* ddict)
|
|||||||
/*! ZSTDv07_decompress_usingDDict() :
|
/*! ZSTDv07_decompress_usingDDict() :
|
||||||
* Decompression using a pre-digested Dictionary
|
* Decompression using a pre-digested Dictionary
|
||||||
* Use dictionary without significant overhead. */
|
* Use dictionary without significant overhead. */
|
||||||
ZSTDLIB_API size_t ZSTDv07_decompress_usingDDict(ZSTDv07_DCtx* dctx,
|
ZSTDLIBv07_API size_t ZSTDv07_decompress_usingDDict(ZSTDv07_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 ZSTDv07_DDict* ddict)
|
const ZSTDv07_DDict* ddict)
|
||||||
@@ -4571,7 +4320,7 @@ struct ZBUFFv07_DCtx_s {
|
|||||||
ZSTDv07_customMem customMem;
|
ZSTDv07_customMem customMem;
|
||||||
}; /* typedef'd to ZBUFFv07_DCtx within "zstd_buffered.h" */
|
}; /* typedef'd to ZBUFFv07_DCtx within "zstd_buffered.h" */
|
||||||
|
|
||||||
ZSTDLIB_API ZBUFFv07_DCtx* ZBUFFv07_createDCtx_advanced(ZSTDv07_customMem customMem);
|
ZSTDLIBv07_API ZBUFFv07_DCtx* ZBUFFv07_createDCtx_advanced(ZSTDv07_customMem customMem);
|
||||||
|
|
||||||
ZBUFFv07_DCtx* ZBUFFv07_createDCtx(void)
|
ZBUFFv07_DCtx* ZBUFFv07_createDCtx(void)
|
||||||
{
|
{
|
||||||
@@ -4655,9 +4404,9 @@ size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* zbd,
|
|||||||
|
|
||||||
case ZBUFFds_loadHeader :
|
case ZBUFFds_loadHeader :
|
||||||
{ size_t const hSize = ZSTDv07_getFrameParams(&(zbd->fParams), zbd->headerBuffer, zbd->lhSize);
|
{ size_t const hSize = ZSTDv07_getFrameParams(&(zbd->fParams), zbd->headerBuffer, zbd->lhSize);
|
||||||
|
if (ZSTDv07_isError(hSize)) return hSize;
|
||||||
if (hSize != 0) {
|
if (hSize != 0) {
|
||||||
size_t const toLoad = hSize - zbd->lhSize; /* if hSize!=0, hSize > zbd->lhSize */
|
size_t const toLoad = hSize - zbd->lhSize; /* if hSize!=0, hSize > zbd->lhSize */
|
||||||
if (ZSTDv07_isError(hSize)) return hSize;
|
|
||||||
if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */
|
if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */
|
||||||
memcpy(zbd->headerBuffer + zbd->lhSize, ip, iend-ip);
|
memcpy(zbd->headerBuffer + zbd->lhSize, ip, iend-ip);
|
||||||
zbd->lhSize += iend-ip;
|
zbd->lhSize += iend-ip;
|
||||||
@@ -4697,6 +4446,7 @@ size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* zbd,
|
|||||||
if (zbd->outBuff == NULL) return ERROR(memory_allocation);
|
if (zbd->outBuff == NULL) return ERROR(memory_allocation);
|
||||||
} } }
|
} } }
|
||||||
zbd->stage = ZBUFFds_read;
|
zbd->stage = ZBUFFds_read;
|
||||||
|
/* pass-through */
|
||||||
|
|
||||||
case ZBUFFds_read:
|
case ZBUFFds_read:
|
||||||
{ size_t const neededInSize = ZSTDv07_nextSrcSizeToDecompress(zbd->zd);
|
{ size_t const neededInSize = ZSTDv07_nextSrcSizeToDecompress(zbd->zd);
|
||||||
|
|||||||
+37
-60
@@ -1,34 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
zstd_v07 - decoder for 0.7 format
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Header File
|
* All rights reserved.
|
||||||
Copyright (C) 2014-2016, Yann Collet.
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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 ZSTDv07_H_235446
|
#ifndef ZSTDv07_H_235446
|
||||||
#define ZSTDv07_H_235446
|
#define ZSTDv07_H_235446
|
||||||
|
|
||||||
@@ -46,13 +24,12 @@ extern "C" {
|
|||||||
* Enable exporting of functions when building a Windows DLL
|
* Enable exporting of functions when building a Windows DLL
|
||||||
*/
|
*/
|
||||||
#if defined(_WIN32) && defined(ZSTDv07_DLL_EXPORT) && (ZSTDv07_DLL_EXPORT==1)
|
#if defined(_WIN32) && defined(ZSTDv07_DLL_EXPORT) && (ZSTDv07_DLL_EXPORT==1)
|
||||||
# define ZSTDLIB_API __declspec(dllexport)
|
# define ZSTDLIBv07_API __declspec(dllexport)
|
||||||
#else
|
#else
|
||||||
# define ZSTDLIB_API
|
# define ZSTDLIBv07_API
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Simple API
|
* Simple API
|
||||||
***************************************/
|
***************************************/
|
||||||
@@ -68,12 +45,12 @@ unsigned long long ZSTDv07_getDecompressedSize(const void* src, size_t srcSize);
|
|||||||
`dstCapacity` must be equal or larger than originalSize.
|
`dstCapacity` must be equal or larger than originalSize.
|
||||||
@return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
|
@return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
|
||||||
or an errorCode if it fails (which can be tested using ZSTDv07_isError()) */
|
or an errorCode if it fails (which can be tested using ZSTDv07_isError()) */
|
||||||
ZSTDLIB_API size_t ZSTDv07_decompress( void* dst, size_t dstCapacity,
|
ZSTDLIBv07_API size_t ZSTDv07_decompress( void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t compressedSize);
|
const void* src, size_t compressedSize);
|
||||||
|
|
||||||
/*====== Helper functions ======*/
|
/*====== Helper functions ======*/
|
||||||
ZSTDLIB_API unsigned ZSTDv07_isError(size_t code); /*!< tells if a `size_t` function result is an error code */
|
ZSTDLIBv07_API unsigned ZSTDv07_isError(size_t code); /*!< tells if a `size_t` function result is an error code */
|
||||||
ZSTDLIB_API const char* ZSTDv07_getErrorName(size_t code); /*!< provides readable string from an error code */
|
ZSTDLIBv07_API const char* ZSTDv07_getErrorName(size_t code); /*!< provides readable string from an error code */
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
@@ -81,12 +58,12 @@ ZSTDLIB_API const char* ZSTDv07_getErrorName(size_t code); /*!< provides rea
|
|||||||
***************************************/
|
***************************************/
|
||||||
/** Decompression context */
|
/** Decompression context */
|
||||||
typedef struct ZSTDv07_DCtx_s ZSTDv07_DCtx;
|
typedef struct ZSTDv07_DCtx_s ZSTDv07_DCtx;
|
||||||
ZSTDLIB_API ZSTDv07_DCtx* ZSTDv07_createDCtx(void);
|
ZSTDLIBv07_API ZSTDv07_DCtx* ZSTDv07_createDCtx(void);
|
||||||
ZSTDLIB_API size_t ZSTDv07_freeDCtx(ZSTDv07_DCtx* dctx); /*!< @return : errorCode */
|
ZSTDLIBv07_API size_t ZSTDv07_freeDCtx(ZSTDv07_DCtx* dctx); /*!< @return : errorCode */
|
||||||
|
|
||||||
/** ZSTDv07_decompressDCtx() :
|
/** ZSTDv07_decompressDCtx() :
|
||||||
* Same as ZSTDv07_decompress(), requires an allocated ZSTDv07_DCtx (see ZSTDv07_createDCtx()) */
|
* Same as ZSTDv07_decompress(), requires an allocated ZSTDv07_DCtx (see ZSTDv07_createDCtx()) */
|
||||||
ZSTDLIB_API size_t ZSTDv07_decompressDCtx(ZSTDv07_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
ZSTDLIBv07_API size_t ZSTDv07_decompressDCtx(ZSTDv07_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
|
||||||
/*-************************
|
/*-************************
|
||||||
@@ -96,10 +73,10 @@ ZSTDLIB_API size_t ZSTDv07_decompressDCtx(ZSTDv07_DCtx* ctx, void* dst, size_t d
|
|||||||
* 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.
|
* Dictionary must be identical to the one used during compression.
|
||||||
* Note : This function load the dictionary, resulting in a significant startup time */
|
* Note : This function load the dictionary, resulting in a significant startup time */
|
||||||
ZSTDLIB_API size_t ZSTDv07_decompress_usingDict(ZSTDv07_DCtx* dctx,
|
ZSTDLIBv07_API size_t ZSTDv07_decompress_usingDict(ZSTDv07_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);
|
||||||
|
|
||||||
|
|
||||||
/*-**************************
|
/*-**************************
|
||||||
@@ -109,16 +86,16 @@ ZSTDLIB_API size_t ZSTDv07_decompress_usingDict(ZSTDv07_DCtx* dctx,
|
|||||||
* Create a digested dictionary, ready to start decompression operation without startup delay.
|
* Create a digested dictionary, ready to start decompression operation without startup delay.
|
||||||
* `dict` can be released after creation */
|
* `dict` can be released after creation */
|
||||||
typedef struct ZSTDv07_DDict_s ZSTDv07_DDict;
|
typedef struct ZSTDv07_DDict_s ZSTDv07_DDict;
|
||||||
ZSTDLIB_API ZSTDv07_DDict* ZSTDv07_createDDict(const void* dict, size_t dictSize);
|
ZSTDLIBv07_API ZSTDv07_DDict* ZSTDv07_createDDict(const void* dict, size_t dictSize);
|
||||||
ZSTDLIB_API size_t ZSTDv07_freeDDict(ZSTDv07_DDict* ddict);
|
ZSTDLIBv07_API size_t ZSTDv07_freeDDict(ZSTDv07_DDict* ddict);
|
||||||
|
|
||||||
/*! ZSTDv07_decompress_usingDDict() :
|
/*! ZSTDv07_decompress_usingDDict() :
|
||||||
* Decompression using a pre-digested Dictionary
|
* Decompression using a pre-digested Dictionary
|
||||||
* Faster startup than ZSTDv07_decompress_usingDict(), recommended when same dictionary is used multiple times. */
|
* Faster startup than ZSTDv07_decompress_usingDict(), recommended when same dictionary is used multiple times. */
|
||||||
ZSTDLIB_API size_t ZSTDv07_decompress_usingDDict(ZSTDv07_DCtx* dctx,
|
ZSTDLIBv07_API size_t ZSTDv07_decompress_usingDDict(ZSTDv07_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 ZSTDv07_DDict* ddict);
|
const ZSTDv07_DDict* ddict);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned long long frameContentSize;
|
unsigned long long frameContentSize;
|
||||||
@@ -127,7 +104,7 @@ typedef struct {
|
|||||||
unsigned checksumFlag;
|
unsigned checksumFlag;
|
||||||
} ZSTDv07_frameParams;
|
} ZSTDv07_frameParams;
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZSTDv07_getFrameParams(ZSTDv07_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input */
|
ZSTDLIBv07_API size_t ZSTDv07_getFrameParams(ZSTDv07_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -136,13 +113,13 @@ ZSTDLIB_API size_t ZSTDv07_getFrameParams(ZSTDv07_frameParams* fparamsPtr, const
|
|||||||
* Streaming functions
|
* Streaming functions
|
||||||
***************************************/
|
***************************************/
|
||||||
typedef struct ZBUFFv07_DCtx_s ZBUFFv07_DCtx;
|
typedef struct ZBUFFv07_DCtx_s ZBUFFv07_DCtx;
|
||||||
ZSTDLIB_API ZBUFFv07_DCtx* ZBUFFv07_createDCtx(void);
|
ZSTDLIBv07_API ZBUFFv07_DCtx* ZBUFFv07_createDCtx(void);
|
||||||
ZSTDLIB_API size_t ZBUFFv07_freeDCtx(ZBUFFv07_DCtx* dctx);
|
ZSTDLIBv07_API size_t ZBUFFv07_freeDCtx(ZBUFFv07_DCtx* dctx);
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZBUFFv07_decompressInit(ZBUFFv07_DCtx* dctx);
|
ZSTDLIBv07_API size_t ZBUFFv07_decompressInit(ZBUFFv07_DCtx* dctx);
|
||||||
ZSTDLIB_API size_t ZBUFFv07_decompressInitDictionary(ZBUFFv07_DCtx* dctx, const void* dict, size_t dictSize);
|
ZSTDLIBv07_API size_t ZBUFFv07_decompressInitDictionary(ZBUFFv07_DCtx* dctx, const void* dict, size_t dictSize);
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* dctx,
|
ZSTDLIBv07_API size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* dctx,
|
||||||
void* dst, size_t* dstCapacityPtr,
|
void* dst, size_t* dstCapacityPtr,
|
||||||
const void* src, size_t* srcSizePtr);
|
const void* src, size_t* srcSizePtr);
|
||||||
|
|
||||||
@@ -174,13 +151,13 @@ ZSTDLIB_API size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* dctx,
|
|||||||
/* *************************************
|
/* *************************************
|
||||||
* Tool functions
|
* Tool functions
|
||||||
***************************************/
|
***************************************/
|
||||||
ZSTDLIB_API unsigned ZBUFFv07_isError(size_t errorCode);
|
ZSTDLIBv07_API unsigned ZBUFFv07_isError(size_t errorCode);
|
||||||
ZSTDLIB_API const char* ZBUFFv07_getErrorName(size_t errorCode);
|
ZSTDLIBv07_API const char* ZBUFFv07_getErrorName(size_t errorCode);
|
||||||
|
|
||||||
/** Functions below provide recommended buffer sizes for Compression or Decompression operations.
|
/** Functions below provide recommended buffer sizes for Compression or Decompression operations.
|
||||||
* These sizes are just hints, they tend to offer better latency */
|
* These sizes are just hints, they tend to offer better latency */
|
||||||
ZSTDLIB_API size_t ZBUFFv07_recommendedDInSize(void);
|
ZSTDLIBv07_API size_t ZBUFFv07_recommendedDInSize(void);
|
||||||
ZSTDLIB_API size_t ZBUFFv07_recommendedDOutSize(void);
|
ZSTDLIBv07_API size_t ZBUFFv07_recommendedDOutSize(void);
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ includedir=@INCLUDEDIR@
|
|||||||
|
|
||||||
Name: zstd
|
Name: zstd
|
||||||
Description: lossless compression algorithm library
|
Description: lossless compression algorithm library
|
||||||
URL: https://github.com/Cyan4973/zstd
|
URL: https://github.com/facebook/zstd
|
||||||
Version: @VERSION@
|
Version: @VERSION@
|
||||||
Libs: -L@LIBDIR@ -lzstd
|
Libs: -L@LIBDIR@ -lzstd
|
||||||
Cflags: -I@INCLUDEDIR@
|
Cflags: -I@INCLUDEDIR@
|
||||||
|
|||||||
+177
-171
@@ -1,34 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
zstd - standard compression library
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Header File
|
* All rights reserved.
|
||||||
Copyright (C) 2014-2016, Yann Collet.
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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 ZSTD_H_235446
|
#ifndef ZSTD_H_235446
|
||||||
#define ZSTD_H_235446
|
#define ZSTD_H_235446
|
||||||
|
|
||||||
@@ -53,9 +31,9 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
/*======= Version =======*/
|
/*======= Version =======*/
|
||||||
#define ZSTD_VERSION_MAJOR 0
|
#define ZSTD_VERSION_MAJOR 1
|
||||||
#define ZSTD_VERSION_MINOR 8
|
#define ZSTD_VERSION_MINOR 1
|
||||||
#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
|
||||||
@@ -70,40 +48,41 @@ ZSTDLIB_API unsigned ZSTD_versionNumber (void);
|
|||||||
* Simple API
|
* Simple API
|
||||||
***************************************/
|
***************************************/
|
||||||
/*! ZSTD_compress() :
|
/*! ZSTD_compress() :
|
||||||
Compresses `src` buffer into already allocated `dst`.
|
Compresses `src` content as a single zstd compressed frame into already allocated `dst`.
|
||||||
Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`.
|
Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`.
|
||||||
@return : the number of bytes written into `dst` (<= `dstCapacity),
|
@return : compressed size written into `dst` (<= `dstCapacity),
|
||||||
or an error code if it fails (which can be tested using ZSTD_isError()) */
|
or an error code if it fails (which can be tested using ZSTD_isError()) */
|
||||||
ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity,
|
ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
int compressionLevel);
|
int compressionLevel);
|
||||||
|
|
||||||
/*! ZSTD_getDecompressedSize() :
|
|
||||||
* @return : decompressed size as a 64-bits value _if known_, 0 otherwise.
|
|
||||||
* note 1 : decompressed size can be very large (64-bits value),
|
|
||||||
* potentially larger than what local system can handle as a single memory segment.
|
|
||||||
* In which case, it's necessary to use streaming mode to decompress data.
|
|
||||||
* note 2 : decompressed size is an optional field, that may not be present.
|
|
||||||
* When `return==0`, data to decompress can have any size.
|
|
||||||
* In which case, it's necessary to use streaming mode to decompress data.
|
|
||||||
* Optionally, application may rely on its own implied limits.
|
|
||||||
* (For example, application own data could be necessarily cut into blocks <= 16 KB).
|
|
||||||
* note 3 : decompressed size could be wrong or intentionally modified !
|
|
||||||
* Always ensure result fits within application's authorized limits !
|
|
||||||
* Each application can set its own limits.
|
|
||||||
* note 4 : when `return==0`, if precise failure cause is needed, use ZSTD_getFrameParams() to know more. */
|
|
||||||
ZSTDLIB_API unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
|
|
||||||
|
|
||||||
/*! ZSTD_decompress() :
|
/*! ZSTD_decompress() :
|
||||||
`compressedSize` : must be the _exact_ size of compressed input, otherwise decompression will fail.
|
`compressedSize` : must be the _exact_ size of a single compressed frame.
|
||||||
`dstCapacity` must be equal or larger than originalSize (see ZSTD_getDecompressedSize() ).
|
`dstCapacity` is an upper bound of originalSize.
|
||||||
If originalSize is unknown, and if there is no implied application-specific limitations,
|
If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data.
|
||||||
it's preferable to use streaming mode to decompress data.
|
|
||||||
@return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
|
@return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
|
||||||
or an errorCode if it fails (which can be tested using ZSTD_isError()) */
|
or an errorCode if it fails (which can be tested using ZSTD_isError()) */
|
||||||
ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity,
|
ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t compressedSize);
|
const void* src, size_t compressedSize);
|
||||||
|
|
||||||
|
/*! ZSTD_getDecompressedSize() :
|
||||||
|
* 'src' is the start of a zstd compressed frame.
|
||||||
|
* @return : content size to be decompressed, as a 64-bits value _if known_, 0 otherwise.
|
||||||
|
* note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode.
|
||||||
|
* When `return==0`, data to decompress could be any size.
|
||||||
|
* In which case, it's necessary to use streaming mode to decompress data.
|
||||||
|
* Optionally, application can still use ZSTD_decompress() while relying on implied limits.
|
||||||
|
* (For example, data may be necessarily cut into blocks <= 16 KB).
|
||||||
|
* note 2 : decompressed size is always present when compression is done with ZSTD_compress()
|
||||||
|
* note 3 : decompressed size can be very large (64-bits value),
|
||||||
|
* potentially larger than what local system can handle as a single memory segment.
|
||||||
|
* In which case, it's necessary to use streaming mode to decompress data.
|
||||||
|
* note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified.
|
||||||
|
* Always ensure result fits within application's authorized limits.
|
||||||
|
* Each application can set its own limits.
|
||||||
|
* note 5 : when `return==0`, if precise failure cause is needed, use ZSTD_getFrameParams() to know more. */
|
||||||
|
ZSTDLIB_API unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
|
||||||
/*====== Helper functions ======*/
|
/*====== Helper functions ======*/
|
||||||
ZSTDLIB_API int ZSTD_maxCLevel(void); /*!< maximum compression level available */
|
ZSTDLIB_API int ZSTD_maxCLevel(void); /*!< maximum compression level available */
|
||||||
@@ -116,7 +95,7 @@ ZSTDLIB_API const char* ZSTD_getErrorName(size_t code); /*!< provides readab
|
|||||||
* Explicit memory management
|
* Explicit memory management
|
||||||
***************************************/
|
***************************************/
|
||||||
/** Compression context */
|
/** Compression context */
|
||||||
typedef struct ZSTD_CCtx_s ZSTD_CCtx; /*< incomplete type */
|
typedef struct ZSTD_CCtx_s ZSTD_CCtx;
|
||||||
ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void);
|
ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void);
|
||||||
ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx);
|
ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx);
|
||||||
|
|
||||||
@@ -125,7 +104,7 @@ ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx);
|
|||||||
ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel);
|
ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel);
|
||||||
|
|
||||||
/** Decompression context */
|
/** Decompression context */
|
||||||
typedef struct ZSTD_DCtx_s ZSTD_DCtx; /*< incomplete type */
|
typedef struct ZSTD_DCtx_s ZSTD_DCtx;
|
||||||
ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void);
|
ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void);
|
||||||
ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);
|
ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);
|
||||||
|
|
||||||
@@ -191,6 +170,110 @@ ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
|
|||||||
const ZSTD_DDict* ddict);
|
const ZSTD_DDict* ddict);
|
||||||
|
|
||||||
|
|
||||||
|
/*-**************************
|
||||||
|
* Streaming
|
||||||
|
****************************/
|
||||||
|
|
||||||
|
typedef struct ZSTD_inBuffer_s {
|
||||||
|
const void* src; /**< start of input buffer */
|
||||||
|
size_t size; /**< size of input buffer */
|
||||||
|
size_t pos; /**< position where reading stopped. Will be updated. Necessarily 0 <= pos <= size */
|
||||||
|
} ZSTD_inBuffer;
|
||||||
|
|
||||||
|
typedef struct ZSTD_outBuffer_s {
|
||||||
|
void* dst; /**< start of output buffer */
|
||||||
|
size_t size; /**< size of output buffer */
|
||||||
|
size_t pos; /**< position where writing stopped. Will be updated. Necessarily 0 <= pos <= size */
|
||||||
|
} ZSTD_outBuffer;
|
||||||
|
|
||||||
|
|
||||||
|
/*====== streaming compression ======*/
|
||||||
|
|
||||||
|
/*-***********************************************************************
|
||||||
|
* Streaming compression - howto
|
||||||
|
*
|
||||||
|
* A ZSTD_CStream object is required to track streaming operation.
|
||||||
|
* Use ZSTD_createCStream() and ZSTD_freeCStream() to create/release resources.
|
||||||
|
* ZSTD_CStream objects can be reused multiple times on consecutive compression operations.
|
||||||
|
*
|
||||||
|
* Start by initializing ZSTD_CStream.
|
||||||
|
* Use ZSTD_initCStream() to start a new compression operation.
|
||||||
|
* Use ZSTD_initCStream_usingDict() for a compression which requires a dictionary.
|
||||||
|
*
|
||||||
|
* Use ZSTD_compressStream() repetitively to consume input stream.
|
||||||
|
* The function will automatically update both `pos` fields.
|
||||||
|
* Note that it may not consume the entire input, in which case `pos < size`,
|
||||||
|
* and it's up to the caller to present again remaining data.
|
||||||
|
* @return : a size hint, preferred nb of bytes to use as input for next function call
|
||||||
|
* (it's just a hint, to help latency a little, any other value will work fine)
|
||||||
|
* (note : the size hint is guaranteed to be <= ZSTD_CStreamInSize() )
|
||||||
|
* or an error code, which can be tested using ZSTD_isError().
|
||||||
|
*
|
||||||
|
* At any moment, it's possible to flush whatever data remains within buffer, using ZSTD_flushStream().
|
||||||
|
* `output->pos` will be updated.
|
||||||
|
* Note some content might still be left within internal buffer if `output->size` is too small.
|
||||||
|
* @return : nb of bytes still present within internal buffer (0 if it's empty)
|
||||||
|
* or an error code, which can be tested using ZSTD_isError().
|
||||||
|
*
|
||||||
|
* ZSTD_endStream() instructs to finish a frame.
|
||||||
|
* It will perform a flush and write frame epilogue.
|
||||||
|
* The epilogue is required for decoders to consider a frame completed.
|
||||||
|
* Similar to ZSTD_flushStream(), it may not be able to flush the full content if `output->size` is too small.
|
||||||
|
* In which case, call again ZSTD_endStream() to complete the flush.
|
||||||
|
* @return : nb of bytes still present within internal buffer (0 if it's empty)
|
||||||
|
* or an error code, which can be tested using ZSTD_isError().
|
||||||
|
*
|
||||||
|
* *******************************************************************/
|
||||||
|
|
||||||
|
typedef struct ZSTD_CStream_s ZSTD_CStream;
|
||||||
|
ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream(void);
|
||||||
|
ZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream* zcs);
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZSTD_CStreamInSize(void); /**< recommended size for input buffer */
|
||||||
|
ZSTDLIB_API size_t ZSTD_CStreamOutSize(void); /**< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block in all circumstances. */
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel);
|
||||||
|
ZSTDLIB_API size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
|
||||||
|
ZSTDLIB_API size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
|
||||||
|
ZSTDLIB_API size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
|
||||||
|
|
||||||
|
|
||||||
|
/*====== decompression ======*/
|
||||||
|
|
||||||
|
/*-***************************************************************************
|
||||||
|
* Streaming decompression howto
|
||||||
|
*
|
||||||
|
* A ZSTD_DStream object is required to track streaming operations.
|
||||||
|
* Use ZSTD_createDStream() and ZSTD_freeDStream() to create/release resources.
|
||||||
|
* ZSTD_DStream objects can be re-used multiple times.
|
||||||
|
*
|
||||||
|
* Use ZSTD_initDStream() to start a new decompression operation,
|
||||||
|
* or ZSTD_initDStream_usingDict() if decompression requires a dictionary.
|
||||||
|
* @return : recommended first input size
|
||||||
|
*
|
||||||
|
* Use ZSTD_decompressStream() repetitively to consume your input.
|
||||||
|
* The function will update both `pos` fields.
|
||||||
|
* If `input.pos < input.size`, some input has not been consumed.
|
||||||
|
* It's up to the caller to present again remaining data.
|
||||||
|
* If `output.pos < output.size`, decoder has flushed everything it could.
|
||||||
|
* @return : 0 when a frame is completely decoded and fully flushed,
|
||||||
|
* an error code, which can be tested using ZSTD_isError(),
|
||||||
|
* any other value > 0, which means there is still some work to do to complete the frame.
|
||||||
|
* The return value is a suggested next input size (just an hint, to help latency).
|
||||||
|
* *******************************************************************************/
|
||||||
|
|
||||||
|
typedef struct ZSTD_DStream_s ZSTD_DStream;
|
||||||
|
ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream(void);
|
||||||
|
ZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream* zds);
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZSTD_DStreamInSize(void); /*!< recommended size for input buffer */
|
||||||
|
ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */
|
||||||
|
|
||||||
|
ZSTDLIB_API size_t ZSTD_initDStream(ZSTD_DStream* zds);
|
||||||
|
ZSTDLIB_API size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef ZSTD_STATIC_LINKING_ONLY
|
#ifdef ZSTD_STATIC_LINKING_ONLY
|
||||||
|
|
||||||
/* ====================================================================================
|
/* ====================================================================================
|
||||||
@@ -207,27 +290,28 @@ ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
|
|||||||
#define ZSTD_WINDOWLOG_MAX_32 25
|
#define ZSTD_WINDOWLOG_MAX_32 25
|
||||||
#define ZSTD_WINDOWLOG_MAX_64 27
|
#define ZSTD_WINDOWLOG_MAX_64 27
|
||||||
#define ZSTD_WINDOWLOG_MAX ((U32)(MEM_32bits() ? ZSTD_WINDOWLOG_MAX_32 : ZSTD_WINDOWLOG_MAX_64))
|
#define ZSTD_WINDOWLOG_MAX ((U32)(MEM_32bits() ? ZSTD_WINDOWLOG_MAX_32 : ZSTD_WINDOWLOG_MAX_64))
|
||||||
#define ZSTD_WINDOWLOG_MIN 18
|
#define ZSTD_WINDOWLOG_MIN 10
|
||||||
#define ZSTD_CHAINLOG_MAX (ZSTD_WINDOWLOG_MAX+1)
|
|
||||||
#define ZSTD_CHAINLOG_MIN 4
|
|
||||||
#define ZSTD_HASHLOG_MAX ZSTD_WINDOWLOG_MAX
|
#define ZSTD_HASHLOG_MAX ZSTD_WINDOWLOG_MAX
|
||||||
#define ZSTD_HASHLOG_MIN 12
|
#define ZSTD_HASHLOG_MIN 6
|
||||||
|
#define ZSTD_CHAINLOG_MAX (ZSTD_WINDOWLOG_MAX+1)
|
||||||
|
#define ZSTD_CHAINLOG_MIN ZSTD_HASHLOG_MIN
|
||||||
#define ZSTD_HASHLOG3_MAX 17
|
#define ZSTD_HASHLOG3_MAX 17
|
||||||
#define ZSTD_SEARCHLOG_MAX (ZSTD_WINDOWLOG_MAX-1)
|
#define ZSTD_SEARCHLOG_MAX (ZSTD_WINDOWLOG_MAX-1)
|
||||||
#define ZSTD_SEARCHLOG_MIN 1
|
#define ZSTD_SEARCHLOG_MIN 1
|
||||||
#define ZSTD_SEARCHLENGTH_MAX 7
|
#define ZSTD_SEARCHLENGTH_MAX 7 /* only for ZSTD_fast, other strategies are limited to 6 */
|
||||||
#define ZSTD_SEARCHLENGTH_MIN 3
|
#define ZSTD_SEARCHLENGTH_MIN 3 /* only for ZSTD_btopt, other strategies are limited to 4 */
|
||||||
#define ZSTD_TARGETLENGTH_MIN 4
|
#define ZSTD_TARGETLENGTH_MIN 4
|
||||||
#define ZSTD_TARGETLENGTH_MAX 999
|
#define ZSTD_TARGETLENGTH_MAX 999
|
||||||
|
|
||||||
#define ZSTD_FRAMEHEADERSIZE_MAX 18 /* for static allocation */
|
#define ZSTD_FRAMEHEADERSIZE_MAX 18 /* for static allocation */
|
||||||
static const size_t ZSTD_frameHeaderSize_min = 5;
|
static const size_t ZSTD_frameHeaderSize_prefix = 5;
|
||||||
|
static const size_t ZSTD_frameHeaderSize_min = 6;
|
||||||
static const size_t ZSTD_frameHeaderSize_max = ZSTD_FRAMEHEADERSIZE_MAX;
|
static const size_t ZSTD_frameHeaderSize_max = ZSTD_FRAMEHEADERSIZE_MAX;
|
||||||
static const size_t ZSTD_skippableHeaderSize = 8; /* magic number + skippable frame length */
|
static const size_t ZSTD_skippableHeaderSize = 8; /* magic number + skippable frame length */
|
||||||
|
|
||||||
|
|
||||||
/*--- Types ---*/
|
/*--- Types ---*/
|
||||||
typedef enum { ZSTD_fast, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt } ZSTD_strategy; /*< from faster to stronger */
|
typedef enum { ZSTD_fast, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt } ZSTD_strategy; /* from faster to stronger */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned windowLog; /**< largest match distance : larger == more compression, more memory needed during decompression */
|
unsigned windowLog; /**< largest match distance : larger == more compression, more memory needed during decompression */
|
||||||
@@ -268,19 +352,23 @@ ZSTDLIB_API size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
|
|||||||
* Create a ZSTD compression context using external alloc and free functions */
|
* Create a ZSTD compression context using external alloc and free functions */
|
||||||
ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
|
ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
|
||||||
|
|
||||||
|
/*! ZSTD_sizeofCCtx() :
|
||||||
|
* Gives the amount of memory used by a given ZSTD_CCtx */
|
||||||
|
ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
|
||||||
|
|
||||||
/*! ZSTD_createCDict_advanced() :
|
/*! ZSTD_createCDict_advanced() :
|
||||||
* Create a ZSTD_CDict using external alloc and free, and customized compression parameters */
|
* 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,
|
ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize,
|
||||||
ZSTD_parameters params, ZSTD_customMem customMem);
|
ZSTD_parameters params, ZSTD_customMem customMem);
|
||||||
|
|
||||||
/*! ZSTD_sizeofCCtx() :
|
/*! ZSTD_sizeof_CDict() :
|
||||||
* Gives the amount of memory used by a given ZSTD_CCtx */
|
* Gives the amount of memory used by a given ZSTD_sizeof_CDict */
|
||||||
ZSTDLIB_API size_t ZSTD_sizeofCCtx(const ZSTD_CCtx* cctx);
|
ZSTDLIB_API size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict);
|
||||||
|
|
||||||
/*! ZSTD_getParams() :
|
/*! ZSTD_getParams() :
|
||||||
* same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of a `ZSTD_compressionParameters`.
|
* same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of a `ZSTD_compressionParameters`.
|
||||||
* All fields of `ZSTD_frameParameters` are set to default (0) */
|
* All fields of `ZSTD_frameParameters` are set to default (0) */
|
||||||
ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSize, size_t dictSize);
|
ZSTDLIB_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSize, size_t dictSize);
|
||||||
|
|
||||||
/*! ZSTD_getCParams() :
|
/*! ZSTD_getCParams() :
|
||||||
* @return ZSTD_compressionParameters structure for a selected compression level and srcSize.
|
* @return ZSTD_compressionParameters structure for a selected compression level and srcSize.
|
||||||
@@ -315,120 +403,38 @@ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
|
|||||||
* Create a ZSTD decompression context using external alloc and free functions */
|
* Create a ZSTD decompression context using external alloc and free functions */
|
||||||
ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem);
|
ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem);
|
||||||
|
|
||||||
/*! ZSTD_sizeofDCtx() :
|
/*! ZSTD_sizeof_DCtx() :
|
||||||
* Gives the amount of memory used by a given ZSTD_DCtx */
|
* Gives the amount of memory used by a given ZSTD_DCtx */
|
||||||
ZSTDLIB_API size_t ZSTD_sizeofDCtx(const ZSTD_DCtx* dctx);
|
ZSTDLIB_API size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx);
|
||||||
|
|
||||||
|
/*! ZSTD_sizeof_DDict() :
|
||||||
|
* Gives the amount of memory used by a given ZSTD_DDict */
|
||||||
|
ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
|
||||||
|
|
||||||
|
|
||||||
/* ******************************************************************
|
/* ******************************************************************
|
||||||
* Streaming
|
* Advanced Streaming functions
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
typedef struct ZSTD_inBuffer_s {
|
|
||||||
const void* src; /**< start of input buffer */
|
|
||||||
size_t size; /**< size of input buffer */
|
|
||||||
size_t pos; /**< position where reading stopped. Will be updated. Necessarily 0 <= pos <= size */
|
|
||||||
} ZSTD_inBuffer;
|
|
||||||
|
|
||||||
typedef struct ZSTD_outBuffer_s {
|
|
||||||
void* dst; /**< start of output buffer */
|
|
||||||
size_t size; /**< size of output buffer */
|
|
||||||
size_t pos; /**< position where writing stopped. Will be updated. Necessarily 0 <= pos <= size */
|
|
||||||
} ZSTD_outBuffer;
|
|
||||||
|
|
||||||
|
|
||||||
/*====== compression ======*/
|
/*====== compression ======*/
|
||||||
|
|
||||||
/*-***********************************************************************
|
ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
|
||||||
* Streaming compression - howto
|
ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel);
|
||||||
*
|
ZSTDLIB_API size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
|
||||||
* A ZSTD_CStream object is required to track streaming operation.
|
ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize is optional and can be zero == unknown */
|
||||||
* Use ZSTD_createCStream() and ZSTD_freeCStream() to create/release resources.
|
ZSTDLIB_API size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize); /**< re-use compression parameters from previous init; saves dictionary loading */
|
||||||
* ZSTD_CStream objects can be reused multiple times on consecutive compression operations.
|
ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);
|
||||||
*
|
|
||||||
* Start by initializing ZSTD_CStream.
|
|
||||||
* Use ZSTD_initCStream() to start a new compression operation.
|
|
||||||
* Use ZSTD_initCStream_usingDict() for a compression which requires a dictionary.
|
|
||||||
*
|
|
||||||
* Use ZSTD_compressStream() repetitively to consume input stream.
|
|
||||||
* The function will automatically update both `pos`.
|
|
||||||
* Note that it may not consume the entire input, in which case `pos < size`,
|
|
||||||
* and it's up to the caller to present again remaining data.
|
|
||||||
* @return : a hint to preferred nb of bytes to use as input for next function call (it's just a hint, to improve latency)
|
|
||||||
* or an error code, which can be tested using ZSTD_isError().
|
|
||||||
*
|
|
||||||
* At any moment, it's possible to flush whatever data remains within buffer, using ZSTD_flushStream().
|
|
||||||
* `output->pos` will be updated.
|
|
||||||
* Note some content might still be left within internal buffer if `output->size` is too small.
|
|
||||||
* @return : nb of bytes still present within internal buffer (0 if it's empty)
|
|
||||||
* or an error code, which can be tested using ZSTD_isError().
|
|
||||||
*
|
|
||||||
* ZSTD_endStream() instructs to finish a frame.
|
|
||||||
* It will perform a flush and write frame epilogue.
|
|
||||||
* The epilogue is required for decoders to consider a frame completed.
|
|
||||||
* Similar to ZSTD_flushStream(), it may not be able to flush the full content if `output->size` is too small.
|
|
||||||
* In which case, call again ZSTD_endStream() to complete the flush.
|
|
||||||
* @return : nb of bytes still present within internal buffer (0 if it's empty)
|
|
||||||
* or an error code, which can be tested using ZSTD_isError().
|
|
||||||
*
|
|
||||||
* *******************************************************************/
|
|
||||||
|
|
||||||
typedef struct ZSTD_CStream_s ZSTD_CStream;
|
|
||||||
ZSTD_CStream* ZSTD_createCStream(void);
|
|
||||||
size_t ZSTD_freeCStream(ZSTD_CStream* zcs);
|
|
||||||
|
|
||||||
size_t ZSTD_CStreamInSize(void); /**< recommended size for input buffer */
|
|
||||||
size_t ZSTD_CStreamOutSize(void); /**< recommended size for output buffer */
|
|
||||||
|
|
||||||
size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel);
|
|
||||||
size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
|
|
||||||
size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
|
|
||||||
size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
|
|
||||||
|
|
||||||
/* advanced */
|
|
||||||
ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
|
|
||||||
size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel);
|
|
||||||
size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
|
|
||||||
ZSTD_parameters params, unsigned long long pledgedSrcSize);
|
|
||||||
|
|
||||||
|
|
||||||
/*====== decompression ======*/
|
/*====== decompression ======*/
|
||||||
|
|
||||||
/*-***************************************************************************
|
typedef enum { ZSTDdsp_maxWindowSize } ZSTD_DStreamParameter_e;
|
||||||
* Streaming decompression howto
|
|
||||||
*
|
|
||||||
* A ZSTD_DStream object is required to track streaming operations.
|
|
||||||
* Use ZSTD_createDStream() and ZSTD_freeDStream() to create/release resources.
|
|
||||||
* ZSTD_DStream objects can be re-init multiple times.
|
|
||||||
*
|
|
||||||
* Use ZSTD_initDStream() to start a new decompression operation,
|
|
||||||
* or ZSTD_initDStream_usingDict() if decompression requires a dictionary.
|
|
||||||
*
|
|
||||||
* Use ZSTD_decompressStream() repetitively to consume your input.
|
|
||||||
* The function will update both `pos`.
|
|
||||||
* Note that it may not consume the entire input (pos < size),
|
|
||||||
* in which case it's up to the caller to present remaining input again.
|
|
||||||
* @return : 0 when a frame is completely decoded and fully flushed,
|
|
||||||
* 1 when there is still some data left within internal buffer to flush,
|
|
||||||
* >1 when more data is expected, with value being a suggested next input size (it's just a hint, which helps latency, any size is accepted),
|
|
||||||
* or an error code, which can be tested using ZSTD_isError().
|
|
||||||
*
|
|
||||||
* *******************************************************************************/
|
|
||||||
|
|
||||||
typedef struct ZSTD_DStream_s ZSTD_DStream;
|
|
||||||
ZSTD_DStream* ZSTD_createDStream(void);
|
|
||||||
size_t ZSTD_freeDStream(ZSTD_DStream* zds);
|
|
||||||
|
|
||||||
size_t ZSTD_DStreamInSize(void); /*!< recommended size for input buffer */
|
|
||||||
size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output buffer */
|
|
||||||
|
|
||||||
size_t ZSTD_initDStream(ZSTD_DStream* zds);
|
|
||||||
size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
|
|
||||||
|
|
||||||
/* advanced */
|
|
||||||
ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
|
|
||||||
size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize);
|
|
||||||
|
|
||||||
|
ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
|
||||||
|
ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize);
|
||||||
|
ZSTDLIB_API size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, ZSTD_DStreamParameter_e paramType, unsigned paramValue);
|
||||||
|
ZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds); /**< re-use decompression parameters from previous init; saves dictionary loading */
|
||||||
|
ZSTDLIB_API size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
|
||||||
|
|
||||||
|
|
||||||
/* ******************************************************************
|
/* ******************************************************************
|
||||||
@@ -441,7 +447,7 @@ size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t di
|
|||||||
ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
|
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_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, unsigned long long pledgedSrcSize);
|
ZSTDLIB_API size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize);
|
||||||
ZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx);
|
ZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize);
|
||||||
|
|
||||||
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_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, const void* src, size_t srcSize);
|
ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
||||||
|
|||||||
+1
-27
@@ -3,42 +3,17 @@ zstd
|
|||||||
zstd32
|
zstd32
|
||||||
zstd-compress
|
zstd-compress
|
||||||
zstd-decompress
|
zstd-decompress
|
||||||
fullbench
|
|
||||||
fullbench32
|
|
||||||
fuzzer
|
|
||||||
fuzzer32
|
|
||||||
zbufftest
|
|
||||||
zbufftest32
|
|
||||||
zstreamtest
|
|
||||||
zstreamtest32
|
|
||||||
datagen
|
|
||||||
paramgrill
|
|
||||||
paramgrill32
|
|
||||||
roundTripCrash
|
|
||||||
|
|
||||||
# Object files
|
# Object files
|
||||||
*.o
|
*.o
|
||||||
*.ko
|
*.ko
|
||||||
|
default.profraw
|
||||||
# Libraries
|
|
||||||
*.lib
|
|
||||||
*.a
|
|
||||||
|
|
||||||
# Shared objects (inc. Windows DLLs)
|
|
||||||
*.dll
|
|
||||||
*.so
|
|
||||||
*.so.*
|
|
||||||
*.dylib
|
|
||||||
|
|
||||||
# Executables
|
# Executables
|
||||||
*.exe
|
*.exe
|
||||||
*.out
|
*.out
|
||||||
*.app
|
*.app
|
||||||
|
|
||||||
# Visual solution files
|
|
||||||
*.suo
|
|
||||||
*.user
|
|
||||||
|
|
||||||
# Default result files
|
# Default result files
|
||||||
dictionary
|
dictionary
|
||||||
grillResults.txt
|
grillResults.txt
|
||||||
@@ -53,5 +28,4 @@ afl
|
|||||||
|
|
||||||
# Misc files
|
# Misc files
|
||||||
*.bat
|
*.bat
|
||||||
fileTests.sh
|
|
||||||
dirTest*
|
dirTest*
|
||||||
|
|||||||
@@ -1,339 +0,0 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 2, June 1991
|
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
License is intended to guarantee your freedom to share and change free
|
|
||||||
software--to make sure the software is free for all its users. This
|
|
||||||
General Public License applies to most of the Free Software
|
|
||||||
Foundation's software and to any other program whose authors commit to
|
|
||||||
using it. (Some other Free Software Foundation software is covered by
|
|
||||||
the GNU Lesser General Public License instead.) You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
this service if you wish), that you receive source code or can get it
|
|
||||||
if you want it, that you can change the software or use pieces of it
|
|
||||||
in new free programs; and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
anyone to deny you these rights or to ask you to surrender the rights.
|
|
||||||
These restrictions translate to certain responsibilities for you if you
|
|
||||||
distribute copies of the software, or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must give the recipients all the rights that
|
|
||||||
you have. You must make sure that they, too, receive or can get the
|
|
||||||
source code. And you must show them these terms so they know their
|
|
||||||
rights.
|
|
||||||
|
|
||||||
We protect your rights with two steps: (1) copyright the software, and
|
|
||||||
(2) offer you this license which gives you legal permission to copy,
|
|
||||||
distribute and/or modify the software.
|
|
||||||
|
|
||||||
Also, for each author's protection and ours, we want to make certain
|
|
||||||
that everyone understands that there is no warranty for this free
|
|
||||||
software. If the software is modified by someone else and passed on, we
|
|
||||||
want its recipients to know that what they have is not the original, so
|
|
||||||
that any problems introduced by others will not reflect on the original
|
|
||||||
authors' reputations.
|
|
||||||
|
|
||||||
Finally, any free program is threatened constantly by software
|
|
||||||
patents. We wish to avoid the danger that redistributors of a free
|
|
||||||
program will individually obtain patent licenses, in effect making the
|
|
||||||
program proprietary. To prevent this, we have made it clear that any
|
|
||||||
patent must be licensed for everyone's free use or not licensed at all.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License applies to any program or other work which contains
|
|
||||||
a notice placed by the copyright holder saying it may be distributed
|
|
||||||
under the terms of this General Public License. The "Program", below,
|
|
||||||
refers to any such program or work, and a "work based on the Program"
|
|
||||||
means either the Program or any derivative work under copyright law:
|
|
||||||
that is to say, a work containing the Program or a portion of it,
|
|
||||||
either verbatim or with modifications and/or translated into another
|
|
||||||
language. (Hereinafter, translation is included without limitation in
|
|
||||||
the term "modification".) Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running the Program is not restricted, and the output from the Program
|
|
||||||
is covered only if its contents constitute a work based on the
|
|
||||||
Program (independent of having been made by running the Program).
|
|
||||||
Whether that is true depends on what the Program does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Program's
|
|
||||||
source code as you receive it, in any medium, provided that you
|
|
||||||
conspicuously and appropriately publish on each copy an appropriate
|
|
||||||
copyright notice and disclaimer of warranty; keep intact all the
|
|
||||||
notices that refer to this License and to the absence of any warranty;
|
|
||||||
and give any other recipients of the Program a copy of this License
|
|
||||||
along with the Program.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy, and
|
|
||||||
you may at your option offer warranty protection in exchange for a fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Program or any portion
|
|
||||||
of it, thus forming a work based on the Program, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) You must cause the modified files to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
b) You must cause any work that you distribute or publish, that in
|
|
||||||
whole or in part contains or is derived from the Program or any
|
|
||||||
part thereof, to be licensed as a whole at no charge to all third
|
|
||||||
parties under the terms of this License.
|
|
||||||
|
|
||||||
c) If the modified program normally reads commands interactively
|
|
||||||
when run, you must cause it, when started running for such
|
|
||||||
interactive use in the most ordinary way, to print or display an
|
|
||||||
announcement including an appropriate copyright notice and a
|
|
||||||
notice that there is no warranty (or else, saying that you provide
|
|
||||||
a warranty) and that users may redistribute the program under
|
|
||||||
these conditions, and telling the user how to view a copy of this
|
|
||||||
License. (Exception: if the Program itself is interactive but
|
|
||||||
does not normally print such an announcement, your work based on
|
|
||||||
the Program is not required to print an announcement.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Program,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Program, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Program.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Program
|
|
||||||
with the Program (or with a work based on the Program) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may copy and distribute the Program (or a work based on it,
|
|
||||||
under Section 2) in object code or executable form under the terms of
|
|
||||||
Sections 1 and 2 above provided that you also do one of the following:
|
|
||||||
|
|
||||||
a) Accompany it with the complete corresponding machine-readable
|
|
||||||
source code, which must be distributed under the terms of Sections
|
|
||||||
1 and 2 above on a medium customarily used for software interchange; or,
|
|
||||||
|
|
||||||
b) Accompany it with a written offer, valid for at least three
|
|
||||||
years, to give any third party, for a charge no more than your
|
|
||||||
cost of physically performing source distribution, a complete
|
|
||||||
machine-readable copy of the corresponding source code, to be
|
|
||||||
distributed under the terms of Sections 1 and 2 above on a medium
|
|
||||||
customarily used for software interchange; or,
|
|
||||||
|
|
||||||
c) Accompany it with the information you received as to the offer
|
|
||||||
to distribute corresponding source code. (This alternative is
|
|
||||||
allowed only for noncommercial distribution and only if you
|
|
||||||
received the program in object code or executable form with such
|
|
||||||
an offer, in accord with Subsection b above.)
|
|
||||||
|
|
||||||
The source code for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For an executable work, complete source
|
|
||||||
code means all the source code for all modules it contains, plus any
|
|
||||||
associated interface definition files, plus the scripts used to
|
|
||||||
control compilation and installation of the executable. However, as a
|
|
||||||
special exception, the source code distributed need not include
|
|
||||||
anything that is normally distributed (in either source or binary
|
|
||||||
form) with the major components (compiler, kernel, and so on) of the
|
|
||||||
operating system on which the executable runs, unless that component
|
|
||||||
itself accompanies the executable.
|
|
||||||
|
|
||||||
If distribution of executable or object code is made by offering
|
|
||||||
access to copy from a designated place, then offering equivalent
|
|
||||||
access to copy the source code from the same place counts as
|
|
||||||
distribution of the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, or distribute the Program
|
|
||||||
except as expressly provided under this License. Any attempt
|
|
||||||
otherwise to copy, modify, sublicense or distribute the Program is
|
|
||||||
void, and will automatically terminate your rights under this License.
|
|
||||||
However, parties who have received copies, or rights, from you under
|
|
||||||
this License will not have their licenses terminated so long as such
|
|
||||||
parties remain in full compliance.
|
|
||||||
|
|
||||||
5. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Program or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Program (or any work based on the
|
|
||||||
Program), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Program or works based on it.
|
|
||||||
|
|
||||||
6. Each time you redistribute the Program (or any work based on the
|
|
||||||
Program), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute or modify the Program subject to
|
|
||||||
these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties to
|
|
||||||
this License.
|
|
||||||
|
|
||||||
7. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Program at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Program by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Program.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under
|
|
||||||
any particular circumstance, the balance of the section is intended to
|
|
||||||
apply and the section as a whole is intended to apply in other
|
|
||||||
circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system, which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
8. If the distribution and/or use of the Program is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Program under this License
|
|
||||||
may add an explicit geographical distribution limitation excluding
|
|
||||||
those countries, so that distribution is permitted only in or among
|
|
||||||
countries not thus excluded. In such case, this License incorporates
|
|
||||||
the limitation as if written in the body of this License.
|
|
||||||
|
|
||||||
9. The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
|
||||||
specifies a version number of this License which applies to it and "any
|
|
||||||
later version", you have the option of following the terms and conditions
|
|
||||||
either of that version or of any later version published by the Free
|
|
||||||
Software Foundation. If the Program does not specify a version number of
|
|
||||||
this License, you may choose any version ever published by the Free Software
|
|
||||||
Foundation.
|
|
||||||
|
|
||||||
10. If you wish to incorporate parts of the Program into other free
|
|
||||||
programs whose distribution conditions are different, write to the author
|
|
||||||
to ask for permission. For software which is copyrighted by the Free
|
|
||||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
|
||||||
make exceptions for this. Our decision will be guided by the two goals
|
|
||||||
of preserving the free status of all derivatives of our free software and
|
|
||||||
of promoting the sharing and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
|
||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
|
||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
|
||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
|
||||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
|
||||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
|
||||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
|
||||||
REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
|
||||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
|
||||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
|
||||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
|
||||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|
||||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
convey the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program is interactive, make it output a short notice like this
|
|
||||||
when it starts in an interactive mode:
|
|
||||||
|
|
||||||
Gnomovision version 69, Copyright (C) year name of author
|
|
||||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, the commands you use may
|
|
||||||
be called something other than `show w' and `show c'; they could even be
|
|
||||||
mouse-clicks or menu items--whatever suits your program.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or your
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
|
||||||
necessary. Here is a sample; alter the names:
|
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
|
||||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1989
|
|
||||||
Ty Coon, President of Vice
|
|
||||||
|
|
||||||
This General Public License does not permit incorporating your program into
|
|
||||||
proprietary programs. If your program is a subroutine library, you may
|
|
||||||
consider it more useful to permit linking proprietary applications with the
|
|
||||||
library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License.
|
|
||||||
+37
-162
@@ -1,34 +1,17 @@
|
|||||||
# ##########################################################################
|
# ##########################################################################
|
||||||
# ZSTD programs - Makefile
|
# Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
# Copyright (C) Yann Collet 2015-2016
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# GPL v2 License
|
# This source code is licensed under the BSD-style license found in the
|
||||||
#
|
# LICENSE file in the root directory of this source tree. An additional grant
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# of patent rights can be found in the PATENTS file in the same directory.
|
||||||
# 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/
|
|
||||||
# ##########################################################################
|
# ##########################################################################
|
||||||
# zstd : Command Line Utility, supporting gzip-like arguments
|
# zstd : Command Line Utility, supporting gzip-like arguments
|
||||||
# datagen : Synthetic and parametrable data generator, for tests
|
# zstd32 : Same as zstd, but forced to compile in 32-bits mode
|
||||||
# fuzzer : Test tool, to check zstd integrity on target platform
|
# zstd_nolegacy : zstd without support of decompression of legacy versions
|
||||||
# fuzzer32: Same as fuzzer, but forced to compile in 32-bits mode
|
# zstd-small : minimal zstd without dictionary builder and benchmark
|
||||||
# zbufftest : Test tool, to check ZBUFF integrity on target platform
|
# zstd-compress : compressor-only version of zstd
|
||||||
# zbufftest32: Same as zbufftest, but forced to compile in 32-bits mode
|
# zstd-decompress : decompressor-only version of zstd
|
||||||
# fullbench : Precisely measure speed for each zstd inner function
|
|
||||||
# fullbench32: Same as fullbench, but forced to compile in 32-bits mode
|
|
||||||
# ##########################################################################
|
# ##########################################################################
|
||||||
|
|
||||||
DESTDIR?=
|
DESTDIR?=
|
||||||
@@ -56,7 +39,6 @@ ZSTDCOMMON_FILES := $(ZSTDDIR)/common/*.c
|
|||||||
ZSTDCOMP_FILES := $(ZSTDDIR)/compress/zstd_compress.c $(ZSTDDIR)/compress/fse_compress.c $(ZSTDDIR)/compress/huf_compress.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
|
ZSTDDECOMP_FILES := $(ZSTDDIR)/decompress/huf_decompress.c
|
||||||
ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES)
|
ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES)
|
||||||
ZBUFF_FILES := $(ZSTDDIR)/compress/zbuff_compress.c $(ZSTDDIR)/decompress/zbuff_decompress.c
|
|
||||||
ZDICT_FILES := $(ZSTDDIR)/dictBuilder/*.c
|
ZDICT_FILES := $(ZSTDDIR)/dictBuilder/*.c
|
||||||
ZSTDDECOMP_O = $(ZSTDDIR)/decompress/zstd_decompress.o
|
ZSTDDECOMP_O = $(ZSTDDIR)/decompress/zstd_decompress.o
|
||||||
ZSTDDECOMP32_O = $(ZSTDDIR)/decompress/zstd_decompress32.o
|
ZSTDDECOMP32_O = $(ZSTDDIR)/decompress/zstd_decompress32.o
|
||||||
@@ -66,8 +48,8 @@ CPPFLAGS += -DZSTD_LEGACY_SUPPORT=0
|
|||||||
ZSTDLEGACY_FILES:=
|
ZSTDLEGACY_FILES:=
|
||||||
else
|
else
|
||||||
ZSTD_LEGACY_SUPPORT:=1
|
ZSTD_LEGACY_SUPPORT:=1
|
||||||
CPPFLAGS += -I$(ZSTDDIR)/legacy -I./legacy
|
CPPFLAGS += -I$(ZSTDDIR)/legacy
|
||||||
ZSTDLEGACY_FILES:= $(ZSTDDIR)/legacy/*.c legacy/fileio_legacy.c
|
ZSTDLEGACY_FILES:= $(ZSTDDIR)/legacy/*.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
@@ -75,37 +57,39 @@ endif
|
|||||||
ifneq (,$(filter Windows%,$(OS)))
|
ifneq (,$(filter Windows%,$(OS)))
|
||||||
EXT =.exe
|
EXT =.exe
|
||||||
VOID = nul
|
VOID = nul
|
||||||
|
RES64_FILE = ..\build\VS2010\zstd\generate_res\zstd64.res
|
||||||
|
RES32_FILE = ..\build\VS2010\zstd\generate_res\zstd32.res
|
||||||
|
ifneq (,$(filter x86_64%,$(shell $(CC) -dumpmachine)))
|
||||||
|
RES_FILE = $(RES64_FILE)
|
||||||
|
else
|
||||||
|
RES_FILE = $(RES32_FILE)
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
EXT =
|
EXT =
|
||||||
VOID = /dev/null
|
VOID = /dev/null
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ZBUFFTEST = -T2mn
|
|
||||||
FUZZERTEST= -T5mn
|
|
||||||
ZSTDRTTEST= --test-large-data
|
|
||||||
|
|
||||||
.PHONY: default all all32 clean install uninstall test test32 test-all
|
.PHONY: default all clean install uninstall
|
||||||
|
|
||||||
default: zstd
|
default: zstd
|
||||||
|
|
||||||
all: zstd fullbench fuzzer zbufftest zstreamtest paramgrill datagen
|
all: zstd
|
||||||
|
|
||||||
all32: cleano32 zstd32 fullbench32 fuzzer32 zbufftest32 zstreamtest32
|
|
||||||
|
|
||||||
|
|
||||||
$(ZSTDDECOMP_O): $(ZSTDDIR)/decompress/zstd_decompress.c
|
$(ZSTDDECOMP_O): $(ZSTDDIR)/decompress/zstd_decompress.c
|
||||||
$(CC) $(ALIGN_LOOP) $(FLAGS) $^ -c -o $@
|
$(CC) $(ALIGN_LOOP) $(FLAGS) -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) $^ -c -o $@
|
||||||
|
|
||||||
$(ZSTDDECOMP32_O): $(ZSTDDIR)/decompress/zstd_decompress.c
|
$(ZSTDDECOMP32_O): $(ZSTDDIR)/decompress/zstd_decompress.c
|
||||||
$(CC) -m32 $(ALIGN_LOOP) $(FLAGS) $^ -c -o $@
|
$(CC) -m32 $(ALIGN_LOOP) $(FLAGS) -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) $^ -c -o $@
|
||||||
|
|
||||||
zstd : $(ZSTDDECOMP_O) $(ZSTD_FILES) $(ZSTDLEGACY_FILES) $(ZDICT_FILES) \
|
zstd : $(ZSTDDECOMP_O) $(ZSTD_FILES) $(ZSTDLEGACY_FILES) $(ZDICT_FILES) \
|
||||||
zstdcli.c fileio.c bench.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) $^ $(RES_FILE) -o $@$(EXT)
|
||||||
|
|
||||||
zstd32 : $(ZSTDDECOMP32_O) $(ZSTD_FILES) $(ZSTDLEGACY_FILES) $(ZDICT_FILES) \
|
zstd32 : $(ZSTDDECOMP32_O) $(ZSTD_FILES) $(ZSTDLEGACY_FILES) $(ZDICT_FILES) \
|
||||||
zstdcli.c fileio.c bench.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) $^ $(RES32_FILE) -o $@$(EXT)
|
||||||
|
|
||||||
|
|
||||||
zstd_nolegacy :
|
zstd_nolegacy :
|
||||||
@@ -119,7 +103,8 @@ zstd-pgo : clean zstd
|
|||||||
./zstd -b $(PROFILE_WITH)
|
./zstd -b $(PROFILE_WITH)
|
||||||
./zstd -b7i2 $(PROFILE_WITH)
|
./zstd -b7i2 $(PROFILE_WITH)
|
||||||
./zstd -b5 $(PROFILE_WITH)
|
./zstd -b5 $(PROFILE_WITH)
|
||||||
rm zstd
|
$(RM) zstd
|
||||||
|
$(RM) $(ZSTDDIR)/decompress/zstd_decompress.o
|
||||||
$(MAKE) zstd MOREFLAGS=-fprofile-use
|
$(MAKE) zstd MOREFLAGS=-fprofile-use
|
||||||
|
|
||||||
zstd-frugal: $(ZSTDDECOMP_O) $(ZSTD_FILES) zstdcli.c fileio.c
|
zstd-frugal: $(ZSTDDECOMP_O) $(ZSTD_FILES) zstdcli.c fileio.c
|
||||||
@@ -136,58 +121,20 @@ zstd-decompress: $(ZSTDCOMMON_FILES) $(ZSTDDECOMP_FILES) \
|
|||||||
zstd-small: clean
|
zstd-small: clean
|
||||||
CFLAGS="-Os -s" $(MAKE) zstd-frugal
|
CFLAGS="-Os -s" $(MAKE) zstd-frugal
|
||||||
|
|
||||||
fullbench : $(ZSTDDECOMP_O) $(ZSTD_FILES) $(ZBUFF_FILES) datagen.c fullbench.c
|
|
||||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
|
||||||
|
|
||||||
fullbench32 : $(ZSTDDECOMP32_O) $(ZSTD_FILES) $(ZBUFF_FILES) datagen.c fullbench.c
|
|
||||||
$(CC) -m32 $(FLAGS) $^ -o $@$(EXT)
|
|
||||||
|
|
||||||
fuzzer : CPPFLAGS += -I$(ZSTDDIR)/dictBuilder
|
|
||||||
fuzzer : $(ZSTDDECOMP_O) $(ZSTD_FILES) $(ZDICT_FILES) datagen.c fuzzer.c
|
|
||||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
|
||||||
|
|
||||||
fuzzer32 : CPPFLAGS += -I$(ZSTDDIR)/dictBuilder
|
|
||||||
fuzzer32 : $(ZSTDDECOMP32_O) $(ZSTD_FILES) $(ZDICT_FILES) datagen.c fuzzer.c
|
|
||||||
$(CC) -m32 $(FLAGS) $^ -o $@$(EXT)
|
|
||||||
|
|
||||||
zbufftest : $(ZSTDDECOMP_O) $(ZSTD_FILES) $(ZBUFF_FILES) datagen.c zbufftest.c
|
|
||||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
|
||||||
|
|
||||||
zbufftest32 : $(ZSTDDECOMP32_O) $(ZSTD_FILES) $(ZBUFF_FILES) datagen.c zbufftest.c
|
|
||||||
$(CC) -m32 $(FLAGS) $^ -o $@$(EXT)
|
|
||||||
|
|
||||||
zstreamtest : $(ZSTDDECOMP_O) $(ZSTD_FILES) datagen.c zstreamtest.c
|
|
||||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
|
||||||
|
|
||||||
zstreamtest32 : $(ZSTDDECOMP32_O) $(ZSTD_FILES) datagen.c zstreamtest.c
|
|
||||||
$(CC) -m32 $(FLAGS) $^ -o $@$(EXT)
|
|
||||||
|
|
||||||
paramgrill : $(ZSTDDECOMP_O) $(ZSTD_FILES) datagen.c paramgrill.c
|
|
||||||
$(CC) $(FLAGS) $^ -lm -o $@$(EXT)
|
|
||||||
|
|
||||||
datagen : datagen.c datagencli.c
|
|
||||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
|
||||||
|
|
||||||
roundTripCrash : $(ZSTDDECOMP_O) $(ZSTD_FILES) roundTripCrash.c
|
|
||||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -C ../lib clean
|
$(MAKE) -C ../lib clean
|
||||||
@rm -f core *.o tmp* result* *.gcda dictionary *.zst \
|
@$(RM) $(ZSTDDIR)/decompress/*.o $(ZSTDDIR)/decompress/zstd_decompress.gcda
|
||||||
|
@$(RM) 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) \
|
*.gcda default.profraw
|
||||||
fuzzer$(EXT) fuzzer32$(EXT) zbufftest$(EXT) zbufftest32$(EXT) \
|
|
||||||
datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT)
|
|
||||||
@echo Cleaning completed
|
@echo Cleaning completed
|
||||||
|
|
||||||
cleano32:
|
|
||||||
@rm -f ../lib/decompress/*.o
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------
|
||||||
#make install is validated only for Linux, OSX, kFreeBSD, Hurd and some BSD targets
|
#make install is validated only for Linux, OSX, kFreeBSD, Hurd and some BSD targets
|
||||||
#----------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------
|
||||||
ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD DragonFly))
|
ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD DragonFly NetBSD))
|
||||||
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)/
|
||||||
@@ -201,83 +148,11 @@ install: zstd
|
|||||||
@echo zstd installation completed
|
@echo zstd installation completed
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f $(DESTDIR)$(BINDIR)/zstdcat
|
$(RM) $(DESTDIR)$(BINDIR)/zstdcat
|
||||||
rm -f $(DESTDIR)$(BINDIR)/unzstd
|
$(RM) $(DESTDIR)$(BINDIR)/unzstd
|
||||||
[ -x $(DESTDIR)$(BINDIR)/zstd$(EXT) ] && rm -f $(DESTDIR)$(BINDIR)/zstd$(EXT)
|
$(RM) $(DESTDIR)$(BINDIR)/zstd$(EXT)
|
||||||
rm -f $(DESTDIR)$(MANDIR)/zstdcat.1
|
$(RM) $(DESTDIR)$(MANDIR)/zstdcat.1
|
||||||
rm -f $(DESTDIR)$(MANDIR)/unzstd.1
|
$(RM) $(DESTDIR)$(MANDIR)/unzstd.1
|
||||||
[ -f $(DESTDIR)$(MANDIR)/zstd.1 ] && rm -f $(DESTDIR)$(MANDIR)/zstd.1
|
$(RM) $(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-zstream
|
|
||||||
|
|
||||||
test32: test-zstd32 test-fullbench32 test-fuzzer32 test-zbuff32 test-zstream32
|
|
||||||
|
|
||||||
test-all: test test32 valgrindTest
|
|
||||||
|
|
||||||
test-zstd: ZSTD = ./zstd
|
|
||||||
test-zstd: zstd zstd-playTests
|
|
||||||
|
|
||||||
test-zstd32: ZSTD = ./zstd32
|
|
||||||
test-zstd32: zstd32 zstd-playTests
|
|
||||||
|
|
||||||
test-zstd_nolegacy: ZSTD = ./zstd
|
|
||||||
test-zstd_nolegacy: zstd_nolegacy zstd-playTests
|
|
||||||
|
|
||||||
test-fullbench: fullbench datagen
|
|
||||||
./fullbench -i1
|
|
||||||
./fullbench -i1 -P0
|
|
||||||
|
|
||||||
test-fullbench32: fullbench32 datagen
|
|
||||||
./fullbench32 -i1
|
|
||||||
./fullbench32 -i1 -P0
|
|
||||||
|
|
||||||
test-fuzzer: fuzzer
|
|
||||||
./fuzzer $(FUZZERTEST)
|
|
||||||
|
|
||||||
test-fuzzer32: fuzzer32
|
|
||||||
./fuzzer32 $(FUZZERTEST)
|
|
||||||
|
|
||||||
test-zbuff: zbufftest
|
|
||||||
./zbufftest $(ZBUFFTEST)
|
|
||||||
|
|
||||||
test-zbuff32: zbufftest32
|
|
||||||
./zbufftest32 $(ZBUFFTEST)
|
|
||||||
|
|
||||||
test-zstream: zstreamtest
|
|
||||||
./zstreamtest $(ZBUFFTEST)
|
|
||||||
|
|
||||||
test-zstream32: zstreamtest32
|
|
||||||
./zstreamtest32 $(ZBUFFTEST)
|
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
Command Line Interface for Zstandard library
|
||||||
|
============================================
|
||||||
|
|
||||||
|
Command Line Interface (CLI) can be created using the `make` command without any additional parameters.
|
||||||
|
There are however other Makefile targets that create different variations of CLI:
|
||||||
|
- `zstd` : default CLI supporting gzip-like arguments; includes dictionary builder, benchmark, and support for decompression of legacy zstd versions
|
||||||
|
- `zstd32` : Same as `zstd`, but forced to compile in 32-bits mode
|
||||||
|
- `zstd_nolegacy` : Same as `zstd` except of support for decompression of legacy zstd versions
|
||||||
|
- `zstd-small` : CLI optimized for minimal size; without dictionary builder, benchmark, and support for decompression of legacy zstd versions
|
||||||
|
- `zstd-compress` : compressor-only version of CLI; without dictionary builder, benchmark, and support for decompression of legacy zstd versions
|
||||||
|
- `zstd-decompress` : decompressor-only version of CLI; without dictionary builder, benchmark, and support for decompression of legacy zstd versions
|
||||||
|
|
||||||
|
|
||||||
|
#### Aggregation of parameters
|
||||||
|
CLI supports aggregation of parameters i.e. `-b1`, `-e18`, and `-i1` can be joined into `-b1e18i1`.
|
||||||
|
|
||||||
|
|
||||||
|
#### Dictionary builder in Command Line Interface
|
||||||
|
Zstd offers a training mode, which can be used to tune the algorithm for a selected
|
||||||
|
type of data, by providing it with a few samples. The result of the training is stored
|
||||||
|
in a file selected with the `-o` option (default name is `dictionary`),
|
||||||
|
which can be loaded before compression and decompression.
|
||||||
|
|
||||||
|
Using a dictionary, the compression ratio achievable on small data improves dramatically.
|
||||||
|
These compression gains are achieved while simultaneously providing faster compression and decompression speeds.
|
||||||
|
Dictionary work if there is some correlation in a family of small data (there is no universal dictionary).
|
||||||
|
Hence, deploying one dictionary per type of data will provide the greater benefits.
|
||||||
|
Dictionary gains are mostly effective in the first few KB. Then, the compression algorithm
|
||||||
|
will rely more and more on previously decoded content to compress the rest of the file.
|
||||||
|
|
||||||
|
Usage of the dictionary builder and created dictionaries with CLI:
|
||||||
|
|
||||||
|
1. Create the dictionary : `zstd --train FullPathToTrainingSet/* -o dictionaryName`
|
||||||
|
2. Compress with the dictionary: `zstd FILE -D dictionaryName`
|
||||||
|
3. Decompress with the dictionary: `zstd --decompress FILE.zst -D dictionaryName`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### Benchmark in Command Line Interface
|
||||||
|
CLI includes in-memory compression benchmark module for zstd.
|
||||||
|
The benchmark is conducted using given filenames. The files are read into memory and joined together.
|
||||||
|
It makes benchmark more precise as it eliminates I/O overhead.
|
||||||
|
Many filenames can be supplied as multiple parameters, parameters with wildcards or
|
||||||
|
names of directories can be used as parameters with the `-r` option.
|
||||||
|
|
||||||
|
The benchmark measures ratio, compressed size, compression and decompression speed.
|
||||||
|
One can select compression levels starting from `-b` and ending with `-e`.
|
||||||
|
The `-i` parameter selects minimal time used for each of tested levels.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### Usage of Command Line Interface
|
||||||
|
The full list of options can be obtained with `-h` or `-H` parameter:
|
||||||
|
```
|
||||||
|
Usage :
|
||||||
|
zstd [args] [FILE(s)] [-o file]
|
||||||
|
|
||||||
|
FILE : a filename
|
||||||
|
with no FILE, or when FILE is - , read standard input
|
||||||
|
Arguments :
|
||||||
|
-# : # compression level (1-19, default:3)
|
||||||
|
-d : decompression
|
||||||
|
-D file: use `file` as Dictionary
|
||||||
|
-o file: result stored into `file` (only if 1 input file)
|
||||||
|
-f : overwrite output without prompting
|
||||||
|
--rm : remove source file(s) after successful de/compression
|
||||||
|
-k : preserve source file(s) (default)
|
||||||
|
-h/-H : display help/long help and exit
|
||||||
|
|
||||||
|
Advanced arguments :
|
||||||
|
-V : display Version number and exit
|
||||||
|
-v : verbose mode; specify multiple times to increase log level (default:2)
|
||||||
|
-q : suppress warnings; specify twice to suppress errors too
|
||||||
|
-c : force write to standard output, even if it is the console
|
||||||
|
-r : operate recursively on directories
|
||||||
|
--ultra : enable levels beyond 19, up to 22 (requires more memory)
|
||||||
|
--no-dictID : don't write dictID into header (dictionary compression)
|
||||||
|
--[no-]check : integrity check (default:enabled)
|
||||||
|
--test : test compressed file integrity
|
||||||
|
--[no-]sparse : sparse mode (default:enabled on file, disabled on stdout)
|
||||||
|
|
||||||
|
Dictionary builder :
|
||||||
|
--train ## : create a dictionary from a training set of files
|
||||||
|
-o file : `file` is dictionary name (default: dictionary)
|
||||||
|
--maxdict ## : limit dictionary to specified size (default : 112640)
|
||||||
|
-s# : dictionary selectivity level (default: 9)
|
||||||
|
--dictID ## : force dictionary ID to specified value (default: random)
|
||||||
|
|
||||||
|
Benchmark arguments :
|
||||||
|
-b# : benchmark file(s), using # compression level (default : 1)
|
||||||
|
-e# : test all compression levels from -bX to # (default: 1)
|
||||||
|
-i# : minimum evaluation time in seconds (default : 3s)
|
||||||
|
-B# : cut file into independent blocks of size # (default: no block)
|
||||||
|
```
|
||||||
+10
-26
@@ -1,27 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
bench.c - open-source compression benchmark module
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2012-2016
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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
|
|
||||||
- zstd source repository : https://github.com/Cyan4973/zstd
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Includes
|
* Includes
|
||||||
@@ -30,7 +15,7 @@
|
|||||||
#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 <time.h> /* clock_t, clock, CLOCKS_PER_SEC */
|
#include <time.h> /* clock_t, clock, CLOCKS_PER_SEC */
|
||||||
|
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#define ZSTD_STATIC_LINKING_ONLY
|
#define ZSTD_STATIC_LINKING_ONLY
|
||||||
@@ -39,7 +24,6 @@
|
|||||||
#include "xxhash.h"
|
#include "xxhash.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Constants
|
* Constants
|
||||||
***************************************/
|
***************************************/
|
||||||
@@ -257,7 +241,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
|||||||
(void)fastestD; (void)crcOrig; /* unused when decompression disabled */
|
(void)fastestD; (void)crcOrig; /* unused when decompression disabled */
|
||||||
#if 1
|
#if 1
|
||||||
/* Decompression */
|
/* Decompression */
|
||||||
memset(resultBuffer, 0xD6, srcSize); /* warm result buffer */
|
if (!dCompleted) memset(resultBuffer, 0xD6, srcSize); /* warm result buffer */
|
||||||
|
|
||||||
UTIL_sleepMilli(1); /* give processor time to other processes */
|
UTIL_sleepMilli(1); /* give processor time to other processes */
|
||||||
UTIL_waitForNextTick(ticksPerSecond);
|
UTIL_waitForNextTick(ticksPerSecond);
|
||||||
|
|||||||
+8
-21
@@ -1,26 +1,13 @@
|
|||||||
/*
|
/**
|
||||||
bench.h - Demo program to benchmark open-source compression algorithm
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2012-2016
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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/
|
|
||||||
*/
|
|
||||||
#ifndef BENCH_H_121279284357
|
#ifndef BENCH_H_121279284357
|
||||||
#define BENCH_H_121279284357
|
#define BENCH_H_121279284357
|
||||||
|
|
||||||
|
|||||||
+10
-25
@@ -1,27 +1,13 @@
|
|||||||
/*
|
/**
|
||||||
datagen.c - compressible data generator test tool
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2012-2016
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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/
|
|
||||||
- source repository : https://github.com/Cyan4973/zstd
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Compiler Options
|
* Compiler Options
|
||||||
@@ -34,10 +20,9 @@
|
|||||||
/*-************************************
|
/*-************************************
|
||||||
* Dependencies
|
* Dependencies
|
||||||
**************************************/
|
**************************************/
|
||||||
#include <stdlib.h> /* malloc */
|
#include <stdlib.h> /* malloc, free */
|
||||||
#include <stdio.h> /* FILE, fwrite, fprintf */
|
#include <stdio.h> /* FILE, fwrite, fprintf */
|
||||||
#include <string.h> /* memcpy */
|
#include <string.h> /* memcpy */
|
||||||
#include <errno.h> /* errno */
|
|
||||||
#include "mem.h" /* U32 */
|
#include "mem.h" /* U32 */
|
||||||
|
|
||||||
|
|
||||||
@@ -190,7 +175,7 @@ void RDG_genStdout(unsigned long long size, double matchProba, double litProba,
|
|||||||
BYTE ldt[LTSIZE]; /* literals distribution table */
|
BYTE ldt[LTSIZE]; /* literals distribution table */
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
if (buff==NULL) { fprintf(stderr, "datagen: error: %s \n", strerror(errno)); exit(1); }
|
if (buff==NULL) { perror("datagen"); exit(1); }
|
||||||
if (litProba<=0.0) litProba = matchProba / 4.5;
|
if (litProba<=0.0) litProba = matchProba / 4.5;
|
||||||
memset(ldt, '0', sizeof(ldt)); /* yes, character '0', this is intentional */
|
memset(ldt, '0', sizeof(ldt)); /* yes, character '0', this is intentional */
|
||||||
RDG_fillLiteralDistrib(ldt, litProba);
|
RDG_fillLiteralDistrib(ldt, litProba);
|
||||||
|
|||||||
+12
-25
@@ -1,28 +1,13 @@
|
|||||||
/*
|
/**
|
||||||
datagen.h - compressible data generator header
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2012-2015
|
* All rights reserved.
|
||||||
|
*
|
||||||
GPL v2 License
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
This program is free software; you can redistribute it and/or modify
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
it under the terms of the GNU General Public License as published by
|
*/
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
#ifndef DATAGEN_H
|
||||||
(at your option) any later version.
|
#define DATAGEN_H
|
||||||
|
|
||||||
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 source repository : https://github.com/Cyan4973/zstd
|
|
||||||
- Public forum : https://groups.google.com/forum/#!forum/lz4c
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stddef.h> /* size_t */
|
#include <stddef.h> /* size_t */
|
||||||
|
|
||||||
@@ -38,3 +23,5 @@ void RDG_genBuffer(void* buffer, size_t size, double matchProba, double litProba
|
|||||||
RDG_genStdout
|
RDG_genStdout
|
||||||
Same as RDG_genBuffer, but generates data into stdout
|
Same as RDG_genBuffer, but generates data into stdout
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
+8
-21
@@ -1,26 +1,13 @@
|
|||||||
/*
|
/**
|
||||||
dibio - I/O API for dictionary builder
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2016
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Includes
|
* Includes
|
||||||
|
|||||||
+8
-23
@@ -1,26 +1,11 @@
|
|||||||
/*
|
/**
|
||||||
dibio.h - I/O API for dictionary builder
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2016
|
* All rights reserved.
|
||||||
|
*
|
||||||
GPL v2 License
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
This program is free software; you can redistribute it and/or modify
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
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 library is designed for a single-threaded console application.
|
/* This library is designed for a single-threaded console application.
|
||||||
* It exit() and printf() into stderr when it encounters an error condition. */
|
* It exit() and printf() into stderr when it encounters an error condition. */
|
||||||
|
|||||||
+73
-88
@@ -1,38 +1,26 @@
|
|||||||
/*
|
/**
|
||||||
fileio.c - File i/o handler for zstd
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2013-2016
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
/*
|
/*
|
||||||
Note : this file is part of zstd command line, which is not library.
|
Note : this file is part of zstd command line, which is not library.
|
||||||
The license of ZSTD library is BSD.
|
The license of ZSTD library is BSD.
|
||||||
The license of this file is GPLv2.
|
The license of this file is GPLv2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
* Tuning options
|
* Tuning options
|
||||||
***************************************/
|
***************************************/
|
||||||
#ifndef ZSTD_LEGACY_SUPPORT
|
#ifndef ZSTD_LEGACY_SUPPORT
|
||||||
/* LEGACY_SUPPORT :
|
/* LEGACY_SUPPORT :
|
||||||
* decompressor can decode older formats (starting from Zstd 0.1+) */
|
* decompressor can decode older formats (starting from zstd 0.1+) */
|
||||||
# define ZSTD_LEGACY_SUPPORT 1
|
# define ZSTD_LEGACY_SUPPORT 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -45,7 +33,7 @@
|
|||||||
# pragma warning(disable : 4204) /* non-constant aggregate initializer */
|
# pragma warning(disable : 4204) /* non-constant aggregate initializer */
|
||||||
#endif
|
#endif
|
||||||
#if defined(__MINGW32__) && !defined(_POSIX_SOURCE)
|
#if defined(__MINGW32__) && !defined(_POSIX_SOURCE)
|
||||||
# define _POSIX_SOURCE 1 /* disable %llu warnings with MinGW on Windows */
|
# define _POSIX_SOURCE 1 /* disable %llu warnings with MinGW on Windows */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
@@ -65,7 +53,6 @@
|
|||||||
|
|
||||||
#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 */
|
||||||
# include "fileio_legacy.h" /* FIO_decompressLegacyFrame */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -132,8 +119,6 @@ static clock_t g_time = 0;
|
|||||||
***************************************/
|
***************************************/
|
||||||
static U32 g_overwrite = 0;
|
static U32 g_overwrite = 0;
|
||||||
void FIO_overwriteMode(void) { g_overwrite=1; }
|
void FIO_overwriteMode(void) { g_overwrite=1; }
|
||||||
static U32 g_maxWLog = 23;
|
|
||||||
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 */
|
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; }
|
void FIO_setSparseWrite(unsigned sparse) { g_sparseFileSupport=sparse; }
|
||||||
static U32 g_dictIDFlag = 1;
|
static U32 g_dictIDFlag = 1;
|
||||||
@@ -180,7 +165,9 @@ static FILE* FIO_openSrcFile(const char* srcFileName)
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* `dstFileName must` be non-NULL */
|
/** FIO_openDstFile() :
|
||||||
|
* condition : `dstFileName` must be non-NULL.
|
||||||
|
* @result : FILE* to `dstFileName`, or NULL if it fails */
|
||||||
static FILE* FIO_openDstFile(const char* dstFileName)
|
static FILE* FIO_openDstFile(const char* dstFileName)
|
||||||
{
|
{
|
||||||
FILE* f;
|
FILE* f;
|
||||||
@@ -263,14 +250,12 @@ typedef struct {
|
|||||||
size_t srcBufferSize;
|
size_t srcBufferSize;
|
||||||
void* dstBuffer;
|
void* dstBuffer;
|
||||||
size_t dstBufferSize;
|
size_t dstBufferSize;
|
||||||
void* dictBuffer;
|
|
||||||
size_t dictBufferSize;
|
|
||||||
ZSTD_CStream* cctx;
|
ZSTD_CStream* cctx;
|
||||||
FILE* dstFile;
|
FILE* dstFile;
|
||||||
FILE* srcFile;
|
FILE* srcFile;
|
||||||
} cRess_t;
|
} cRess_t;
|
||||||
|
|
||||||
static cRess_t FIO_createCResources(const char* dictFileName)
|
static cRess_t FIO_createCResources(const char* dictFileName, int cLevel, U64 srcSize)
|
||||||
{
|
{
|
||||||
cRess_t ress;
|
cRess_t ress;
|
||||||
memset(&ress, 0, sizeof(ress));
|
memset(&ress, 0, sizeof(ress));
|
||||||
@@ -284,19 +269,27 @@ static cRess_t FIO_createCResources(const char* dictFileName)
|
|||||||
if (!ress.srcBuffer || !ress.dstBuffer) EXM_THROW(31, "zstd: allocation error : not enough memory");
|
if (!ress.srcBuffer || !ress.dstBuffer) EXM_THROW(31, "zstd: allocation error : not enough memory");
|
||||||
|
|
||||||
/* dictionary */
|
/* dictionary */
|
||||||
ress.dictBufferSize = FIO_loadFile(&(ress.dictBuffer), dictFileName);
|
{ void* dictBuffer;
|
||||||
|
size_t const dictBuffSize = FIO_loadFile(&dictBuffer, dictFileName);
|
||||||
|
if (dictFileName && (dictBuffer==NULL)) EXM_THROW(32, "zstd: allocation error : can't create dictBuffer");
|
||||||
|
{ ZSTD_parameters params = ZSTD_getParams(cLevel, srcSize, dictBuffSize);
|
||||||
|
params.fParams.contentSizeFlag = 1;
|
||||||
|
params.fParams.checksumFlag = g_checksumFlag;
|
||||||
|
params.fParams.noDictIDFlag = !g_dictIDFlag;
|
||||||
|
{ size_t const errorCode = ZSTD_initCStream_advanced(ress.cctx, dictBuffer, dictBuffSize, params, srcSize);
|
||||||
|
if (ZSTD_isError(errorCode)) EXM_THROW(33, "Error initializing CStream : %s", ZSTD_getErrorName(errorCode));
|
||||||
|
} }
|
||||||
|
free(dictBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
return ress;
|
return ress;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FIO_freeCResources(cRess_t ress)
|
static void FIO_freeCResources(cRess_t ress)
|
||||||
{
|
{
|
||||||
size_t errorCode;
|
|
||||||
free(ress.srcBuffer);
|
free(ress.srcBuffer);
|
||||||
free(ress.dstBuffer);
|
free(ress.dstBuffer);
|
||||||
free(ress.dictBuffer);
|
ZSTD_freeCStream(ress.cctx); /* never fails */
|
||||||
errorCode = ZSTD_freeCStream(ress.cctx);
|
|
||||||
if (ZSTD_isError(errorCode)) EXM_THROW(38, "zstd: error : can't release ZSTD_CStream : %s", ZSTD_getErrorName(errorCode));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -306,8 +299,7 @@ static void FIO_freeCResources(cRess_t ress)
|
|||||||
* 1 : missing or pb opening srcFileName
|
* 1 : missing or pb opening srcFileName
|
||||||
*/
|
*/
|
||||||
static int FIO_compressFilename_internal(cRess_t ress,
|
static int FIO_compressFilename_internal(cRess_t ress,
|
||||||
const char* dstFileName, const char* srcFileName,
|
const char* dstFileName, const char* srcFileName)
|
||||||
int cLevel)
|
|
||||||
{
|
{
|
||||||
FILE* const srcFile = ress.srcFile;
|
FILE* const srcFile = ress.srcFile;
|
||||||
FILE* const dstFile = ress.dstFile;
|
FILE* const dstFile = ress.dstFile;
|
||||||
@@ -316,17 +308,9 @@ static int FIO_compressFilename_internal(cRess_t ress,
|
|||||||
U64 const fileSize = UTIL_getFileSize(srcFileName);
|
U64 const fileSize = UTIL_getFileSize(srcFileName);
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
{ ZSTD_parameters params = ZSTD_getParams(cLevel, fileSize, ress.dictBufferSize);
|
{ size_t const resetError = ZSTD_resetCStream(ress.cctx, fileSize);
|
||||||
params.fParams.contentSizeFlag = 1;
|
if (ZSTD_isError(resetError)) EXM_THROW(21, "Error initializing compression : %s", ZSTD_getErrorName(resetError));
|
||||||
params.fParams.checksumFlag = g_checksumFlag;
|
}
|
||||||
params.fParams.noDictIDFlag = !g_dictIDFlag;
|
|
||||||
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 = ZSTD_initCStream_advanced(ress.cctx, ress.dictBuffer, ress.dictBufferSize, params, fileSize);
|
|
||||||
if (ZSTD_isError(errorCode)) EXM_THROW(21, "Error initializing compression : %s", ZSTD_getErrorName(errorCode));
|
|
||||||
} }
|
|
||||||
|
|
||||||
/* Main compression loop */
|
/* Main compression loop */
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -380,8 +364,7 @@ static int FIO_compressFilename_internal(cRess_t ress,
|
|||||||
* 1 : missing or pb opening srcFileName
|
* 1 : missing or pb opening srcFileName
|
||||||
*/
|
*/
|
||||||
static int FIO_compressFilename_srcFile(cRess_t ress,
|
static int FIO_compressFilename_srcFile(cRess_t ress,
|
||||||
const char* dstFileName, const char* srcFileName,
|
const char* dstFileName, const char* srcFileName)
|
||||||
int cLevel)
|
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
@@ -393,10 +376,10 @@ static int FIO_compressFilename_srcFile(cRess_t ress,
|
|||||||
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);
|
||||||
|
|
||||||
fclose(ress.srcFile);
|
fclose(ress.srcFile);
|
||||||
if ((g_removeSrcFile) && (!result)) { if (remove(srcFileName)) EXM_THROW(1, "zstd: %s: %s", srcFileName, strerror(errno)); }
|
if (g_removeSrcFile && !result) { if (remove(srcFileName)) EXM_THROW(1, "zstd: %s: %s", srcFileName, strerror(errno)); } /* remove source file : --rm */
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,17 +389,16 @@ static int FIO_compressFilename_srcFile(cRess_t ress,
|
|||||||
* 1 : pb
|
* 1 : pb
|
||||||
*/
|
*/
|
||||||
static int FIO_compressFilename_dstFile(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 result;
|
int result;
|
||||||
|
|
||||||
ress.dstFile = FIO_openDstFile(dstFileName);
|
ress.dstFile = FIO_openDstFile(dstFileName);
|
||||||
if (ress.dstFile==0) return 1;
|
if (ress.dstFile==NULL) return 1; /* could not open dstFileName */
|
||||||
|
|
||||||
result = FIO_compressFilename_srcFile(ress, dstFileName, srcFileName, cLevel);
|
result = FIO_compressFilename_srcFile(ress, dstFileName, srcFileName);
|
||||||
|
|
||||||
if (fclose(ress.dstFile)) { DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno)); result=1; }
|
if (fclose(ress.dstFile)) { DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno)); result=1; } /* error closing dstFile */
|
||||||
if (result!=0) { if (remove(dstFileName)) EXM_THROW(1, "zstd: %s: %s", dstFileName, strerror(errno)); } /* remove operation artefact */
|
if (result!=0) { if (remove(dstFileName)) EXM_THROW(1, "zstd: %s: %s", dstFileName, strerror(errno)); } /* remove operation artefact */
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -426,9 +408,10 @@ int FIO_compressFilename(const char* dstFileName, const char* srcFileName,
|
|||||||
const char* dictFileName, int compressionLevel)
|
const char* dictFileName, int compressionLevel)
|
||||||
{
|
{
|
||||||
clock_t const start = clock();
|
clock_t const start = clock();
|
||||||
|
U64 const srcSize = UTIL_getFileSize(srcFileName);
|
||||||
|
|
||||||
cRess_t const ress = FIO_createCResources(dictFileName);
|
cRess_t const ress = FIO_createCResources(dictFileName, compressionLevel, srcSize);
|
||||||
int const result = FIO_compressFilename_dstFile(ress, dstFileName, srcFileName, compressionLevel);
|
int const result = FIO_compressFilename_dstFile(ress, dstFileName, srcFileName);
|
||||||
|
|
||||||
double const 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);
|
||||||
@@ -446,7 +429,8 @@ int FIO_compressMultipleFilenames(const char** inFileNamesTable, unsigned nbFile
|
|||||||
size_t dfnSize = FNSPACE;
|
size_t dfnSize = FNSPACE;
|
||||||
char* dstFileName = (char*)malloc(FNSPACE);
|
char* dstFileName = (char*)malloc(FNSPACE);
|
||||||
size_t const suffixSize = suffix ? strlen(suffix) : 0;
|
size_t const suffixSize = suffix ? strlen(suffix) : 0;
|
||||||
cRess_t ress = FIO_createCResources(dictFileName);
|
U64 const srcSize = (nbFiles != 1) ? 0 : UTIL_getFileSize(inFileNamesTable[0]) ;
|
||||||
|
cRess_t ress = FIO_createCResources(dictFileName, compressionLevel, srcSize);
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
if (dstFileName==NULL) EXM_THROW(27, "FIO_compressMultipleFilenames : allocation error for dstFileName");
|
if (dstFileName==NULL) EXM_THROW(27, "FIO_compressMultipleFilenames : allocation error for dstFileName");
|
||||||
@@ -458,8 +442,7 @@ int FIO_compressMultipleFilenames(const char** inFileNamesTable, unsigned nbFile
|
|||||||
ress.dstFile = stdout;
|
ress.dstFile = stdout;
|
||||||
SET_BINARY_MODE(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]);
|
||||||
inFileNamesTable[u], compressionLevel);
|
|
||||||
if (fclose(ress.dstFile)) EXM_THROW(29, "Write error : cannot properly close %s", stdoutmark);
|
if (fclose(ress.dstFile)) EXM_THROW(29, "Write error : cannot properly close %s", stdoutmark);
|
||||||
} else {
|
} else {
|
||||||
unsigned u;
|
unsigned u;
|
||||||
@@ -468,8 +451,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_dstFile(ress, dstFileName,
|
missed_files += FIO_compressFilename_dstFile(ress, dstFileName, inFileNamesTable[u]);
|
||||||
inFileNamesTable[u], compressionLevel);
|
|
||||||
} }
|
} }
|
||||||
|
|
||||||
/* Close & Free */
|
/* Close & Free */
|
||||||
@@ -493,8 +475,6 @@ typedef struct {
|
|||||||
size_t srcBufferSize;
|
size_t srcBufferSize;
|
||||||
void* dstBuffer;
|
void* dstBuffer;
|
||||||
size_t dstBufferSize;
|
size_t dstBufferSize;
|
||||||
void* dictBuffer;
|
|
||||||
size_t dictBufferSize;
|
|
||||||
ZSTD_DStream* dctx;
|
ZSTD_DStream* dctx;
|
||||||
FILE* dstFile;
|
FILE* dstFile;
|
||||||
} dRess_t;
|
} dRess_t;
|
||||||
@@ -514,7 +494,12 @@ static dRess_t FIO_createDResources(const char* dictFileName)
|
|||||||
if (!ress.srcBuffer || !ress.dstBuffer) EXM_THROW(61, "Allocation error : not enough memory");
|
if (!ress.srcBuffer || !ress.dstBuffer) EXM_THROW(61, "Allocation error : not enough memory");
|
||||||
|
|
||||||
/* dictionary */
|
/* dictionary */
|
||||||
ress.dictBufferSize = FIO_loadFile(&(ress.dictBuffer), dictFileName);
|
{ void* dictBuffer;
|
||||||
|
size_t const dictBufferSize = FIO_loadFile(&dictBuffer, dictFileName);
|
||||||
|
size_t const initError = ZSTD_initDStream_usingDict(ress.dctx, dictBuffer, dictBufferSize);
|
||||||
|
if (ZSTD_isError(initError)) EXM_THROW(61, "ZSTD_initDStream_usingDict error : %s", ZSTD_getErrorName(initError));
|
||||||
|
free(dictBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
return ress;
|
return ress;
|
||||||
}
|
}
|
||||||
@@ -525,7 +510,6 @@ static void FIO_freeDResources(dRess_t ress)
|
|||||||
if (ZSTD_isError(errorCode)) EXM_THROW(69, "Error : can't free ZSTD_DStream context resource : %s", ZSTD_getErrorName(errorCode));
|
if (ZSTD_isError(errorCode)) EXM_THROW(69, "Error : can't free ZSTD_DStream context resource : %s", ZSTD_getErrorName(errorCode));
|
||||||
free(ress.srcBuffer);
|
free(ress.srcBuffer);
|
||||||
free(ress.dstBuffer);
|
free(ress.dstBuffer);
|
||||||
free(ress.dictBuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -610,11 +594,11 @@ static void FIO_fwriteSparseEnd(FILE* file, unsigned storedSkips)
|
|||||||
unsigned long long FIO_decompressFrame(dRess_t ress,
|
unsigned long long FIO_decompressFrame(dRess_t ress,
|
||||||
FILE* foutput, FILE* finput, size_t alreadyLoaded)
|
FILE* foutput, FILE* finput, size_t alreadyLoaded)
|
||||||
{
|
{
|
||||||
U64 frameSize = 0;
|
U64 frameSize = 0;
|
||||||
size_t readSize;
|
size_t readSize;
|
||||||
U32 storedSkips = 0;
|
U32 storedSkips = 0;
|
||||||
|
|
||||||
ZSTD_initDStream_usingDict(ress.dctx, ress.dictBuffer, ress.dictBufferSize);
|
ZSTD_resetDStream(ress.dctx);
|
||||||
|
|
||||||
/* Header loading (optional, saves one loop) */
|
/* Header loading (optional, saves one loop) */
|
||||||
{ size_t const toLoad = 9 - alreadyLoaded; /* assumption : 9 >= alreadyLoaded */
|
{ size_t const toLoad = 9 - alreadyLoaded; /* assumption : 9 >= alreadyLoaded */
|
||||||
@@ -626,22 +610,22 @@ unsigned long long FIO_decompressFrame(dRess_t ress,
|
|||||||
while (1) {
|
while (1) {
|
||||||
ZSTD_inBuffer inBuff = { ress.srcBuffer, readSize, 0 };
|
ZSTD_inBuffer inBuff = { ress.srcBuffer, readSize, 0 };
|
||||||
ZSTD_outBuffer outBuff= { ress.dstBuffer, ress.dstBufferSize, 0 };
|
ZSTD_outBuffer outBuff= { ress.dstBuffer, ress.dstBufferSize, 0 };
|
||||||
size_t const toRead = ZSTD_decompressStream(ress.dctx, &outBuff, &inBuff );
|
size_t const readSizeHint = ZSTD_decompressStream(ress.dctx, &outBuff, &inBuff );
|
||||||
if (ZSTD_isError(toRead)) EXM_THROW(36, "Decoding error : %s", ZSTD_getErrorName(toRead));
|
if (ZSTD_isError(readSizeHint)) EXM_THROW(36, "Decoding error : %s", ZSTD_getErrorName(readSizeHint));
|
||||||
|
|
||||||
/* Write block */
|
/* Write block */
|
||||||
storedSkips = FIO_fwriteSparse(foutput, ress.dstBuffer, outBuff.pos, storedSkips);
|
storedSkips = FIO_fwriteSparse(foutput, ress.dstBuffer, outBuff.pos, storedSkips);
|
||||||
frameSize += outBuff.pos;
|
frameSize += outBuff.pos;
|
||||||
DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)(frameSize>>20) );
|
DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)(frameSize>>20) );
|
||||||
|
|
||||||
if (toRead == 0) break; /* end of frame */
|
if (readSizeHint == 0) break; /* end of frame */
|
||||||
if (inBuff.size != inBuff.pos) EXM_THROW(37, "Decoding error : should consume entire input");
|
if (inBuff.size != inBuff.pos) EXM_THROW(37, "Decoding error : should consume entire input");
|
||||||
|
|
||||||
/* Fill input buffer */
|
/* Fill input buffer */
|
||||||
if (toRead > ress.srcBufferSize) EXM_THROW(38, "too large block");
|
{ size_t const toRead = MIN(readSizeHint, ress.srcBufferSize); /* support large skippable frames */
|
||||||
readSize = fread(ress.srcBuffer, 1, toRead, finput);
|
readSize = fread(ress.srcBuffer, 1, toRead, finput);
|
||||||
if (readSize == 0) EXM_THROW(39, "Read error : premature end");
|
if (readSize < toRead) EXM_THROW(39, "Read error : premature end");
|
||||||
}
|
} }
|
||||||
|
|
||||||
FIO_fwriteSparseEnd(foutput, storedSkips);
|
FIO_fwriteSparseEnd(foutput, storedSkips);
|
||||||
|
|
||||||
@@ -699,16 +683,14 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName)
|
|||||||
if (readSomething==0) { DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */
|
if (readSomething==0) { DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */
|
||||||
break; /* no more input */
|
break; /* no more input */
|
||||||
}
|
}
|
||||||
readSomething = 1;
|
readSomething = 1; /* there is at least >= 4 bytes in srcFile */
|
||||||
if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */
|
if (sizeCheck != toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */
|
||||||
{ U32 const magic = MEM_readLE32(ress.srcBuffer);
|
{ U32 const magic = MEM_readLE32(ress.srcBuffer);
|
||||||
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
|
if (((magic & 0xFFFFFFF0U) != ZSTD_MAGIC_SKIPPABLE_START) & (magic != ZSTD_MAGICNUMBER)
|
||||||
if (ZSTD_isLegacy(ress.srcBuffer, 4)) {
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
|
||||||
filesize += FIO_decompressLegacyFrame(dstFile, srcFile, ress.dictBuffer, ress.dictBufferSize, magic);
|
& (!ZSTD_isLegacy(ress.srcBuffer, toRead))
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
if (((magic & 0xFFFFFFF0U) != ZSTD_MAGIC_SKIPPABLE_START) & (magic != ZSTD_MAGICNUMBER)) {
|
) {
|
||||||
if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */
|
if ((g_overwrite) && !strcmp (srcFileName, stdinmark)) { /* pass-through mode */
|
||||||
unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize);
|
unsigned const result = FIO_passThrough(dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize);
|
||||||
if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */
|
if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */
|
||||||
@@ -723,7 +705,7 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName)
|
|||||||
|
|
||||||
/* Final Status */
|
/* Final Status */
|
||||||
DISPLAYLEVEL(2, "\r%79s\r", "");
|
DISPLAYLEVEL(2, "\r%79s\r", "");
|
||||||
DISPLAYLEVEL(2, "%-20.20s: %llu bytes \n", srcFileName, filesize);
|
DISPLAYLEVEL(2, "%-20s: %llu bytes \n", srcFileName, filesize);
|
||||||
|
|
||||||
/* Close */
|
/* Close */
|
||||||
if (fclose(srcFile)) EXM_THROW(33, "zstd: %s close error", srcFileName); /* error should never happen */
|
if (fclose(srcFile)) EXM_THROW(33, "zstd: %s close error", srcFileName); /* error should never happen */
|
||||||
@@ -747,7 +729,10 @@ static int FIO_decompressDstFile(dRess_t ress,
|
|||||||
result = FIO_decompressSrcFile(ress, srcFileName);
|
result = FIO_decompressSrcFile(ress, srcFileName);
|
||||||
|
|
||||||
if (fclose(ress.dstFile)) EXM_THROW(38, "Write error : cannot properly close %s", dstFileName);
|
if (fclose(ress.dstFile)) EXM_THROW(38, "Write error : cannot properly close %s", dstFileName);
|
||||||
if (result != 0) if (remove(dstFileName)) result=1; /* don't do anything if remove fails */
|
if ( (result != 0)
|
||||||
|
&& strcmp(dstFileName, nulmark) /* special case : don't remove() /dev/null (#316) */
|
||||||
|
&& remove(dstFileName) )
|
||||||
|
result=1; /* don't do anything special if remove() fails */
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-23
@@ -1,27 +1,15 @@
|
|||||||
/*
|
/**
|
||||||
fileio.h - file i/o handler
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2013-2016
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
GPL v2 License
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
#ifndef FILEIO_H_23981798732
|
||||||
it under the terms of the GNU General Public License as published by
|
#define FILEIO_H_23981798732
|
||||||
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/
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -45,7 +33,6 @@ 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_setSparseWrite(unsigned sparse); /**< 0: no sparse; 1: disable on stdout; 2: always enabled */
|
void FIO_setSparseWrite(unsigned sparse); /**< 0: no sparse; 1: disable on stdout; 2: always enabled */
|
||||||
void FIO_setDictIDFlag(unsigned dictIDFlag);
|
void FIO_setDictIDFlag(unsigned dictIDFlag);
|
||||||
void FIO_setChecksumFlag(unsigned checksumFlag);
|
void FIO_setChecksumFlag(unsigned checksumFlag);
|
||||||
@@ -83,3 +70,5 @@ int FIO_decompressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles
|
|||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* FILEIO_H_23981798732 */
|
||||||
|
|||||||
@@ -1,673 +0,0 @@
|
|||||||
/*
|
|
||||||
fileio_legacy.c - File i/o handler for legacy format
|
|
||||||
Copyright (C) Yann Collet 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
|
|
||||||
- zstd source repository : https://github.com/Cyan4973/zstd
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
Note : this file is not part of ZSTD compression library.
|
|
||||||
The license of ZSTD library is BSD.
|
|
||||||
The license of this file is GPLv2.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* *************************************
|
|
||||||
* Compiler Options
|
|
||||||
***************************************/
|
|
||||||
/* Disable some Visual warning messages */
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
# define _CRT_SECURE_NO_WARNINGS
|
|
||||||
# define _CRT_SECURE_NO_DEPRECATE /* VS2005 */
|
|
||||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _FILE_OFFSET_BITS 64 /* Large file support on 32-bits unix */
|
|
||||||
#define _POSIX_SOURCE 1 /* enable fileno() within <stdio.h> on unix */
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
|
||||||
* Includes
|
|
||||||
***************************************/
|
|
||||||
#include <stdio.h> /* fprintf, fopen, fread, _fileno, stdin, stdout */
|
|
||||||
#include <stdlib.h> /* malloc, free */
|
|
||||||
#include <string.h> /* strcmp, strlen */
|
|
||||||
#include <time.h> /* clock */
|
|
||||||
#include <errno.h> /* errno */
|
|
||||||
#include "mem.h"
|
|
||||||
#include "fileio_legacy.h"
|
|
||||||
#include "zstd_legacy.h" /* legacy support */
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
|
||||||
* OS-specific Includes
|
|
||||||
***************************************/
|
|
||||||
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
|
|
||||||
# include <fcntl.h> /* _O_BINARY */
|
|
||||||
# include <io.h> /* _setmode, _isatty */
|
|
||||||
# ifdef __MINGW32__
|
|
||||||
/* int _fileno(FILE *stream); // seems no longer useful // MINGW somehow forgets to include this windows declaration into <stdio.h> */
|
|
||||||
# endif
|
|
||||||
# define SET_BINARY_MODE(file) { int unused = _setmode(_fileno(file), _O_BINARY); (void)unused; }
|
|
||||||
# define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream))
|
|
||||||
#else
|
|
||||||
# include <unistd.h> /* isatty */
|
|
||||||
# define SET_BINARY_MODE(file)
|
|
||||||
# define IS_CONSOLE(stdStream) isatty(fileno(stdStream))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
|
||||||
* Constants
|
|
||||||
***************************************/
|
|
||||||
#define KB *(1U<<10)
|
|
||||||
#define MB *(1U<<20)
|
|
||||||
#define GB *(1U<<30)
|
|
||||||
|
|
||||||
#define _1BIT 0x01
|
|
||||||
#define _2BITS 0x03
|
|
||||||
#define _3BITS 0x07
|
|
||||||
#define _4BITS 0x0F
|
|
||||||
#define _6BITS 0x3F
|
|
||||||
#define _8BITS 0xFF
|
|
||||||
|
|
||||||
#define BIT6 0x40
|
|
||||||
#define BIT7 0x80
|
|
||||||
|
|
||||||
#define FIO_FRAMEHEADERSIZE 5 /* as a define, because needed to allocated table on stack */
|
|
||||||
#define FSE_CHECKSUM_SEED 0
|
|
||||||
|
|
||||||
#define CACHELINE 64
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
|
||||||
* Macros
|
|
||||||
***************************************/
|
|
||||||
#define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
|
|
||||||
#define DISPLAYLEVEL(l, ...) if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); }
|
|
||||||
static U32 g_displayLevel = 1; /* 0 : no display; 1: errors; 2 : + result + interaction + warnings; 3 : + progression; 4 : + information */
|
|
||||||
|
|
||||||
#define DISPLAYUPDATE(l, ...) if (g_displayLevel>=l) { \
|
|
||||||
if ((FIO_GetMilliSpan(g_time) > refreshRate) || (g_displayLevel>=4)) \
|
|
||||||
{ g_time = clock(); DISPLAY(__VA_ARGS__); \
|
|
||||||
if (g_displayLevel>=4) fflush(stdout); } }
|
|
||||||
static const unsigned refreshRate = 150;
|
|
||||||
static clock_t g_time = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
|
||||||
* Local Parameters
|
|
||||||
***************************************/
|
|
||||||
void FIO_legacy_setNotificationLevel(unsigned level) { g_displayLevel=level; }
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
|
||||||
* Exceptions
|
|
||||||
***************************************/
|
|
||||||
#ifndef DEBUG
|
|
||||||
# define DEBUG 0
|
|
||||||
#endif
|
|
||||||
#define DEBUGOUTPUT(...) if (DEBUG) DISPLAY(__VA_ARGS__);
|
|
||||||
#define EXM_THROW(error, ...) \
|
|
||||||
{ \
|
|
||||||
DEBUGOUTPUT("Error defined at %s, line %i : \n", __FILE__, __LINE__); \
|
|
||||||
DISPLAYLEVEL(1, "Error %i : ", error); \
|
|
||||||
DISPLAYLEVEL(1, __VA_ARGS__); \
|
|
||||||
DISPLAYLEVEL(1, "\n"); \
|
|
||||||
exit(error); \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
|
||||||
* Functions
|
|
||||||
***************************************/
|
|
||||||
static unsigned FIO_GetMilliSpan(clock_t nPrevious)
|
|
||||||
{
|
|
||||||
clock_t nCurrent = clock();
|
|
||||||
unsigned nSpan = (unsigned)(((nCurrent - nPrevious) * 1000) / CLOCKS_PER_SEC);
|
|
||||||
return nSpan;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned long long FIOv01_decompressFrame(FILE* foutput, FILE* finput)
|
|
||||||
{
|
|
||||||
size_t const outBuffSize = 512 KB;
|
|
||||||
BYTE* outBuff = (BYTE*)malloc(outBuffSize);
|
|
||||||
size_t inBuffSize = 128 KB + 8;
|
|
||||||
BYTE inBuff[128 KB + 8];
|
|
||||||
BYTE* op = outBuff;
|
|
||||||
BYTE* const oend = outBuff + outBuffSize;
|
|
||||||
U64 filesize = 0;
|
|
||||||
size_t toRead;
|
|
||||||
size_t sizeCheck;
|
|
||||||
ZSTDv01_Dctx* dctx = ZSTDv01_createDCtx();
|
|
||||||
|
|
||||||
|
|
||||||
/* init */
|
|
||||||
if (outBuff==NULL) EXM_THROW(41, "Error : not enough memory to decode legacy frame");
|
|
||||||
|
|
||||||
/* restore header, already read from input */
|
|
||||||
MEM_writeLE32(inBuff, ZSTDv01_magicNumberLE);
|
|
||||||
sizeCheck = ZSTDv01_decompressContinue(dctx, NULL, 0, inBuff, sizeof(ZSTDv01_magicNumberLE)); /* Decode frame header */
|
|
||||||
if (ZSTDv01_isError(sizeCheck)) EXM_THROW(42, "Error decoding legacy header");
|
|
||||||
|
|
||||||
/* Main decompression Loop */
|
|
||||||
toRead = ZSTDv01_nextSrcSizeToDecompress(dctx);
|
|
||||||
while (toRead){
|
|
||||||
size_t readSize, decodedSize;
|
|
||||||
|
|
||||||
/* Fill input buffer */
|
|
||||||
if (toRead > inBuffSize)
|
|
||||||
EXM_THROW(43, "too large block");
|
|
||||||
readSize = fread(inBuff, 1, toRead, finput);
|
|
||||||
if (readSize != toRead)
|
|
||||||
EXM_THROW(44, "Read error");
|
|
||||||
|
|
||||||
/* Decode block */
|
|
||||||
decodedSize = ZSTDv01_decompressContinue(dctx, op, oend-op, inBuff, readSize);
|
|
||||||
if (ZSTDv01_isError(decodedSize)) EXM_THROW(45, "Decoding error : input corrupted");
|
|
||||||
|
|
||||||
if (decodedSize) { /* not a header */
|
|
||||||
/* Write block */
|
|
||||||
sizeCheck = fwrite(op, 1, decodedSize, foutput);
|
|
||||||
if (sizeCheck != decodedSize) EXM_THROW(46, "Write error : unable to write data block to destination file");
|
|
||||||
filesize += decodedSize;
|
|
||||||
op += decodedSize;
|
|
||||||
if (op==oend) op = outBuff;
|
|
||||||
DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)(filesize>>20) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* prepare for next Block */
|
|
||||||
toRead = ZSTDv01_nextSrcSizeToDecompress(dctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* release resources */
|
|
||||||
free(outBuff);
|
|
||||||
free(dctx);
|
|
||||||
return filesize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned long long FIOv02_decompressFrame(FILE* foutput, FILE* finput)
|
|
||||||
{
|
|
||||||
size_t const outBuffSize = 512 KB;
|
|
||||||
BYTE* outBuff = (BYTE*)malloc(outBuffSize);
|
|
||||||
size_t inBuffSize = 128 KB + 8;
|
|
||||||
BYTE inBuff[128 KB + 8];
|
|
||||||
BYTE* op = outBuff;
|
|
||||||
BYTE* const oend = outBuff + outBuffSize;
|
|
||||||
U64 filesize = 0;
|
|
||||||
size_t toRead;
|
|
||||||
size_t sizeCheck;
|
|
||||||
ZSTDv02_Dctx* dctx = ZSTDv02_createDCtx();
|
|
||||||
|
|
||||||
/* init */
|
|
||||||
if (outBuff==NULL) EXM_THROW(41, "Error : not enough memory to decode legacy frame");
|
|
||||||
|
|
||||||
/* restore header, already read from input */
|
|
||||||
MEM_writeLE32(inBuff, ZSTDv02_magicNumber);
|
|
||||||
sizeCheck = ZSTDv02_decompressContinue(dctx, NULL, 0, inBuff, sizeof(ZSTDv02_magicNumber)); /* Decode frame header */
|
|
||||||
if (ZSTDv02_isError(sizeCheck)) EXM_THROW(42, "Error decoding legacy header");
|
|
||||||
|
|
||||||
/* Main decompression Loop */
|
|
||||||
toRead = ZSTDv02_nextSrcSizeToDecompress(dctx);
|
|
||||||
while (toRead) {
|
|
||||||
size_t readSize, decodedSize;
|
|
||||||
|
|
||||||
/* Fill input buffer */
|
|
||||||
if (toRead > inBuffSize)
|
|
||||||
EXM_THROW(43, "too large block");
|
|
||||||
readSize = fread(inBuff, 1, toRead, finput);
|
|
||||||
if (readSize != toRead)
|
|
||||||
EXM_THROW(44, "Read error");
|
|
||||||
|
|
||||||
/* Decode block */
|
|
||||||
decodedSize = ZSTDv02_decompressContinue(dctx, op, oend-op, inBuff, readSize);
|
|
||||||
if (ZSTDv02_isError(decodedSize)) EXM_THROW(45, "Decoding error : input corrupted");
|
|
||||||
|
|
||||||
if (decodedSize) { /* not a header */
|
|
||||||
/* Write block */
|
|
||||||
sizeCheck = fwrite(op, 1, decodedSize, foutput);
|
|
||||||
if (sizeCheck != decodedSize) EXM_THROW(46, "Write error : unable to write data block to destination file");
|
|
||||||
filesize += decodedSize;
|
|
||||||
op += decodedSize;
|
|
||||||
if (op==oend) op = outBuff;
|
|
||||||
DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)(filesize>>20) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* prepare for next Block */
|
|
||||||
toRead = ZSTDv02_nextSrcSizeToDecompress(dctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* release resources */
|
|
||||||
free(outBuff);
|
|
||||||
free(dctx);
|
|
||||||
return filesize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned long long FIOv03_decompressFrame(FILE* foutput, FILE* finput)
|
|
||||||
{
|
|
||||||
size_t const outBuffSize = 512 KB;
|
|
||||||
BYTE* outBuff = (BYTE*)malloc(outBuffSize);
|
|
||||||
size_t inBuffSize = 128 KB + 8;
|
|
||||||
BYTE inBuff[128 KB + 8];
|
|
||||||
BYTE* op = outBuff;
|
|
||||||
BYTE* const oend = outBuff + outBuffSize;
|
|
||||||
U64 filesize = 0;
|
|
||||||
size_t toRead;
|
|
||||||
size_t sizeCheck;
|
|
||||||
ZSTDv03_Dctx* dctx = ZSTDv03_createDCtx();
|
|
||||||
|
|
||||||
/* init */
|
|
||||||
if (outBuff==NULL) EXM_THROW(41, "Error : not enough memory to decode legacy frame");
|
|
||||||
|
|
||||||
/* restore header, already read from input */
|
|
||||||
MEM_writeLE32(inBuff, ZSTDv03_magicNumber);
|
|
||||||
sizeCheck = ZSTDv03_decompressContinue(dctx, NULL, 0, inBuff, sizeof(ZSTDv03_magicNumber)); /* Decode frame header */
|
|
||||||
if (ZSTDv03_isError(sizeCheck)) EXM_THROW(42, "Error decoding legacy header");
|
|
||||||
|
|
||||||
/* Main decompression Loop */
|
|
||||||
toRead = ZSTDv03_nextSrcSizeToDecompress(dctx);
|
|
||||||
while (toRead) {
|
|
||||||
size_t readSize, decodedSize;
|
|
||||||
|
|
||||||
/* Fill input buffer */
|
|
||||||
if (toRead > inBuffSize)
|
|
||||||
EXM_THROW(43, "too large block");
|
|
||||||
readSize = fread(inBuff, 1, toRead, finput);
|
|
||||||
if (readSize != toRead)
|
|
||||||
EXM_THROW(44, "Read error");
|
|
||||||
|
|
||||||
/* Decode block */
|
|
||||||
decodedSize = ZSTDv03_decompressContinue(dctx, op, oend-op, inBuff, readSize);
|
|
||||||
if (ZSTDv03_isError(decodedSize)) EXM_THROW(45, "Decoding error : input corrupted");
|
|
||||||
|
|
||||||
if (decodedSize) { /* not a header */
|
|
||||||
/* Write block */
|
|
||||||
sizeCheck = fwrite(op, 1, decodedSize, foutput);
|
|
||||||
if (sizeCheck != decodedSize) EXM_THROW(46, "Write error : unable to write data block to destination file");
|
|
||||||
filesize += decodedSize;
|
|
||||||
op += decodedSize;
|
|
||||||
if (op==oend) op = outBuff;
|
|
||||||
DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)(filesize>>20) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* prepare for next Block */
|
|
||||||
toRead = ZSTDv03_nextSrcSizeToDecompress(dctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* release resources */
|
|
||||||
free(outBuff);
|
|
||||||
free(dctx);
|
|
||||||
return filesize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*===== v0.4.x =====*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
void* srcBuffer;
|
|
||||||
size_t srcBufferSize;
|
|
||||||
void* dstBuffer;
|
|
||||||
size_t dstBufferSize;
|
|
||||||
void* dictBuffer;
|
|
||||||
size_t dictBufferSize;
|
|
||||||
ZBUFFv04_DCtx* dctx;
|
|
||||||
} dRessv04_t;
|
|
||||||
|
|
||||||
static dRessv04_t FIOv04_createDResources(void)
|
|
||||||
{
|
|
||||||
dRessv04_t ress;
|
|
||||||
|
|
||||||
/* init */
|
|
||||||
ress.dctx = ZBUFFv04_createDCtx();
|
|
||||||
if (ress.dctx==NULL) EXM_THROW(60, "Can't create ZBUFF decompression context");
|
|
||||||
ress.dictBuffer = NULL; ress.dictBufferSize=0;
|
|
||||||
|
|
||||||
/* Allocate Memory */
|
|
||||||
ress.srcBufferSize = ZBUFFv04_recommendedDInSize();
|
|
||||||
ress.srcBuffer = malloc(ress.srcBufferSize);
|
|
||||||
ress.dstBufferSize = ZBUFFv04_recommendedDOutSize();
|
|
||||||
ress.dstBuffer = malloc(ress.dstBufferSize);
|
|
||||||
if (!ress.srcBuffer || !ress.dstBuffer) EXM_THROW(61, "Allocation error : not enough memory");
|
|
||||||
|
|
||||||
return ress;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FIOv04_freeDResources(dRessv04_t ress)
|
|
||||||
{
|
|
||||||
size_t errorCode = ZBUFFv04_freeDCtx(ress.dctx);
|
|
||||||
if (ZBUFFv04_isError(errorCode)) EXM_THROW(69, "Error : can't free ZBUFF context resource : %s", ZBUFFv04_getErrorName(errorCode));
|
|
||||||
free(ress.srcBuffer);
|
|
||||||
free(ress.dstBuffer);
|
|
||||||
free(ress.dictBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned long long FIOv04_decompressFrame(dRessv04_t ress,
|
|
||||||
FILE* foutput, FILE* finput)
|
|
||||||
{
|
|
||||||
U64 frameSize = 0;
|
|
||||||
size_t readSize = 4;
|
|
||||||
|
|
||||||
MEM_writeLE32(ress.srcBuffer, ZSTDv04_magicNumber);
|
|
||||||
ZBUFFv04_decompressInit(ress.dctx);
|
|
||||||
ZBUFFv04_decompressWithDictionary(ress.dctx, ress.dictBuffer, ress.dictBufferSize);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
/* Decode */
|
|
||||||
size_t sizeCheck;
|
|
||||||
size_t inSize=readSize, decodedSize=ress.dstBufferSize;
|
|
||||||
size_t toRead = ZBUFFv04_decompressContinue(ress.dctx, ress.dstBuffer, &decodedSize, ress.srcBuffer, &inSize);
|
|
||||||
if (ZBUFFv04_isError(toRead)) EXM_THROW(36, "Decoding error : %s", ZBUFFv04_getErrorName(toRead));
|
|
||||||
readSize -= inSize;
|
|
||||||
|
|
||||||
/* Write block */
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*===== v0.5.x =====*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
void* srcBuffer;
|
|
||||||
size_t srcBufferSize;
|
|
||||||
void* dstBuffer;
|
|
||||||
size_t dstBufferSize;
|
|
||||||
const void* dictBuffer;
|
|
||||||
size_t dictBufferSize;
|
|
||||||
ZBUFFv05_DCtx* dctx;
|
|
||||||
} dRessv05_t;
|
|
||||||
|
|
||||||
static dRessv05_t FIOv05_createDResources(void)
|
|
||||||
{
|
|
||||||
dRessv05_t ress;
|
|
||||||
|
|
||||||
/* init */
|
|
||||||
ress.dctx = ZBUFFv05_createDCtx();
|
|
||||||
if (ress.dctx==NULL) EXM_THROW(60, "Can't create ZBUFF decompression context");
|
|
||||||
ress.dictBuffer = NULL; ress.dictBufferSize=0;
|
|
||||||
|
|
||||||
/* Allocate Memory */
|
|
||||||
ress.srcBufferSize = ZBUFFv05_recommendedDInSize();
|
|
||||||
ress.srcBuffer = malloc(ress.srcBufferSize);
|
|
||||||
ress.dstBufferSize = ZBUFFv05_recommendedDOutSize();
|
|
||||||
ress.dstBuffer = malloc(ress.dstBufferSize);
|
|
||||||
if (!ress.srcBuffer || !ress.dstBuffer) EXM_THROW(61, "Allocation error : not enough memory");
|
|
||||||
|
|
||||||
return ress;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FIOv05_freeDResources(dRessv05_t ress)
|
|
||||||
{
|
|
||||||
size_t const errorCode = ZBUFFv05_freeDCtx(ress.dctx);
|
|
||||||
if (ZBUFFv05_isError(errorCode)) EXM_THROW(69, "Error : can't free ZBUFF context resource : %s", ZBUFFv05_getErrorName(errorCode));
|
|
||||||
free(ress.srcBuffer);
|
|
||||||
free(ress.dstBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned long long FIOv05_decompressFrame(dRessv05_t ress,
|
|
||||||
FILE* foutput, FILE* finput)
|
|
||||||
{
|
|
||||||
U64 frameSize = 0;
|
|
||||||
size_t readSize = 4;
|
|
||||||
|
|
||||||
MEM_writeLE32(ress.srcBuffer, ZSTDv05_MAGICNUMBER);
|
|
||||||
ZBUFFv05_decompressInitDictionary(ress.dctx, ress.dictBuffer, ress.dictBufferSize);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
/* Decode */
|
|
||||||
size_t inSize=readSize, decodedSize=ress.dstBufferSize;
|
|
||||||
size_t toRead = ZBUFFv05_decompressContinue(ress.dctx, ress.dstBuffer, &decodedSize, ress.srcBuffer, &inSize);
|
|
||||||
if (ZBUFFv05_isError(toRead)) EXM_THROW(36, "Decoding error : %s", ZBUFFv05_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*===== 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*===== v0.7.x =====*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
void* srcBuffer;
|
|
||||||
size_t srcBufferSize;
|
|
||||||
void* dstBuffer;
|
|
||||||
size_t dstBufferSize;
|
|
||||||
const void* dictBuffer;
|
|
||||||
size_t dictBufferSize;
|
|
||||||
ZBUFFv07_DCtx* dctx;
|
|
||||||
} dRessv07_t;
|
|
||||||
|
|
||||||
static dRessv07_t FIOv07_createDResources(void)
|
|
||||||
{
|
|
||||||
dRessv07_t ress;
|
|
||||||
|
|
||||||
/* init */
|
|
||||||
ress.dctx = ZBUFFv07_createDCtx();
|
|
||||||
if (ress.dctx==NULL) EXM_THROW(60, "Can't create ZBUFF decompression context");
|
|
||||||
ress.dictBuffer = NULL; ress.dictBufferSize=0;
|
|
||||||
|
|
||||||
/* Allocate Memory */
|
|
||||||
ress.srcBufferSize = ZBUFFv07_recommendedDInSize();
|
|
||||||
ress.srcBuffer = malloc(ress.srcBufferSize);
|
|
||||||
ress.dstBufferSize = ZBUFFv07_recommendedDOutSize();
|
|
||||||
ress.dstBuffer = malloc(ress.dstBufferSize);
|
|
||||||
if (!ress.srcBuffer || !ress.dstBuffer) EXM_THROW(61, "Allocation error : not enough memory");
|
|
||||||
|
|
||||||
return ress;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FIOv07_freeDResources(dRessv07_t ress)
|
|
||||||
{
|
|
||||||
size_t const errorCode = ZBUFFv07_freeDCtx(ress.dctx);
|
|
||||||
if (ZBUFFv07_isError(errorCode)) EXM_THROW(69, "Error : can't free ZBUFF context resource : %s", ZBUFFv07_getErrorName(errorCode));
|
|
||||||
free(ress.srcBuffer);
|
|
||||||
free(ress.dstBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned long long FIOv07_decompressFrame(dRessv07_t ress,
|
|
||||||
FILE* foutput, FILE* finput)
|
|
||||||
{
|
|
||||||
U64 frameSize = 0;
|
|
||||||
size_t readSize = 4;
|
|
||||||
|
|
||||||
MEM_writeLE32(ress.srcBuffer, ZSTDv07_MAGICNUMBER);
|
|
||||||
ZBUFFv07_decompressInitDictionary(ress.dctx, ress.dictBuffer, ress.dictBufferSize);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
/* Decode */
|
|
||||||
size_t inSize=readSize, decodedSize=ress.dstBufferSize;
|
|
||||||
size_t toRead = ZBUFFv07_decompressContinue(ress.dctx, ress.dstBuffer, &decodedSize, ress.srcBuffer, &inSize);
|
|
||||||
if (ZBUFFv07_isError(toRead)) EXM_THROW(36, "Decoding error : %s", ZBUFFv07_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 =====*/
|
|
||||||
|
|
||||||
unsigned long long FIO_decompressLegacyFrame(FILE* foutput, FILE* finput,
|
|
||||||
const void* dictBuffer, size_t dictSize,
|
|
||||||
U32 magicNumberLE)
|
|
||||||
{
|
|
||||||
switch(magicNumberLE)
|
|
||||||
{
|
|
||||||
case ZSTDv01_magicNumberLE :
|
|
||||||
return FIOv01_decompressFrame(foutput, finput);
|
|
||||||
case ZSTDv02_magicNumber :
|
|
||||||
return FIOv02_decompressFrame(foutput, finput);
|
|
||||||
case ZSTDv03_magicNumber :
|
|
||||||
return FIOv03_decompressFrame(foutput, finput);
|
|
||||||
case ZSTDv04_magicNumber :
|
|
||||||
{ dRessv04_t r = FIOv04_createDResources();
|
|
||||||
unsigned long long const s = FIOv04_decompressFrame(r, foutput, finput);
|
|
||||||
FIOv04_freeDResources(r);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
case ZSTDv05_MAGICNUMBER :
|
|
||||||
{ dRessv05_t r = FIOv05_createDResources();
|
|
||||||
r.dictBuffer = dictBuffer;
|
|
||||||
r.dictBufferSize = dictSize;
|
|
||||||
{ unsigned long long const s = FIOv05_decompressFrame(r, foutput, finput);
|
|
||||||
FIOv05_freeDResources(r);
|
|
||||||
return s;
|
|
||||||
} }
|
|
||||||
case ZSTDv06_MAGICNUMBER :
|
|
||||||
{ 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;
|
|
||||||
} }
|
|
||||||
case ZSTDv07_MAGICNUMBER :
|
|
||||||
{ dRessv07_t r = FIOv07_createDResources();
|
|
||||||
r.dictBuffer = dictBuffer;
|
|
||||||
r.dictBufferSize = dictSize;
|
|
||||||
{ unsigned long long const s = FIOv07_decompressFrame(r, foutput, finput);
|
|
||||||
FIOv07_freeDResources(r);
|
|
||||||
return s;
|
|
||||||
} }
|
|
||||||
default :
|
|
||||||
return ERROR(prefix_unknown);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
fileio.h - file i/o handler
|
|
||||||
Copyright (C) Yann Collet 2013-2015
|
|
||||||
|
|
||||||
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 source repository : https://github.com/Cyan4973/zstd
|
|
||||||
- Public forum : https://groups.google.com/forum/#!forum/lz4c
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
|
||||||
* Parameters
|
|
||||||
***************************************/
|
|
||||||
void FIO_legacy_setNotificationLevel(unsigned level);
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
|
||||||
* Stream/File functions
|
|
||||||
***************************************/
|
|
||||||
unsigned long long FIO_decompressLegacyFrame(FILE* foutput, FILE* finput,
|
|
||||||
const void* dictBuffer, size_t dictSize,
|
|
||||||
U32 magicNumberLE);
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
+71
-63
@@ -1,26 +1,12 @@
|
|||||||
/* ******************************************************************
|
/**
|
||||||
util.h - utility functions
|
* Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) 2016, Przemyslaw Skibinski, Yann Collet.
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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/
|
|
||||||
*/
|
|
||||||
#ifndef UTIL_H_MODULE
|
#ifndef UTIL_H_MODULE
|
||||||
#define UTIL_H_MODULE
|
#define UTIL_H_MODULE
|
||||||
|
|
||||||
@@ -45,12 +31,12 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
/* Unix Large Files support (>4GB) */
|
/* Unix Large Files support (>4GB) */
|
||||||
#if !defined(__LP64__) /* No point defining Large file for 64 bit */
|
#if !defined(__LP64__) /* No point defining Large file for 64 bit */
|
||||||
# define _FILE_OFFSET_BITS 64 /* turn off_t into a 64-bit type for ftello, fseeko */
|
# define _FILE_OFFSET_BITS 64 /* turn off_t into a 64-bit type for ftello, fseeko */
|
||||||
# if defined(__sun__) /* Sun Solaris 32-bits requires specific definitions */
|
# if defined(__sun__) && !defined(_LARGEFILE_SOURCE) /* Sun Solaris 32-bits requires specific definitions */
|
||||||
# define _LARGEFILE_SOURCE /* fseeko, ftello */
|
# define _LARGEFILE_SOURCE /* fseeko, ftello */
|
||||||
# else
|
# elif !defined(_LARGEFILE64_SOURCE)
|
||||||
# define _LARGEFILE64_SOURCE /* off64_t, fseeko64, ftello64 */
|
# define _LARGEFILE64_SOURCE /* off64_t, fseeko64, ftello64 */
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -213,108 +199,131 @@ UTIL_STATIC U32 UTIL_isDirectory(const char* infilename)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A modified version of realloc().
|
||||||
|
* If UTIL_realloc() fails the original block is freed.
|
||||||
|
*/
|
||||||
|
UTIL_STATIC void *UTIL_realloc(void *ptr, size_t size)
|
||||||
|
{
|
||||||
|
void *newptr = realloc(ptr, size);
|
||||||
|
if (newptr) return newptr;
|
||||||
|
free(ptr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# define UTIL_HAS_CREATEFILELIST
|
# define UTIL_HAS_CREATEFILELIST
|
||||||
|
|
||||||
UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char** bufStart, size_t* pos, char** bufEnd)
|
UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char** bufStart, size_t* pos, char** bufEnd)
|
||||||
{
|
{
|
||||||
char path[MAX_PATH];
|
char* path;
|
||||||
int pathLength, nbFiles = 0;
|
int dirLength, fnameLength, pathLength, nbFiles = 0;
|
||||||
WIN32_FIND_DATA cFile;
|
WIN32_FIND_DATA cFile;
|
||||||
HANDLE hFile;
|
HANDLE hFile;
|
||||||
|
|
||||||
pathLength = snprintf(path, MAX_PATH, "%s\\*", dirName);
|
dirLength = (int)strlen(dirName);
|
||||||
if (pathLength < 0 || pathLength >= MAX_PATH) {
|
path = (char*) malloc(dirLength + 3);
|
||||||
fprintf(stderr, "Path length has got too long.\n");
|
if (!path) return 0;
|
||||||
return 0;
|
|
||||||
}
|
memcpy(path, dirName, dirLength);
|
||||||
|
path[dirLength] = '\\';
|
||||||
|
path[dirLength+1] = '*';
|
||||||
|
path[dirLength+2] = 0;
|
||||||
|
|
||||||
hFile=FindFirstFile(path, &cFile);
|
hFile=FindFirstFile(path, &cFile);
|
||||||
if (hFile == INVALID_HANDLE_VALUE) {
|
if (hFile == INVALID_HANDLE_VALUE) {
|
||||||
fprintf(stderr, "Cannot open directory '%s'\n", dirName);
|
fprintf(stderr, "Cannot open directory '%s'\n", dirName);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
free(path);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
pathLength = snprintf(path, MAX_PATH, "%s\\%s", dirName, cFile.cFileName);
|
fnameLength = (int)strlen(cFile.cFileName);
|
||||||
if (pathLength < 0 || pathLength >= MAX_PATH) {
|
path = (char*) malloc(dirLength + fnameLength + 2);
|
||||||
fprintf(stderr, "Path length has got too long.\n");
|
if (!path) { FindClose(hFile); return 0; }
|
||||||
continue;
|
memcpy(path, dirName, dirLength);
|
||||||
}
|
path[dirLength] = '\\';
|
||||||
|
memcpy(path+dirLength+1, cFile.cFileName, fnameLength);
|
||||||
|
pathLength = dirLength+1+fnameLength;
|
||||||
|
path[pathLength] = 0;
|
||||||
if (cFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
if (cFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
if (strcmp (cFile.cFileName, "..") == 0 ||
|
if (strcmp (cFile.cFileName, "..") == 0 ||
|
||||||
strcmp (cFile.cFileName, ".") == 0) continue;
|
strcmp (cFile.cFileName, ".") == 0) continue;
|
||||||
// printf ("[%s]\n", path);
|
|
||||||
nbFiles += UTIL_prepareFileList(path, bufStart, pos, bufEnd); /* Recursively call "UTIL_prepareFileList" with the new path. */
|
nbFiles += UTIL_prepareFileList(path, bufStart, pos, bufEnd); /* Recursively call "UTIL_prepareFileList" with the new path. */
|
||||||
if (*bufStart == NULL) { FindClose(hFile); return 0; }
|
if (*bufStart == NULL) { free(path); FindClose(hFile); return 0; }
|
||||||
}
|
}
|
||||||
else if ((cFile.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) || (cFile.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) || (cFile.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)) {
|
else if ((cFile.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) || (cFile.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) || (cFile.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)) {
|
||||||
if (*bufStart + *pos + pathLength >= *bufEnd) {
|
if (*bufStart + *pos + pathLength >= *bufEnd) {
|
||||||
ptrdiff_t newListSize = (*bufEnd - *bufStart) + LIST_SIZE_INCREASE;
|
ptrdiff_t newListSize = (*bufEnd - *bufStart) + LIST_SIZE_INCREASE;
|
||||||
*bufStart = (char*)realloc(*bufStart, newListSize);
|
*bufStart = (char*)UTIL_realloc(*bufStart, newListSize);
|
||||||
*bufEnd = *bufStart + newListSize;
|
*bufEnd = *bufStart + newListSize;
|
||||||
if (*bufStart == NULL) { FindClose(hFile); return 0; }
|
if (*bufStart == NULL) { free(path); FindClose(hFile); return 0; }
|
||||||
}
|
}
|
||||||
if (*bufStart + *pos + pathLength < *bufEnd) {
|
if (*bufStart + *pos + pathLength < *bufEnd) {
|
||||||
strncpy(*bufStart + *pos, path, *bufEnd - (*bufStart + *pos));
|
strncpy(*bufStart + *pos, path, *bufEnd - (*bufStart + *pos));
|
||||||
*pos += pathLength + 1;
|
*pos += pathLength + 1;
|
||||||
nbFiles++;
|
nbFiles++;
|
||||||
}
|
}
|
||||||
// printf ("%s\\%s nbFiles=%d left=%d\n", dirName, cFile.cFileName, nbFiles, (int)(bufEnd - *bufStart));
|
|
||||||
}
|
}
|
||||||
|
free(path);
|
||||||
} while (FindNextFile(hFile, &cFile));
|
} while (FindNextFile(hFile, &cFile));
|
||||||
|
|
||||||
FindClose(hFile);
|
FindClose(hFile);
|
||||||
return nbFiles;
|
return nbFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif (defined(__unix__) || defined(__unix) || defined(__midipix__) || (defined(__APPLE__) && defined(__MACH__))) && defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) /* snprintf, opendir */
|
#elif (defined(__APPLE__) && defined(__MACH__)) || \
|
||||||
|
((defined(__unix__) || defined(__unix) || defined(__midipix__)) && defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) /* snprintf, opendir */
|
||||||
# define UTIL_HAS_CREATEFILELIST
|
# define UTIL_HAS_CREATEFILELIST
|
||||||
# include <dirent.h> /* opendir, readdir */
|
# include <dirent.h> /* opendir, readdir */
|
||||||
# include <limits.h> /* PATH_MAX */
|
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
|
|
||||||
UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char** bufStart, size_t* pos, char** bufEnd)
|
UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char** bufStart, size_t* pos, char** bufEnd)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
char path[PATH_MAX];
|
char* path;
|
||||||
int pathLength, nbFiles = 0;
|
int dirLength, fnameLength, pathLength, nbFiles = 0;
|
||||||
|
|
||||||
if (!(dir = opendir(dirName))) {
|
if (!(dir = opendir(dirName))) {
|
||||||
fprintf(stderr, "Cannot open directory '%s': %s\n", dirName, strerror(errno));
|
fprintf(stderr, "Cannot open directory '%s': %s\n", dirName, strerror(errno));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dirLength = (int)strlen(dirName);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
while ((entry = readdir(dir)) != NULL) {
|
||||||
if (strcmp (entry->d_name, "..") == 0 ||
|
if (strcmp (entry->d_name, "..") == 0 ||
|
||||||
strcmp (entry->d_name, ".") == 0) continue;
|
strcmp (entry->d_name, ".") == 0) continue;
|
||||||
pathLength = snprintf(path, PATH_MAX, "%s/%s", dirName, entry->d_name);
|
fnameLength = (int)strlen(entry->d_name);
|
||||||
if (pathLength < 0 || pathLength >= PATH_MAX) {
|
path = (char*) malloc(dirLength + fnameLength + 2);
|
||||||
fprintf(stderr, "Path length has got too long.\n");
|
if (!path) { closedir(dir); return 0; }
|
||||||
continue;
|
memcpy(path, dirName, dirLength);
|
||||||
}
|
path[dirLength] = '/';
|
||||||
|
memcpy(path+dirLength+1, entry->d_name, fnameLength);
|
||||||
|
pathLength = dirLength+1+fnameLength;
|
||||||
|
path[pathLength] = 0;
|
||||||
|
|
||||||
if (UTIL_isDirectory(path)) {
|
if (UTIL_isDirectory(path)) {
|
||||||
// printf ("[%s]\n", path);
|
|
||||||
nbFiles += UTIL_prepareFileList(path, bufStart, pos, bufEnd); /* Recursively call "UTIL_prepareFileList" with the new path. */
|
nbFiles += UTIL_prepareFileList(path, bufStart, pos, bufEnd); /* Recursively call "UTIL_prepareFileList" with the new path. */
|
||||||
if (*bufStart == NULL) { closedir(dir); return 0; }
|
if (*bufStart == NULL) { free(path); closedir(dir); return 0; }
|
||||||
} else {
|
} else {
|
||||||
if (*bufStart + *pos + pathLength >= *bufEnd) {
|
if (*bufStart + *pos + pathLength >= *bufEnd) {
|
||||||
ptrdiff_t newListSize = (*bufEnd - *bufStart) + LIST_SIZE_INCREASE;
|
ptrdiff_t newListSize = (*bufEnd - *bufStart) + LIST_SIZE_INCREASE;
|
||||||
*bufStart = (char*)realloc(*bufStart, newListSize);
|
*bufStart = (char*)UTIL_realloc(*bufStart, newListSize);
|
||||||
*bufEnd = *bufStart + newListSize;
|
*bufEnd = *bufStart + newListSize;
|
||||||
if (*bufStart == NULL) { closedir(dir); return 0; }
|
if (*bufStart == NULL) { free(path); closedir(dir); return 0; }
|
||||||
}
|
}
|
||||||
if (*bufStart + *pos + pathLength < *bufEnd) {
|
if (*bufStart + *pos + pathLength < *bufEnd) {
|
||||||
strncpy(*bufStart + *pos, path, *bufEnd - (*bufStart + *pos));
|
strncpy(*bufStart + *pos, path, *bufEnd - (*bufStart + *pos));
|
||||||
*pos += pathLength + 1;
|
*pos += pathLength + 1;
|
||||||
nbFiles++;
|
nbFiles++;
|
||||||
}
|
}
|
||||||
// printf ("%s/%s nbFiles=%d left=%d\n", dirName, entry->d_name, nbFiles, (int)(bufEnd - *bufStart));
|
|
||||||
}
|
}
|
||||||
errno = 0; // clear errno after UTIL_isDirectory, UTIL_prepareFileList
|
free(path);
|
||||||
|
errno = 0; /* clear errno after UTIL_isDirectory, UTIL_prepareFileList */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errno != 0) {
|
if (errno != 0) {
|
||||||
@@ -335,7 +344,7 @@ UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char** bufStart, size_
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // #ifdef _WIN32
|
#endif /* #ifdef _WIN32 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UTIL_createFileList - takes a list of files and directories (params: inputNames, inputNamesNb), scans directories,
|
* UTIL_createFileList - takes a list of files and directories (params: inputNames, inputNamesNb), scans directories,
|
||||||
@@ -359,7 +368,7 @@ UTIL_STATIC const char** UTIL_createFileList(const char **inputNames, unsigned 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;
|
||||||
buf = (char*)realloc(buf, newListSize);
|
buf = (char*)UTIL_realloc(buf, newListSize);
|
||||||
bufend = buf + newListSize;
|
bufend = buf + newListSize;
|
||||||
if (!buf) return NULL;
|
if (!buf) return NULL;
|
||||||
}
|
}
|
||||||
@@ -405,4 +414,3 @@ UTIL_STATIC void UTIL_freeFileList(const char** filenameTable, char* allocatedBu
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* UTIL_H_MODULE */
|
#endif /* UTIL_H_MODULE */
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -89,6 +89,10 @@ It also features a very fast decoder, with speed > 500 MB/s per core.
|
|||||||
.BR \-t ", " --test
|
.BR \-t ", " --test
|
||||||
Test the integrity of compressed files. This option is equivalent to \fB--decompress --stdout > /dev/null\fR.
|
Test the integrity of compressed files. This option is equivalent to \fB--decompress --stdout > /dev/null\fR.
|
||||||
No files are created or removed.
|
No files are created or removed.
|
||||||
|
.TP
|
||||||
|
.BR --
|
||||||
|
All arguments after -- are treated as files
|
||||||
|
|
||||||
|
|
||||||
.SH DICTIONARY
|
.SH DICTIONARY
|
||||||
.PP
|
.PP
|
||||||
@@ -135,7 +139,7 @@ Typical gains range from ~10% (at 64KB) to x5 better (at <1KB).
|
|||||||
|
|
||||||
|
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
Report bugs at:- https://github.com/Cyan4973/zstd/issues
|
Report bugs at:- https://github.com/facebook/zstd/issues
|
||||||
|
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Yann Collet
|
Yann Collet
|
||||||
|
|||||||
+58
-60
@@ -1,26 +1,13 @@
|
|||||||
/*
|
/**
|
||||||
zstdcli - Command Line Interface (cli) for zstd
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2014-2016
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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/
|
|
||||||
*/
|
|
||||||
/*
|
/*
|
||||||
Note : this is a user program, not part of libzstd.
|
Note : this is a user program, not part of libzstd.
|
||||||
The license of libzstd is BSD.
|
The license of libzstd is BSD.
|
||||||
@@ -36,7 +23,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ZSTDCLI_CLEVEL_MAX
|
#ifndef ZSTDCLI_CLEVEL_MAX
|
||||||
# define ZSTDCLI_CLEVEL_MAX 19
|
# define ZSTDCLI_CLEVEL_MAX 19 /* when not using --ultra */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -64,13 +51,11 @@
|
|||||||
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
|
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
|
||||||
# include <io.h> /* _isatty */
|
# include <io.h> /* _isatty */
|
||||||
# define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream))
|
# define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream))
|
||||||
|
#elif defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || (defined(__APPLE__) && defined(__MACH__)) /* https://sourceforge.net/p/predef/wiki/OperatingSystems/ */
|
||||||
|
# include <unistd.h> /* isatty */
|
||||||
|
# define IS_CONSOLE(stdStream) isatty(fileno(stdStream))
|
||||||
#else
|
#else
|
||||||
# if defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE)
|
# define IS_CONSOLE(stdStream) 0
|
||||||
# include <unistd.h> /* isatty */
|
|
||||||
# define IS_CONSOLE(stdStream) isatty(fileno(stdStream))
|
|
||||||
# else
|
|
||||||
# define IS_CONSOLE(stdStream) 0
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -96,7 +81,7 @@
|
|||||||
|
|
||||||
static const char* g_defaultDictName = "dictionary";
|
static const char* g_defaultDictName = "dictionary";
|
||||||
static const unsigned g_defaultMaxDictSize = 110 KB;
|
static const unsigned g_defaultMaxDictSize = 110 KB;
|
||||||
static const int g_defaultDictCLevel = 5;
|
static const int g_defaultDictCLevel = 3;
|
||||||
static const unsigned g_defaultSelectivityLevel = 9;
|
static const unsigned g_defaultSelectivityLevel = 9;
|
||||||
|
|
||||||
|
|
||||||
@@ -157,6 +142,7 @@ static int usage_advanced(const char* programName)
|
|||||||
DISPLAY( "--test : test compressed file integrity \n");
|
DISPLAY( "--test : test compressed file integrity \n");
|
||||||
DISPLAY( "--[no-]sparse : sparse mode (default:enabled on file, disabled on stdout)\n");
|
DISPLAY( "--[no-]sparse : sparse mode (default:enabled on file, disabled on stdout)\n");
|
||||||
#endif
|
#endif
|
||||||
|
DISPLAY( "-- : All arguments after \"--\" are treated as files \n");
|
||||||
#ifndef ZSTD_NODICT
|
#ifndef ZSTD_NODICT
|
||||||
DISPLAY( "\n");
|
DISPLAY( "\n");
|
||||||
DISPLAY( "Dictionary builder :\n");
|
DISPLAY( "Dictionary builder :\n");
|
||||||
@@ -195,7 +181,7 @@ static void waitEnter(void)
|
|||||||
/*! readU32FromChar() :
|
/*! readU32FromChar() :
|
||||||
@return : unsigned integer value reach from input in `char` format
|
@return : unsigned integer value reach from input in `char` format
|
||||||
Will also modify `*stringPtr`, advancing it to position where it stopped reading.
|
Will also modify `*stringPtr`, advancing it to position where it stopped reading.
|
||||||
Note : this function can overflow if result > MAX_UINT */
|
Note : this function can overflow if digit string > MAX_UINT */
|
||||||
static unsigned readU32FromChar(const char** stringPtr)
|
static unsigned readU32FromChar(const char** stringPtr)
|
||||||
{
|
{
|
||||||
unsigned result = 0;
|
unsigned result = 0;
|
||||||
@@ -207,7 +193,7 @@ static unsigned readU32FromChar(const char** stringPtr)
|
|||||||
|
|
||||||
#define CLEAN_RETURN(i) { operationResult = (i); goto _end; }
|
#define CLEAN_RETURN(i) { operationResult = (i); goto _end; }
|
||||||
|
|
||||||
int main(int argCount, char** argv)
|
int main(int argCount, const char* argv[])
|
||||||
{
|
{
|
||||||
int argNb,
|
int argNb,
|
||||||
bench=0,
|
bench=0,
|
||||||
@@ -222,7 +208,8 @@ int main(int argCount, char** argv)
|
|||||||
nextArgumentIsMaxDict=0,
|
nextArgumentIsMaxDict=0,
|
||||||
nextArgumentIsDictID=0,
|
nextArgumentIsDictID=0,
|
||||||
nextArgumentIsFile=0,
|
nextArgumentIsFile=0,
|
||||||
ultra=0;
|
ultra=0,
|
||||||
|
lastCommand = 0;
|
||||||
int cLevel = ZSTDCLI_CLEVEL_DEFAULT;
|
int cLevel = ZSTDCLI_CLEVEL_DEFAULT;
|
||||||
int cLevelLast = 1;
|
int cLevelLast = 1;
|
||||||
unsigned recursive = 0;
|
unsigned recursive = 0;
|
||||||
@@ -231,13 +218,12 @@ int main(int argCount, char** argv)
|
|||||||
const char* programName = argv[0];
|
const char* programName = argv[0];
|
||||||
const char* outFileName = NULL;
|
const char* outFileName = NULL;
|
||||||
const char* dictFileName = NULL;
|
const char* dictFileName = NULL;
|
||||||
char* dynNameSpace = NULL;
|
|
||||||
unsigned maxDictSize = g_defaultMaxDictSize;
|
unsigned maxDictSize = g_defaultMaxDictSize;
|
||||||
unsigned dictID = 0;
|
unsigned dictID = 0;
|
||||||
int dictCLevel = g_defaultDictCLevel;
|
int dictCLevel = g_defaultDictCLevel;
|
||||||
unsigned dictSelect = g_defaultSelectivityLevel;
|
unsigned dictSelect = g_defaultSelectivityLevel;
|
||||||
#ifdef UTIL_HAS_CREATEFILELIST
|
#ifdef UTIL_HAS_CREATEFILELIST
|
||||||
const char** fileNamesTable = NULL;
|
const char** extendedFileList = NULL;
|
||||||
char* fileNamesBuf = NULL;
|
char* fileNamesBuf = NULL;
|
||||||
unsigned fileNamesNb;
|
unsigned fileNamesNb;
|
||||||
#endif
|
#endif
|
||||||
@@ -275,7 +261,7 @@ int main(int argCount, char** argv)
|
|||||||
if (!strcmp(argument, "--verbose")) { displayLevel++; continue; }
|
if (!strcmp(argument, "--verbose")) { displayLevel++; continue; }
|
||||||
if (!strcmp(argument, "--quiet")) { displayLevel--; continue; }
|
if (!strcmp(argument, "--quiet")) { displayLevel--; continue; }
|
||||||
if (!strcmp(argument, "--stdout")) { forceStdout=1; outFileName=stdoutmark; displayLevel-=(displayLevel==2); continue; }
|
if (!strcmp(argument, "--stdout")) { forceStdout=1; outFileName=stdoutmark; displayLevel-=(displayLevel==2); continue; }
|
||||||
if (!strcmp(argument, "--ultra")) { ultra=1; FIO_setMaxWLog(0); continue; }
|
if (!strcmp(argument, "--ultra")) { ultra=1; continue; }
|
||||||
if (!strcmp(argument, "--check")) { FIO_setChecksumFlag(2); continue; }
|
if (!strcmp(argument, "--check")) { FIO_setChecksumFlag(2); continue; }
|
||||||
if (!strcmp(argument, "--no-check")) { FIO_setChecksumFlag(0); continue; }
|
if (!strcmp(argument, "--no-check")) { FIO_setChecksumFlag(0); continue; }
|
||||||
if (!strcmp(argument, "--no-dictID")) { FIO_setDictIDFlag(0); continue; }
|
if (!strcmp(argument, "--no-dictID")) { FIO_setDictIDFlag(0); continue; }
|
||||||
@@ -283,8 +269,8 @@ int main(int argCount, char** argv)
|
|||||||
if (!strcmp(argument, "--no-sparse")) { FIO_setSparseWrite(0); continue; }
|
if (!strcmp(argument, "--no-sparse")) { FIO_setSparseWrite(0); continue; }
|
||||||
if (!strcmp(argument, "--test")) { testmode=1; decode=1; continue; }
|
if (!strcmp(argument, "--test")) { testmode=1; decode=1; 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; lastCommand=1; continue; }
|
||||||
if (!strcmp(argument, "--dictID")) { nextArgumentIsDictID=1; continue; }
|
if (!strcmp(argument, "--dictID")) { nextArgumentIsDictID=1; lastCommand=1; continue; }
|
||||||
if (!strcmp(argument, "--keep")) { FIO_setRemoveSrcFile(0); continue; }
|
if (!strcmp(argument, "--keep")) { FIO_setRemoveSrcFile(0); continue; }
|
||||||
if (!strcmp(argument, "--rm")) { FIO_setRemoveSrcFile(1); continue; }
|
if (!strcmp(argument, "--rm")) { FIO_setRemoveSrcFile(1); continue; }
|
||||||
|
|
||||||
@@ -302,13 +288,17 @@ int main(int argCount, char** argv)
|
|||||||
argument++;
|
argument++;
|
||||||
|
|
||||||
while (argument[0]!=0) {
|
while (argument[0]!=0) {
|
||||||
#ifndef ZSTD_NOCOMPRESS
|
if (lastCommand) {
|
||||||
|
DISPLAY("error : command must be followed by argument \n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#ifndef ZSTD_NOCOMPRESS
|
||||||
/* compression Level */
|
/* compression Level */
|
||||||
if ((*argument>='0') && (*argument<='9')) {
|
if ((*argument>='0') && (*argument<='9')) {
|
||||||
dictCLevel = cLevel = readU32FromChar(&argument);
|
dictCLevel = cLevel = readU32FromChar(&argument);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch(argument[0])
|
switch(argument[0])
|
||||||
{
|
{
|
||||||
@@ -324,7 +314,7 @@ int main(int argCount, char** argv)
|
|||||||
case 'c': forceStdout=1; outFileName=stdoutmark; argument++; break;
|
case 'c': forceStdout=1; outFileName=stdoutmark; argument++; break;
|
||||||
|
|
||||||
/* Use file content as dictionary */
|
/* Use file content as dictionary */
|
||||||
case 'D': nextEntryIsDictionary = 1; argument++; break;
|
case 'D': nextEntryIsDictionary = 1; lastCommand = 1; argument++; break;
|
||||||
|
|
||||||
/* Overwrite */
|
/* Overwrite */
|
||||||
case 'f': FIO_overwriteMode(); forceStdout=1; argument++; break;
|
case 'f': FIO_overwriteMode(); forceStdout=1; argument++; break;
|
||||||
@@ -345,12 +335,14 @@ int main(int argCount, char** argv)
|
|||||||
case 't': testmode=1; decode=1; argument++; break;
|
case 't': testmode=1; decode=1; argument++; break;
|
||||||
|
|
||||||
/* destination file name */
|
/* destination file name */
|
||||||
case 'o': nextArgumentIsOutFileName=1; argument++; break;
|
case 'o': nextArgumentIsOutFileName=1; lastCommand=1; argument++; break;
|
||||||
|
|
||||||
|
#ifdef UTIL_HAS_CREATEFILELIST
|
||||||
/* recursive */
|
/* recursive */
|
||||||
case 'r': recursive=1; argument++; break;
|
case 'r': recursive=1; argument++; break;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef ZSTD_NOBENCH
|
#ifndef ZSTD_NOBENCH
|
||||||
/* Benchmark */
|
/* Benchmark */
|
||||||
case 'b': bench=1; argument++; break;
|
case 'b': bench=1; argument++; break;
|
||||||
|
|
||||||
@@ -381,7 +373,7 @@ int main(int argCount, char** argv)
|
|||||||
BMK_SetBlockSize(bSize);
|
BMK_SetBlockSize(bSize);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* ZSTD_NOBENCH */
|
#endif /* ZSTD_NOBENCH */
|
||||||
|
|
||||||
/* Dictionary Selection level */
|
/* Dictionary Selection level */
|
||||||
case 's':
|
case 's':
|
||||||
@@ -391,11 +383,11 @@ int main(int argCount, char** argv)
|
|||||||
|
|
||||||
/* 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')) {
|
||||||
BMK_setAdditionalParam(readU32FromChar(&argument));
|
BMK_setAdditionalParam(readU32FromChar(&argument));
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
main_pause=1;
|
main_pause=1;
|
||||||
break;
|
break;
|
||||||
/* unknown command */
|
/* unknown command */
|
||||||
@@ -407,6 +399,7 @@ int main(int argCount, char** argv)
|
|||||||
|
|
||||||
if (nextArgumentIsMaxDict) {
|
if (nextArgumentIsMaxDict) {
|
||||||
nextArgumentIsMaxDict = 0;
|
nextArgumentIsMaxDict = 0;
|
||||||
|
lastCommand = 0;
|
||||||
maxDictSize = readU32FromChar(&argument);
|
maxDictSize = readU32FromChar(&argument);
|
||||||
if (toupper(*argument)=='K') maxDictSize <<= 10;
|
if (toupper(*argument)=='K') maxDictSize <<= 10;
|
||||||
if (toupper(*argument)=='M') maxDictSize <<= 20;
|
if (toupper(*argument)=='M') maxDictSize <<= 20;
|
||||||
@@ -415,6 +408,7 @@ int main(int argCount, char** argv)
|
|||||||
|
|
||||||
if (nextArgumentIsDictID) {
|
if (nextArgumentIsDictID) {
|
||||||
nextArgumentIsDictID = 0;
|
nextArgumentIsDictID = 0;
|
||||||
|
lastCommand = 0;
|
||||||
dictID = readU32FromChar(&argument);
|
dictID = readU32FromChar(&argument);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -423,12 +417,14 @@ int main(int argCount, char** argv)
|
|||||||
|
|
||||||
if (nextEntryIsDictionary) {
|
if (nextEntryIsDictionary) {
|
||||||
nextEntryIsDictionary = 0;
|
nextEntryIsDictionary = 0;
|
||||||
|
lastCommand = 0;
|
||||||
dictFileName = argument;
|
dictFileName = argument;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextArgumentIsOutFileName) {
|
if (nextArgumentIsOutFileName) {
|
||||||
nextArgumentIsOutFileName = 0;
|
nextArgumentIsOutFileName = 0;
|
||||||
|
lastCommand = 0;
|
||||||
outFileName = argument;
|
outFileName = argument;
|
||||||
if (!strcmp(outFileName, "-")) outFileName = stdoutmark;
|
if (!strcmp(outFileName, "-")) outFileName = stdoutmark;
|
||||||
continue;
|
continue;
|
||||||
@@ -438,17 +434,19 @@ int main(int argCount, char** argv)
|
|||||||
filenameTable[filenameIdx++] = argument;
|
filenameTable[filenameIdx++] = argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lastCommand) { DISPLAY("error : command must be followed by argument \n"); return 1; } /* forgotten argument */
|
||||||
|
|
||||||
/* Welcome message (if verbose) */
|
/* Welcome message (if verbose) */
|
||||||
DISPLAYLEVEL(3, WELCOME_MESSAGE);
|
DISPLAYLEVEL(3, WELCOME_MESSAGE);
|
||||||
|
|
||||||
#ifdef UTIL_HAS_CREATEFILELIST
|
#ifdef UTIL_HAS_CREATEFILELIST
|
||||||
if (recursive) {
|
if (recursive) { /* at this stage, filenameTable is a list of paths, which can contain both files and directories */
|
||||||
fileNamesTable = UTIL_createFileList(filenameTable, filenameIdx, &fileNamesBuf, &fileNamesNb);
|
extendedFileList = UTIL_createFileList(filenameTable, filenameIdx, &fileNamesBuf, &fileNamesNb);
|
||||||
if (fileNamesTable) {
|
if (extendedFileList) {
|
||||||
unsigned u;
|
unsigned u;
|
||||||
for (u=0; u<fileNamesNb; u++) DISPLAYLEVEL(4, "%u %s\n", u, fileNamesTable[u]);
|
for (u=0; u<fileNamesNb; u++) DISPLAYLEVEL(4, "%u %s\n", u, extendedFileList[u]);
|
||||||
free((void*)filenameTable);
|
free((void*)filenameTable);
|
||||||
filenameTable = fileNamesTable;
|
filenameTable = extendedFileList;
|
||||||
filenameIdx = fileNamesNb;
|
filenameIdx = fileNamesNb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -478,12 +476,12 @@ int main(int argCount, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* No input filename ==> use stdin and stdout */
|
/* No input filename ==> use stdin and stdout */
|
||||||
filenameIdx += !filenameIdx; /*< default input is stdin */
|
filenameIdx += !filenameIdx; /* filenameTable[0] is stdin by default */
|
||||||
if (!strcmp(filenameTable[0], stdinmark) && !outFileName) outFileName = stdoutmark; /*< when input is stdin, default output is stdout */
|
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 && decode))
|
if (outFileName && !strcmp(outFileName, stdoutmark) && IS_CONSOLE(stdout) && strcmp(filenameTable[0], stdinmark) && !(forceStdout && decode))
|
||||||
CLEAN_RETURN(badusage(programName));
|
CLEAN_RETURN(badusage(programName));
|
||||||
|
|
||||||
/* user-selected output filename, only possible with a single file */
|
/* user-selected output filename, only possible with a single file */
|
||||||
@@ -505,15 +503,16 @@ int main(int argCount, char** argv)
|
|||||||
|
|
||||||
/* IO Stream/File */
|
/* IO Stream/File */
|
||||||
FIO_setNotificationLevel(displayLevel);
|
FIO_setNotificationLevel(displayLevel);
|
||||||
#ifndef ZSTD_NOCOMPRESS
|
|
||||||
if (!decode) {
|
if (!decode) {
|
||||||
if (filenameIdx==1 && outFileName)
|
#ifndef ZSTD_NOCOMPRESS
|
||||||
|
if ((filenameIdx==1) && outFileName)
|
||||||
operationResult = FIO_compressFilename(outFileName, filenameTable[0], dictFileName, cLevel);
|
operationResult = FIO_compressFilename(outFileName, filenameTable[0], dictFileName, cLevel);
|
||||||
else
|
else
|
||||||
operationResult = FIO_compressMultipleFilenames(filenameTable, filenameIdx, outFileName ? outFileName : ZSTD_EXTENSION, dictFileName, cLevel);
|
operationResult = FIO_compressMultipleFilenames(filenameTable, filenameIdx, outFileName ? outFileName : ZSTD_EXTENSION, dictFileName, cLevel);
|
||||||
} else
|
#else
|
||||||
|
DISPLAY("Compression not supported\n");
|
||||||
#endif
|
#endif
|
||||||
{ /* decompression */
|
} else { /* decompression */
|
||||||
#ifndef ZSTD_NODECOMPRESS
|
#ifndef ZSTD_NODECOMPRESS
|
||||||
if (testmode) { outFileName=nulmark; FIO_setRemoveSrcFile(0); } /* test mode */
|
if (testmode) { outFileName=nulmark; FIO_setRemoveSrcFile(0); } /* test mode */
|
||||||
if (filenameIdx==1 && outFileName)
|
if (filenameIdx==1 && outFileName)
|
||||||
@@ -527,10 +526,9 @@ int main(int argCount, char** argv)
|
|||||||
|
|
||||||
_end:
|
_end:
|
||||||
if (main_pause) waitEnter();
|
if (main_pause) waitEnter();
|
||||||
free(dynNameSpace);
|
|
||||||
#ifdef UTIL_HAS_CREATEFILELIST
|
#ifdef UTIL_HAS_CREATEFILELIST
|
||||||
if (fileNamesTable)
|
if (extendedFileList)
|
||||||
UTIL_freeFileList(fileNamesTable, fileNamesBuf);
|
UTIL_freeFileList(extendedFileList, fileNamesBuf);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
free((void*)filenameTable);
|
free((void*)filenameTable);
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
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)
|
|
||||||
- build - command line scripts prepared for Visual Studio compilation without IDE
|
|
||||||
@@ -1,3 +1,17 @@
|
|||||||
|
# local binary (Makefile)
|
||||||
|
fullbench
|
||||||
|
fullbench32
|
||||||
|
fuzzer
|
||||||
|
fuzzer32
|
||||||
|
zbufftest
|
||||||
|
zbufftest32
|
||||||
|
zstreamtest
|
||||||
|
zstreamtest32
|
||||||
|
datagen
|
||||||
|
paramgrill
|
||||||
|
paramgrill32
|
||||||
|
roundTripCrash
|
||||||
|
|
||||||
# Tmp test directory
|
# Tmp test directory
|
||||||
zstdtest
|
zstdtest
|
||||||
speedTest
|
speedTest
|
||||||
@@ -7,3 +21,28 @@ namespaceTest
|
|||||||
# Local script
|
# Local script
|
||||||
startSpeedTest
|
startSpeedTest
|
||||||
speedTest.pid
|
speedTest.pid
|
||||||
|
|
||||||
|
# Object files
|
||||||
|
*.o
|
||||||
|
*.ko
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
|
||||||
|
# Default result files
|
||||||
|
dictionary
|
||||||
|
grillResults.txt
|
||||||
|
_*
|
||||||
|
tmp*
|
||||||
|
*.zst
|
||||||
|
result
|
||||||
|
out
|
||||||
|
|
||||||
|
# fuzzer
|
||||||
|
afl
|
||||||
|
|
||||||
|
# Misc files
|
||||||
|
*.bat
|
||||||
|
dirTest*
|
||||||
|
|||||||
+189
-7
@@ -1,7 +1,6 @@
|
|||||||
# ##########################################################################
|
# ##########################################################################
|
||||||
# Zstd tests - Makefile
|
# ZSTD tests - Makefile
|
||||||
# Copyright (C) Yann Collet 2015-2016
|
# Copyright (C) Yann Collet 2015-2016
|
||||||
# All rights reserved.
|
|
||||||
#
|
#
|
||||||
# GPL v2 License
|
# GPL v2 License
|
||||||
#
|
#
|
||||||
@@ -20,19 +19,115 @@
|
|||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
#
|
#
|
||||||
# You can contact the author at :
|
# You can contact the author at :
|
||||||
# - ZSTD homepage : http://www.zstd.net/
|
# - zstd homepage : http://www.zstd.net/
|
||||||
# ##########################################################################
|
# ##########################################################################
|
||||||
# versionstest : Compatibility test between zstd versions stored on Github (v0.1+)
|
# datagen : Synthetic and parametrable data generator, for tests
|
||||||
|
# fullbench : Precisely measure speed for each zstd inner functions
|
||||||
|
# fullbench32: Same as fullbench, but forced to compile in 32-bits mode
|
||||||
|
# fuzzer : Test tool, to check zstd integrity on target platform
|
||||||
|
# fuzzer32: Same as fuzzer, but forced to compile in 32-bits mode
|
||||||
|
# paramgrill : parameter tester for zstd
|
||||||
|
# test-zstd-speed.py : script for testing zstd speed difference between commits
|
||||||
|
# versionsTest : compatibility test between zstd versions stored on Github (v0.1+)
|
||||||
|
# zbufftest : Test tool, to check ZBUFF integrity on target platform
|
||||||
|
# zbufftest32: Same as zbufftest, but forced to compile in 32-bits mode
|
||||||
|
# zstreamtest : Fuzzer test tool for zstd streaming API
|
||||||
|
# zbufftest32: Same as zstreamtest, but forced to compile in 32-bits mode
|
||||||
# ##########################################################################
|
# ##########################################################################
|
||||||
|
|
||||||
|
DESTDIR?=
|
||||||
|
PREFIX ?= /usr/local
|
||||||
|
BINDIR = $(PREFIX)/bin
|
||||||
|
MANDIR = $(PREFIX)/share/man/man1
|
||||||
|
ZSTDDIR = ../lib
|
||||||
|
PRGDIR = ../programs
|
||||||
PYTHON ?= python3
|
PYTHON ?= python3
|
||||||
TESTARTEFACT := versionsTest namespaceTest
|
TESTARTEFACT := versionsTest namespaceTest
|
||||||
|
|
||||||
.PHONY: default all clean namespaceTest versionsTest
|
|
||||||
|
|
||||||
default: all
|
CPPFLAGS= -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/dictBuilder -I$(PRGDIR)
|
||||||
|
CFLAGS ?= -O3
|
||||||
|
CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 \
|
||||||
|
-Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef
|
||||||
|
CFLAGS += $(MOREFLAGS)
|
||||||
|
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
|
||||||
|
|
||||||
all: namespaceTest versionsTest
|
|
||||||
|
ZSTDCOMMON_FILES := $(ZSTDDIR)/common/*.c
|
||||||
|
ZSTDCOMP_FILES := $(ZSTDDIR)/compress/zstd_compress.c $(ZSTDDIR)/compress/fse_compress.c $(ZSTDDIR)/compress/huf_compress.c
|
||||||
|
ZSTDDECOMP_FILES := $(ZSTDDIR)/decompress/zstd_decompress.c $(ZSTDDIR)/decompress/huf_decompress.c
|
||||||
|
ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES)
|
||||||
|
ZBUFF_FILES := $(ZSTDDIR)/compress/zbuff_compress.c $(ZSTDDIR)/decompress/zbuff_decompress.c
|
||||||
|
ZDICT_FILES := $(ZSTDDIR)/dictBuilder/*.c
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Define *.exe as extension for Windows systems
|
||||||
|
ifneq (,$(filter Windows%,$(OS)))
|
||||||
|
EXT =.exe
|
||||||
|
VOID = nul
|
||||||
|
else
|
||||||
|
EXT =
|
||||||
|
VOID = /dev/null
|
||||||
|
endif
|
||||||
|
|
||||||
|
ZBUFFTEST = -T2mn
|
||||||
|
FUZZERTEST= -T5mn
|
||||||
|
ZSTDRTTEST= --test-large-data
|
||||||
|
|
||||||
|
.PHONY: default all all32 clean test test32 test-all namespaceTest versionsTest
|
||||||
|
|
||||||
|
default: fullbench
|
||||||
|
|
||||||
|
all: fullbench fuzzer zbufftest zstreamtest paramgrill datagen
|
||||||
|
|
||||||
|
all32: fullbench32 fuzzer32 zbufftest32 zstreamtest32
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
zstd:
|
||||||
|
$(MAKE) -C $(PRGDIR) $@
|
||||||
|
|
||||||
|
zstd32:
|
||||||
|
$(MAKE) -C $(PRGDIR) $@
|
||||||
|
|
||||||
|
zstd_nolegacy:
|
||||||
|
$(MAKE) -C $(PRGDIR) $@
|
||||||
|
|
||||||
|
fullbench : $(ZSTD_FILES) $(ZBUFF_FILES) $(PRGDIR)/datagen.c fullbench.c
|
||||||
|
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
|
fullbench32 : $(ZSTD_FILES) $(ZBUFF_FILES) $(PRGDIR)/datagen.c fullbench.c
|
||||||
|
$(CC) -m32 $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
|
fuzzer : CPPFLAGS += -I$(ZSTDDIR)/dictBuilder
|
||||||
|
fuzzer : $(ZSTD_FILES) $(ZDICT_FILES) $(PRGDIR)/datagen.c fuzzer.c
|
||||||
|
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
|
fuzzer32 : CPPFLAGS += -I$(ZSTDDIR)/dictBuilder
|
||||||
|
fuzzer32 : $(ZSTD_FILES) $(ZDICT_FILES) $(PRGDIR)/datagen.c fuzzer.c
|
||||||
|
$(CC) -m32 $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
|
zbufftest : $(ZSTD_FILES) $(ZBUFF_FILES) $(PRGDIR)/datagen.c zbufftest.c
|
||||||
|
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
|
zbufftest32 : $(ZSTD_FILES) $(ZBUFF_FILES) $(PRGDIR)/datagen.c zbufftest.c
|
||||||
|
$(CC) -m32 $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
|
zstreamtest : $(ZSTD_FILES) $(PRGDIR)/datagen.c zstreamtest.c
|
||||||
|
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
|
zstreamtest32 : $(ZSTD_FILES) $(PRGDIR)/datagen.c zstreamtest.c
|
||||||
|
$(CC) -m32 $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
|
paramgrill : $(ZSTD_FILES) $(PRGDIR)/datagen.c paramgrill.c
|
||||||
|
$(CC) $(FLAGS) $^ -lm -o $@$(EXT)
|
||||||
|
|
||||||
|
datagen : $(PRGDIR)/datagen.c datagencli.c
|
||||||
|
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
|
roundTripCrash : $(ZSTD_FILES) roundTripCrash.c
|
||||||
|
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||||
|
|
||||||
namespaceTest:
|
namespaceTest:
|
||||||
if $(CC) namespaceTest.c ../lib/common/xxhash.c -o $@ ; then echo compilation should fail; exit 1 ; fi
|
if $(CC) namespaceTest.c ../lib/common/xxhash.c -o $@ ; then echo compilation should fail; exit 1 ; fi
|
||||||
@@ -42,5 +137,92 @@ versionsTest:
|
|||||||
$(PYTHON) test-zstd-versions.py
|
$(PYTHON) test-zstd-versions.py
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
$(MAKE) -C ../lib clean
|
||||||
@$(RM) -fR $(TESTARTEFACT)
|
@$(RM) -fR $(TESTARTEFACT)
|
||||||
|
@$(RM) -f core *.o tmp* result* *.gcda dictionary *.zst \
|
||||||
|
$(PRGDIR)/zstd$(EXT) $(PRGDIR)/zstd32$(EXT) \
|
||||||
|
fullbench$(EXT) fullbench32$(EXT) \
|
||||||
|
fuzzer$(EXT) fuzzer32$(EXT) zbufftest$(EXT) zbufftest32$(EXT) \
|
||||||
|
zstreamtest$(EXT) zstreamtest32$(EXT) \
|
||||||
|
datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT)
|
||||||
@echo Cleaning completed
|
@echo Cleaning completed
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------------
|
||||||
|
#make valgrindTest is validated only for Linux, OSX, kFreeBSD, Hurd and some BSD targets
|
||||||
|
#----------------------------------------------------------------------------------
|
||||||
|
ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD DragonFly))
|
||||||
|
HOST_OS = POSIX
|
||||||
|
|
||||||
|
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) $(PRGDIR)/zstd ; if [ $$? -eq 0 ] ; then echo "zstd without argument should have failed"; false; fi
|
||||||
|
./datagen -g80 | $(VALGRIND) $(PRGDIR)/zstd - -c > $(VOID)
|
||||||
|
./datagen -g16KB | $(VALGRIND) $(PRGDIR)/zstd -vf - -c > $(VOID)
|
||||||
|
./datagen -g2930KB | $(VALGRIND) $(PRGDIR)/zstd -5 -vf - -o tmp
|
||||||
|
$(VALGRIND) $(PRGDIR)/zstd -vdf tmp -c > $(VOID)
|
||||||
|
./datagen -g64MB | $(VALGRIND) $(PRGDIR)/zstd -vf - -c > $(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-zstream
|
||||||
|
|
||||||
|
test32: test-zstd32 test-fullbench32 test-fuzzer32 test-zbuff32 test-zstream32
|
||||||
|
|
||||||
|
test-all: test test32 valgrindTest
|
||||||
|
|
||||||
|
test-zstd: ZSTD = $(PRGDIR)/zstd
|
||||||
|
test-zstd: zstd zstd-playTests
|
||||||
|
|
||||||
|
test-zstd32: ZSTD = $(PRGDIR)/zstd32
|
||||||
|
test-zstd32: zstd32 zstd-playTests
|
||||||
|
|
||||||
|
test-zstd_nolegacy: ZSTD = $(PRGDIR)/zstd
|
||||||
|
test-zstd_nolegacy: zstd_nolegacy zstd-playTests
|
||||||
|
|
||||||
|
test-fullbench: fullbench datagen
|
||||||
|
./fullbench -i1
|
||||||
|
./fullbench -i1 -P0
|
||||||
|
|
||||||
|
test-fullbench32: fullbench32 datagen
|
||||||
|
./fullbench32 -i1
|
||||||
|
./fullbench32 -i1 -P0
|
||||||
|
|
||||||
|
test-fuzzer: fuzzer
|
||||||
|
./fuzzer $(FUZZERTEST)
|
||||||
|
|
||||||
|
test-fuzzer32: fuzzer32
|
||||||
|
./fuzzer32 $(FUZZERTEST)
|
||||||
|
|
||||||
|
test-zbuff: zbufftest
|
||||||
|
./zbufftest $(ZBUFFTEST)
|
||||||
|
|
||||||
|
test-zbuff32: zbufftest32
|
||||||
|
./zbufftest32 $(ZBUFFTEST)
|
||||||
|
|
||||||
|
test-zstream: zstreamtest
|
||||||
|
./zstreamtest $(ZBUFFTEST)
|
||||||
|
|
||||||
|
test-zstream32: zstreamtest32
|
||||||
|
./zstreamtest32 $(ZBUFFTEST)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|||||||
+15
-4
@@ -1,14 +1,25 @@
|
|||||||
scripts for automated testing of zstd
|
Programs and scripts for automated testing of Zstandard
|
||||||
================================
|
=======================================================
|
||||||
|
|
||||||
#### test-zstd-versions.py - script for testing zstd interoperability between versions
|
This directory contains the following programs and scripts:
|
||||||
|
- `datagen` : Synthetic and parametrable data generator, for tests
|
||||||
|
- `fullbench` : Precisely measure speed for each zstd inner functions
|
||||||
|
- `fuzzer` : Test tool, to check zstd integrity on target platform
|
||||||
|
- `paramgrill` : parameter tester for zstd
|
||||||
|
- `test-zstd-speed.py` : script for testing zstd speed difference between commits
|
||||||
|
- `test-zstd-versions.py` : compatibility test between zstd versions stored on Github (v0.1+)
|
||||||
|
- `zbufftest` : Test tool to check ZBUFF (a buffered streaming API) integrity
|
||||||
|
- `zstreamtest` : Fuzzer test tool for zstd streaming API
|
||||||
|
|
||||||
|
|
||||||
|
#### `test-zstd-versions.py` - script for testing zstd interoperability between versions
|
||||||
|
|
||||||
This script creates `versionsTest` directory to which zstd repository is cloned.
|
This script creates `versionsTest` directory to which zstd repository is cloned.
|
||||||
Then all taged (released) versions of zstd are compiled.
|
Then all taged (released) versions of zstd are compiled.
|
||||||
In the following step interoperability between zstd versions is checked.
|
In the following step interoperability between zstd versions is checked.
|
||||||
|
|
||||||
|
|
||||||
#### test-zstd-speed.py - script for testing zstd speed difference between commits
|
#### `test-zstd-speed.py` - script for testing zstd speed difference between commits
|
||||||
|
|
||||||
This script creates `speedTest` directory to which zstd repository is cloned.
|
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).
|
Then it compiles all branches of zstd and performs a speed benchmark for a given list of files (the `testFileNames` parameter).
|
||||||
|
|||||||
@@ -1,31 +1,15 @@
|
|||||||
/*
|
/**
|
||||||
datagencli.c
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
compressible data command line generator
|
* All rights reserved.
|
||||||
Copyright (C) Yann Collet 2012-2015
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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 source repository : https://github.com/Cyan4973/zstd
|
|
||||||
- Public forum : https://groups.google.com/forum/#!forum/lz4c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-************************************
|
/*-************************************
|
||||||
* Includes
|
* Dependencies
|
||||||
**************************************/
|
**************************************/
|
||||||
#include "util.h" /* Compiler options */
|
#include "util.h" /* Compiler options */
|
||||||
#include <stdio.h> /* fprintf, stderr */
|
#include <stdio.h> /* fprintf, stderr */
|
||||||
@@ -1,26 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
fullbench.c - Detailed bench program for zstd
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2014-2016
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*_************************************
|
/*_************************************
|
||||||
* Includes
|
* Includes
|
||||||
@@ -135,13 +121,12 @@ size_t local_ZSTD_decodeLiteralsBlock(void* dst, size_t dstSize, void* buff2, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr);
|
extern size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr);
|
||||||
extern size_t ZSTD_decodeSeqHeaders(int* nbSeq, FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb, U32 tableRepeatFlag, const void* src, size_t srcSize);
|
extern size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeq, const void* src, size_t srcSize);
|
||||||
size_t local_ZSTD_decodeSeqHeaders(void* dst, size_t dstSize, void* buff2, const void* src, size_t srcSize)
|
size_t local_ZSTD_decodeSeqHeaders(void* dst, size_t dstSize, void* buff2, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
U32 DTableML[FSE_DTABLE_SIZE_U32(10)], DTableLL[FSE_DTABLE_SIZE_U32(10)], DTableOffb[FSE_DTABLE_SIZE_U32(9)]; /* MLFSELog, LLFSELog and OffFSELog are not public values */
|
|
||||||
int nbSeq;
|
int nbSeq;
|
||||||
(void)src; (void)srcSize; (void)dst; (void)dstSize;
|
(void)src; (void)srcSize; (void)dst; (void)dstSize;
|
||||||
return ZSTD_decodeSeqHeaders(&nbSeq, DTableLL, DTableML, DTableOffb, 0, buff2, g_cSize);
|
return ZSTD_decodeSeqHeaders(g_zdc, &nbSeq, buff2, g_cSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -303,6 +288,7 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb)
|
|||||||
}
|
}
|
||||||
iend = ip + ZSTD_blockHeaderSize + cBlockSize; /* End of first block */
|
iend = ip + ZSTD_blockHeaderSize + cBlockSize; /* End of first block */
|
||||||
ip += ZSTD_blockHeaderSize; /* skip block header */
|
ip += ZSTD_blockHeaderSize; /* skip block header */
|
||||||
|
ZSTD_decompressBegin(g_zdc);
|
||||||
ip += ZSTD_decodeLiteralsBlock(g_zdc, ip, iend-ip); /* skip literal segment */
|
ip += ZSTD_decodeLiteralsBlock(g_zdc, ip, iend-ip); /* skip literal segment */
|
||||||
g_cSize = iend-ip;
|
g_cSize = iend-ip;
|
||||||
memcpy(buff2, ip, g_cSize); /* copy rest of block (it starts by SeqHeader) */
|
memcpy(buff2, ip, g_cSize); /* copy rest of block (it starts by SeqHeader) */
|
||||||
@@ -1,26 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
Fuzzer test tool for zstd
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2014-2016
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-************************************
|
/*-************************************
|
||||||
* Compiler specific
|
* Compiler specific
|
||||||
@@ -37,7 +23,6 @@
|
|||||||
**************************************/
|
**************************************/
|
||||||
#include <stdlib.h> /* free */
|
#include <stdlib.h> /* free */
|
||||||
#include <stdio.h> /* fgets, sscanf */
|
#include <stdio.h> /* fgets, sscanf */
|
||||||
#include <sys/timeb.h> /* timeb */
|
|
||||||
#include <string.h> /* strcmp */
|
#include <string.h> /* strcmp */
|
||||||
#include <time.h> /* clock_t */
|
#include <time.h> /* clock_t */
|
||||||
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressContinue, ZSTD_compressBlock */
|
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressContinue, ZSTD_compressBlock */
|
||||||
@@ -72,7 +57,7 @@ static U32 g_displayLevel = 2;
|
|||||||
if ((FUZ_clockSpan(g_displayClock) > g_refreshRate) || (g_displayLevel>=4)) \
|
if ((FUZ_clockSpan(g_displayClock) > g_refreshRate) || (g_displayLevel>=4)) \
|
||||||
{ g_displayClock = clock(); DISPLAY(__VA_ARGS__); \
|
{ g_displayClock = clock(); DISPLAY(__VA_ARGS__); \
|
||||||
if (g_displayLevel>=4) fflush(stdout); } }
|
if (g_displayLevel>=4) fflush(stdout); } }
|
||||||
static const clock_t g_refreshRate = CLOCKS_PER_SEC * 150 / 1000;
|
static const clock_t g_refreshRate = CLOCKS_PER_SEC / 6;
|
||||||
static clock_t g_displayClock = 0;
|
static clock_t g_displayClock = 0;
|
||||||
|
|
||||||
|
|
||||||
@@ -100,7 +85,6 @@ static unsigned FUZ_rand(unsigned* src)
|
|||||||
return rand32 >> 5;
|
return rand32 >> 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static unsigned FUZ_highbit32(U32 v32)
|
static unsigned FUZ_highbit32(U32 v32)
|
||||||
{
|
{
|
||||||
unsigned nbBits = 0;
|
unsigned nbBits = 0;
|
||||||
@@ -110,6 +94,10 @@ static unsigned FUZ_highbit32(U32 v32)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*=============================================
|
||||||
|
* Basic Unit tests
|
||||||
|
=============================================*/
|
||||||
|
|
||||||
#define CHECK_V(var, fn) size_t const var = fn; if (ZSTD_isError(var)) goto _output_error
|
#define CHECK_V(var, fn) size_t const var = fn; if (ZSTD_isError(var)) goto _output_error
|
||||||
#define CHECK(fn) { CHECK_V(err, fn); }
|
#define CHECK(fn) { CHECK_V(err, fn); }
|
||||||
#define CHECKPLUS(var, fn, more) { CHECK_V(var, fn); more; }
|
#define CHECKPLUS(var, fn, more) { CHECK_V(var, fn); more; }
|
||||||
@@ -185,13 +173,13 @@ static int basicUnitTests(U32 seed, double compressibility)
|
|||||||
static const size_t dictSize = 551;
|
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, 0);
|
||||||
if (!ZSTD_isError(copyResult)) goto _output_error; } /* error must 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++);
|
||||||
CHECK( ZSTD_compressBegin_usingDict(ctxOrig, CNBuffer, dictSize, 2) );
|
CHECK( ZSTD_compressBegin_usingDict(ctxOrig, CNBuffer, dictSize, 2) );
|
||||||
CHECK( ZSTD_copyCCtx(ctxDuplicated, ctxOrig) );
|
CHECK( ZSTD_copyCCtx(ctxDuplicated, ctxOrig, CNBuffSize - dictSize) );
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : compress with flat dictionary : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : compress with flat dictionary : ", testNb++);
|
||||||
@@ -233,10 +221,10 @@ static int basicUnitTests(U32 seed, double compressibility)
|
|||||||
p.fParams.contentSizeFlag = 1;
|
p.fParams.contentSizeFlag = 1;
|
||||||
CHECK( ZSTD_compressBegin_advanced(ctxOrig, CNBuffer, dictSize, p, testSize-1) );
|
CHECK( ZSTD_compressBegin_advanced(ctxOrig, CNBuffer, dictSize, p, testSize-1) );
|
||||||
}
|
}
|
||||||
CHECK( ZSTD_copyCCtx(ctxDuplicated, ctxOrig) );
|
CHECK( ZSTD_copyCCtx(ctxDuplicated, ctxOrig, testSize) );
|
||||||
|
|
||||||
CHECKPLUS(r, ZSTD_compressContinue(ctxDuplicated, compressedBuffer, ZSTD_compressBound(testSize),
|
CHECKPLUS(r, ZSTD_compressEnd(ctxDuplicated, compressedBuffer, ZSTD_compressBound(testSize),
|
||||||
(const char*)CNBuffer + dictSize, CNBuffSize - dictSize),
|
(const char*)CNBuffer + dictSize, testSize),
|
||||||
cSize = r);
|
cSize = r);
|
||||||
{ ZSTD_frameParams fp;
|
{ ZSTD_frameParams fp;
|
||||||
if (ZSTD_getFrameParams(&fp, compressedBuffer, cSize)) goto _output_error;
|
if (ZSTD_getFrameParams(&fp, compressedBuffer, cSize)) goto _output_error;
|
||||||
@@ -272,6 +260,12 @@ static int basicUnitTests(U32 seed, double compressibility)
|
|||||||
if (ZDICT_isError(dictSize)) goto _output_error;
|
if (ZDICT_isError(dictSize)) goto _output_error;
|
||||||
DISPLAYLEVEL(4, "OK, created dictionary of size %u \n", (U32)dictSize);
|
DISPLAYLEVEL(4, "OK, created dictionary of size %u \n", (U32)dictSize);
|
||||||
|
|
||||||
|
DISPLAYLEVEL(4, "test%3i : check dictID : ", testNb++);
|
||||||
|
{ U32 const dictID = ZDICT_getDictID(dictBuffer, dictSize);
|
||||||
|
if (dictID==0) goto _output_error;
|
||||||
|
DISPLAYLEVEL(4, "OK : %u \n", dictID);
|
||||||
|
}
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "test%3i : compress with dictionary : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : compress with dictionary : ", testNb++);
|
||||||
cSize = ZSTD_compress_usingDict(cctx, compressedBuffer, ZSTD_compressBound(CNBuffSize),
|
cSize = ZSTD_compress_usingDict(cctx, compressedBuffer, ZSTD_compressBound(CNBuffSize),
|
||||||
CNBuffer, CNBuffSize,
|
CNBuffer, CNBuffSize,
|
||||||
@@ -562,7 +556,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
|
|||||||
/* compression tests */
|
/* compression tests */
|
||||||
{ unsigned const cLevel = (FUZ_rand(&lseed) % (ZSTD_maxCLevel() - (FUZ_highbit32((U32)sampleSize)/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 : %s", ZSTD_getErrorName(cSize));
|
||||||
|
|
||||||
/* compression failure test : too small dest buffer */
|
/* compression failure test : too small dest buffer */
|
||||||
if (cSize > 3) {
|
if (cSize > 3) {
|
||||||
@@ -680,9 +674,9 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
|
|||||||
errorCode = ZSTD_compressBegin_advanced(refCtx, dict, dictSize, p, 0);
|
errorCode = ZSTD_compressBegin_advanced(refCtx, dict, dictSize, p, 0);
|
||||||
CHECK (ZSTD_isError(errorCode), "ZSTD_compressBegin_advanced error : %s", ZSTD_getErrorName(errorCode));
|
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, 0);
|
||||||
CHECK (ZSTD_isError(errorCode), "ZSTD_copyCCtx error : %s", ZSTD_getErrorName(errorCode)); }
|
CHECK (ZSTD_isError(errorCode), "ZSTD_copyCCtx error : %s", ZSTD_getErrorName(errorCode));
|
||||||
}
|
} }
|
||||||
XXH64_reset(&xxhState, 0);
|
XXH64_reset(&xxhState, 0);
|
||||||
{ U32 const nbChunks = (FUZ_rand(&lseed) & 127) + 2;
|
{ U32 const nbChunks = (FUZ_rand(&lseed) & 127) + 2;
|
||||||
U32 n;
|
U32 n;
|
||||||
+9
-24
@@ -1,27 +1,12 @@
|
|||||||
/* ##########################################################################
|
/**
|
||||||
# namespaceTest
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
# ensure xxhash namespace emulation is properly triggered
|
* All rights reserved.
|
||||||
# Copyright (C) Yann Collet 2016
|
*
|
||||||
#
|
* This source code is licensed under the BSD-style license found in the
|
||||||
# GPL v2 License
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
#
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
# 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/
|
|
||||||
# ########################################################################*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stddef.h> /* size_t */
|
#include <stddef.h> /* size_t */
|
||||||
|
|||||||
@@ -1,26 +1,11 @@
|
|||||||
/*
|
/**
|
||||||
paramgrill.c - parameter tester for zstd
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2015-2016
|
* All rights reserved.
|
||||||
|
*
|
||||||
GPL v2 License
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
This program is free software; you can redistribute it and/or modify
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*-************************************
|
/*-************************************
|
||||||
@@ -32,25 +32,41 @@ case "$OS" in
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
MD5SUM="md5sum"
|
MD5SUM="md5sum"
|
||||||
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
MD5SUM="md5 -r"
|
MD5SUM="md5 -r"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$ECHO "\nStarting playTests.sh isWindows=$isWindows TRAVIS_OS_NAME=$TRAVIS_OS_NAME"
|
$ECHO "\nStarting playTests.sh isWindows=$isWindows"
|
||||||
|
|
||||||
[ -n "$ZSTD" ] || die "ZSTD variable must be defined!"
|
[ -n "$ZSTD" ] || die "ZSTD variable must be defined!"
|
||||||
|
|
||||||
file $ZSTD
|
file $ZSTD
|
||||||
|
|
||||||
$ECHO "\n**** simple tests **** "
|
$ECHO "\n**** simple tests **** "
|
||||||
|
|
||||||
./datagen > tmp
|
./datagen > tmp
|
||||||
|
$ECHO "test : basic compression "
|
||||||
$ZSTD -f tmp # trivial compression case, creates tmp.zst
|
$ZSTD -f tmp # trivial compression case, creates tmp.zst
|
||||||
|
$ECHO "test : basic decompression"
|
||||||
$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 -f tmp # too large compression level, automatic sized down
|
$ZSTD -99 -f tmp # too large compression level, automatic sized down
|
||||||
$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 : compress to named file"
|
||||||
|
rm tmpCompressed
|
||||||
|
$ZSTD tmp -o tmpCompressed
|
||||||
|
ls tmpCompressed # must work
|
||||||
|
$ECHO "test : -o must be followed by filename (must fail)"
|
||||||
|
$ZSTD tmp -of tmpCompressed && die "-o must be followed by filename "
|
||||||
|
$ECHO "test : force write, correct order"
|
||||||
|
$ZSTD tmp -fo tmpCompressed
|
||||||
|
$ECHO "test : forgotten argument"
|
||||||
|
cp tmp tmp2
|
||||||
|
$ZSTD tmp2 -fo && die "-o must be followed by filename "
|
||||||
|
$ECHO "test : implied stdout when input is stdin"
|
||||||
|
$ECHO bob | $ZSTD | $ZSTD -d
|
||||||
$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)"
|
||||||
@@ -169,35 +185,49 @@ $ZSTD -f tmp1 notHere tmp2 && die "missing file not detected!"
|
|||||||
|
|
||||||
$ECHO "\n**** dictionary tests **** "
|
$ECHO "\n**** dictionary tests **** "
|
||||||
|
|
||||||
|
TESTFILE=../programs/zstdcli.c
|
||||||
./datagen > tmpDict
|
./datagen > tmpDict
|
||||||
./datagen -g1M | $MD5SUM > tmp1
|
./datagen -g1M | $MD5SUM > tmp1
|
||||||
./datagen -g1M | $ZSTD -D tmpDict | $ZSTD -D tmpDict -dvq | $MD5SUM > tmp2
|
./datagen -g1M | $ZSTD -D tmpDict | $ZSTD -D tmpDict -dvq | $MD5SUM > tmp2
|
||||||
diff -q tmp1 tmp2
|
diff -q tmp1 tmp2
|
||||||
$ECHO "- Create first dictionary"
|
$ECHO "- Create first dictionary"
|
||||||
$ZSTD --train *.c -o tmpDict
|
$ZSTD --train *.c ../programs/*.c -o tmpDict
|
||||||
cp zstdcli.c tmp
|
cp $TESTFILE tmp
|
||||||
$ZSTD -f tmp -D tmpDict
|
$ZSTD -f tmp -D tmpDict
|
||||||
$ZSTD -d tmp.zst -D tmpDict -of result
|
$ZSTD -d tmp.zst -D tmpDict -fo result
|
||||||
diff zstdcli.c result
|
diff $TESTFILE result
|
||||||
$ECHO "- Create second (different) dictionary"
|
$ECHO "- Create second (different) dictionary"
|
||||||
$ZSTD --train *.c *.h -o tmpDictC
|
$ZSTD --train *.c ../programs/*.c ../programs/*.h -o tmpDictC
|
||||||
$ZSTD -d tmp.zst -D tmpDictC -of result && die "wrong dictionary not detected!"
|
$ZSTD -d tmp.zst -D tmpDictC -fo result && die "wrong dictionary not detected!"
|
||||||
$ECHO "- Create dictionary with short dictID"
|
$ECHO "- Create dictionary with short dictID"
|
||||||
$ZSTD --train *.c --dictID 1 -o tmpDict1
|
$ZSTD --train *.c ../programs/*.c --dictID 1 -o tmpDict1
|
||||||
cmp tmpDict tmpDict1 && die "dictionaries should have different ID !"
|
cmp tmpDict tmpDict1 && die "dictionaries should have different ID !"
|
||||||
|
$ECHO "- Create dictionary with wrong dictID parameter order (must fail)"
|
||||||
|
$ZSTD --train *.c ../programs/*.c --dictID -o 1 tmpDict1 && die "wrong order : --dictID must be followed by argument "
|
||||||
|
$ECHO "- Create dictionary with size limit"
|
||||||
|
$ZSTD --train *.c ../programs/*.c -o tmpDict2 --maxdict 4K -v
|
||||||
|
$ECHO "- Create dictionary with wrong parameter order (must fail)"
|
||||||
|
$ZSTD --train *.c ../programs/*.c -o tmpDict2 --maxdict -v 4K && die "wrong order : --maxdict must be followed by argument "
|
||||||
$ECHO "- Compress without dictID"
|
$ECHO "- Compress without dictID"
|
||||||
$ZSTD -f tmp -D tmpDict1 --no-dictID
|
$ZSTD -f tmp -D tmpDict1 --no-dictID
|
||||||
$ZSTD -d tmp.zst -D tmpDict -of result
|
$ZSTD -d tmp.zst -D tmpDict -fo result
|
||||||
diff zstdcli.c result
|
diff $TESTFILE result
|
||||||
|
$ECHO "- Compress with wrong argument order (must fail)"
|
||||||
|
$ZSTD tmp -Df tmpDict1 -c > /dev/null && die "-D must be followed by dictionary name "
|
||||||
$ECHO "- Compress multiple files with dictionary"
|
$ECHO "- Compress multiple files with dictionary"
|
||||||
rm -rf dirTestDict
|
rm -rf dirTestDict
|
||||||
mkdir dirTestDict
|
mkdir dirTestDict
|
||||||
cp *.c dirTestDict
|
cp *.c dirTestDict
|
||||||
cp *.h dirTestDict
|
cp ../programs/*.c dirTestDict
|
||||||
cat dirTestDict/* | $MD5SUM > tmph1 # note : we expect same file order to generate same hash
|
cp ../programs/*.h dirTestDict
|
||||||
$ZSTD -f dirTestDict/* -D tmpDictC
|
$MD5SUM dirTestDict/* > tmph1
|
||||||
$ZSTD -d dirTestDict/*.zst -D tmpDictC -c | $MD5SUM > tmph2
|
$ZSTD -f --rm dirTestDict/* -D tmpDictC
|
||||||
diff -q tmph1 tmph2
|
$ZSTD -d --rm dirTestDict/*.zst -D tmpDictC # note : use internal checksum by default
|
||||||
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
$ECHO "md5sum -c not supported on OS-X : test skipped" # not compatible with OS-X's md5
|
||||||
|
else
|
||||||
|
$MD5SUM -c tmph1
|
||||||
|
fi
|
||||||
rm -rf dirTestDict
|
rm -rf dirTestDict
|
||||||
rm tmp*
|
rm tmp*
|
||||||
|
|
||||||
@@ -1,26 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
roundTripCrash
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2013-2016
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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,
|
This program takes a file in input,
|
||||||
performs a zstd round-trip test (compression - decompress)
|
performs a zstd round-trip test (compression - decompress)
|
||||||
+65
-27
@@ -1,5 +1,18 @@
|
|||||||
#! /usr/bin/env python
|
#! /usr/bin/env python
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This source code is licensed under the BSD-style license found in the
|
||||||
|
# LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
# of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Limitations:
|
||||||
|
# - doesn't support filenames with spaces
|
||||||
|
# - dir1/zstd and dir2/zstd will be merged in a single results file
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
import string
|
import string
|
||||||
@@ -8,14 +21,16 @@ import time
|
|||||||
import traceback
|
import traceback
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
script_version = 'v0.8.0 (2016-08-03)'
|
script_version = 'v1.0.1 (2016-09-15)'
|
||||||
default_repo_url = 'https://github.com/Cyan4973/zstd.git'
|
default_repo_url = 'https://github.com/facebook/zstd.git'
|
||||||
working_dir_name = 'speedTest'
|
working_dir_name = 'speedTest'
|
||||||
working_path = os.getcwd() + '/' + working_dir_name # /path/to/zstd/tests/speedTest
|
working_path = os.getcwd() + '/' + working_dir_name # /path/to/zstd/tests/speedTest
|
||||||
clone_path = working_path + '/' + 'zstd' # /path/to/zstd/tests/speedTest/zstd
|
clone_path = working_path + '/' + 'zstd' # /path/to/zstd/tests/speedTest/zstd
|
||||||
email_header = 'ZSTD_speedTest'
|
email_header = 'ZSTD_speedTest'
|
||||||
pid = str(os.getpid())
|
pid = str(os.getpid())
|
||||||
verbose = False
|
verbose = False
|
||||||
|
clang_version = "unknown"
|
||||||
|
gcc_version = "unknown"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -114,19 +129,19 @@ def get_last_results(resultsFileName):
|
|||||||
with open(resultsFileName, 'r') as f:
|
with open(resultsFileName, 'r') as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
words = line.split()
|
words = line.split()
|
||||||
if len(words) == 2: # branch + commit
|
if len(words) <= 4: # branch + commit + compilerVer + md5
|
||||||
commit = words[1]
|
commit = words[1]
|
||||||
csize = []
|
csize = []
|
||||||
cspeed = []
|
cspeed = []
|
||||||
dspeed = []
|
dspeed = []
|
||||||
if (len(words) == 8): # results
|
if (len(words) == 8) or (len(words) == 9): # results: "filename" or "XX files"
|
||||||
csize.append(int(words[1]))
|
csize.append(int(words[1]))
|
||||||
cspeed.append(float(words[3]))
|
cspeed.append(float(words[3]))
|
||||||
dspeed.append(float(words[5]))
|
dspeed.append(float(words[5]))
|
||||||
return commit, csize, cspeed, dspeed
|
return commit, csize, cspeed, dspeed
|
||||||
|
|
||||||
|
|
||||||
def benchmark_and_compare(branch, commit, last_commit, args, executableName, md5sum, resultsFileName,
|
def benchmark_and_compare(branch, commit, last_commit, args, executableName, md5sum, compilerVersion, resultsFileName,
|
||||||
testFilePath, fileName, last_csize, last_cspeed, last_dspeed):
|
testFilePath, fileName, last_csize, last_cspeed, last_dspeed):
|
||||||
sleepTime = 30
|
sleepTime = 30
|
||||||
while os.getloadavg()[0] > args.maxLoadAvg:
|
while os.getloadavg()[0] > args.maxLoadAvg:
|
||||||
@@ -134,14 +149,16 @@ def benchmark_and_compare(branch, commit, last_commit, args, executableName, md5
|
|||||||
% (os.getloadavg()[0], args.maxLoadAvg, sleepTime))
|
% (os.getloadavg()[0], args.maxLoadAvg, sleepTime))
|
||||||
time.sleep(sleepTime)
|
time.sleep(sleepTime)
|
||||||
start_load = str(os.getloadavg())
|
start_load = str(os.getloadavg())
|
||||||
result = execute('programs/%s -qi5b1e%s %s' % (executableName, args.lastCLevel, testFilePath),
|
if args.dictionary:
|
||||||
print_output=True)
|
result = execute('programs/%s -rqi5b1e%s -D %s %s' % (executableName, args.lastCLevel, args.dictionary, testFilePath), print_output=True)
|
||||||
|
else:
|
||||||
|
result = execute('programs/%s -rqi5b1e%s %s' % (executableName, args.lastCLevel, testFilePath), print_output=True)
|
||||||
end_load = str(os.getloadavg())
|
end_load = str(os.getloadavg())
|
||||||
linesExpected = args.lastCLevel + 1
|
linesExpected = args.lastCLevel + 1
|
||||||
if len(result) != linesExpected:
|
if len(result) != linesExpected:
|
||||||
raise RuntimeError("ERROR: number of result lines=%d is different that expected %d\n%s" % (len(result), linesExpected, '\n'.join(result)))
|
raise RuntimeError("ERROR: number of result lines=%d is different that expected %d\n%s" % (len(result), linesExpected, '\n'.join(result)))
|
||||||
with open(resultsFileName, "a") as myfile:
|
with open(resultsFileName, "a") as myfile:
|
||||||
myfile.write(branch + " " + commit + "\n")
|
myfile.write('%s %s %s md5=%s\n' % (branch, commit, compilerVersion, md5sum))
|
||||||
myfile.write('\n'.join(result) + '\n')
|
myfile.write('\n'.join(result) + '\n')
|
||||||
myfile.close()
|
myfile.close()
|
||||||
if (last_cspeed == None):
|
if (last_cspeed == None):
|
||||||
@@ -158,7 +175,7 @@ def benchmark_and_compare(branch, commit, last_commit, args, executableName, md5
|
|||||||
if (float(last_csize[i])/csize[i] < args.ratioLimit):
|
if (float(last_csize[i])/csize[i] < args.ratioLimit):
|
||||||
text += "WARNING: %s -%d cSize=%d last_cSize=%d diff=%.4f %s\n" % (executableName, i+1, csize[i], last_csize[i], float(last_csize[i])/csize[i], fileName)
|
text += "WARNING: %s -%d cSize=%d last_cSize=%d diff=%.4f %s\n" % (executableName, i+1, csize[i], last_csize[i], float(last_csize[i])/csize[i], fileName)
|
||||||
if text:
|
if text:
|
||||||
text = args.message + ("\nmaxLoadAvg=%s load average at start=%s end=%s last_commit=%s md5=%s\n" % (args.maxLoadAvg, start_load, end_load, last_commit, md5sum)) + text
|
text = args.message + ("\nmaxLoadAvg=%s load average at start=%s end=%s\n%s last_commit=%s md5=%s\n" % (args.maxLoadAvg, start_load, end_load, compilerVersion, last_commit, md5sum)) + text
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
@@ -171,13 +188,13 @@ def update_config_file(branch, commit):
|
|||||||
return last_commit
|
return last_commit
|
||||||
|
|
||||||
|
|
||||||
def double_check(branch, commit, args, executableName, md5sum, resultsFileName, filePath, fileName):
|
def double_check(branch, commit, args, executableName, md5sum, compilerVersion, resultsFileName, filePath, fileName):
|
||||||
last_commit, csize, cspeed, dspeed = get_last_results(resultsFileName)
|
last_commit, csize, cspeed, dspeed = get_last_results(resultsFileName)
|
||||||
if not args.dry_run:
|
if not args.dry_run:
|
||||||
text = benchmark_and_compare(branch, commit, last_commit, args, executableName, md5sum, resultsFileName, filePath, fileName, csize, cspeed, dspeed)
|
text = benchmark_and_compare(branch, commit, last_commit, args, executableName, md5sum, compilerVersion, resultsFileName, filePath, fileName, csize, cspeed, dspeed)
|
||||||
if text:
|
if text:
|
||||||
log("WARNING: redoing tests for branch %s: commit %s" % (branch, commit))
|
log("WARNING: redoing tests for branch %s: commit %s" % (branch, commit))
|
||||||
text = benchmark_and_compare(branch, commit, last_commit, args, executableName, md5sum, resultsFileName, filePath, fileName, csize, cspeed, dspeed)
|
text = benchmark_and_compare(branch, commit, last_commit, args, executableName, md5sum, compilerVersion, resultsFileName, filePath, fileName, csize, cspeed, dspeed)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
@@ -187,29 +204,38 @@ def test_commit(branch, commit, last_commit, args, testFilePaths, have_mutt, hav
|
|||||||
if not args.dry_run:
|
if not args.dry_run:
|
||||||
execute('make -C programs clean zstd CC=clang MOREFLAGS="-Werror -Wconversion -Wno-sign-conversion -DZSTD_GIT_COMMIT=%s" && ' % version +
|
execute('make -C programs clean zstd CC=clang MOREFLAGS="-Werror -Wconversion -Wno-sign-conversion -DZSTD_GIT_COMMIT=%s" && ' % version +
|
||||||
'mv programs/zstd programs/zstd_clang && ' +
|
'mv programs/zstd programs/zstd_clang && ' +
|
||||||
'make -C programs clean zstd MOREFLAGS="-DZSTD_GIT_COMMIT=%s" && ' % version +
|
'make -C programs clean zstd zstd32 MOREFLAGS="-DZSTD_GIT_COMMIT=%s"' % version)
|
||||||
'make -B -C programs zstd32 MOREFLAGS="-DZSTD_GIT_COMMIT=%s"' % version)
|
|
||||||
md5_zstd = hashfile(hashlib.md5(), clone_path + '/programs/zstd')
|
md5_zstd = hashfile(hashlib.md5(), clone_path + '/programs/zstd')
|
||||||
md5_zstd32 = hashfile(hashlib.md5(), clone_path + '/programs/zstd32')
|
md5_zstd32 = hashfile(hashlib.md5(), clone_path + '/programs/zstd32')
|
||||||
md5_zstd_clang = hashfile(hashlib.md5(), clone_path + '/programs/zstd_clang')
|
md5_zstd_clang = hashfile(hashlib.md5(), clone_path + '/programs/zstd_clang')
|
||||||
print("md5(zstd)=%s\nmd5(zstd32)=%s\nmd5(zstd32_clang)=%s" % (md5_zstd, md5_zstd32, md5_zstd_clang))
|
print("md5(zstd)=%s\nmd5(zstd32)=%s\nmd5(zstd_clang)=%s" % (md5_zstd, md5_zstd32, md5_zstd_clang))
|
||||||
|
print("gcc_version=%s clang_version=%s" % (gcc_version, clang_version))
|
||||||
|
|
||||||
logFileName = working_path + "/log_" + branch.replace("/", "_") + ".txt"
|
logFileName = working_path + "/log_" + branch.replace("/", "_") + ".txt"
|
||||||
text_to_send = []
|
text_to_send = []
|
||||||
results_files = ""
|
results_files = ""
|
||||||
|
if args.dictionary:
|
||||||
|
dictName = args.dictionary.rpartition('/')[2]
|
||||||
|
else:
|
||||||
|
dictName = None
|
||||||
|
|
||||||
for filePath in testFilePaths:
|
for filePath in testFilePaths:
|
||||||
fileName = filePath.rpartition('/')[2]
|
fileName = filePath.rpartition('/')[2]
|
||||||
resultsFileName = working_path + "/results_" + branch.replace("/", "_") + "_" + fileName.replace(".", "_") + ".txt"
|
if dictName:
|
||||||
text = double_check(branch, commit, args, 'zstd', md5_zstd, resultsFileName, filePath, fileName)
|
resultsFileName = working_path + "/" + dictName.replace(".", "_") + "_" + branch.replace("/", "_") + "_" + fileName.replace(".", "_") + ".txt"
|
||||||
|
else:
|
||||||
|
resultsFileName = working_path + "/results_" + branch.replace("/", "_") + "_" + fileName.replace(".", "_") + ".txt"
|
||||||
|
text = double_check(branch, commit, args, 'zstd', md5_zstd, 'gcc_version='+gcc_version, resultsFileName, filePath, fileName)
|
||||||
if text:
|
if text:
|
||||||
text_to_send.append(text)
|
text_to_send.append(text)
|
||||||
results_files += resultsFileName + " "
|
results_files += resultsFileName + " "
|
||||||
resultsFileName = working_path + "/results32_" + branch.replace("/", "_") + "_" + fileName.replace(".", "_") + ".txt"
|
resultsFileName = working_path + "/results32_" + branch.replace("/", "_") + "_" + fileName.replace(".", "_") + ".txt"
|
||||||
text = double_check(branch, commit, args, 'zstd32', md5_zstd32, resultsFileName, filePath, fileName)
|
text = double_check(branch, commit, args, 'zstd32', md5_zstd32, 'gcc_version='+gcc_version, resultsFileName, filePath, fileName)
|
||||||
if text:
|
if text:
|
||||||
text_to_send.append(text)
|
text_to_send.append(text)
|
||||||
results_files += resultsFileName + " "
|
results_files += resultsFileName + " "
|
||||||
resultsFileName = working_path + "/resultsClang_" + branch.replace("/", "_") + "_" + fileName.replace(".", "_") + ".txt"
|
resultsFileName = working_path + "/resultsClang_" + branch.replace("/", "_") + "_" + fileName.replace(".", "_") + ".txt"
|
||||||
text = double_check(branch, commit, args, 'zstd_clang', md5_zstd_clang, resultsFileName, filePath, fileName)
|
text = double_check(branch, commit, args, 'zstd_clang', md5_zstd_clang, 'clang_version='+clang_version, resultsFileName, filePath, fileName)
|
||||||
if text:
|
if text:
|
||||||
text_to_send.append(text)
|
text_to_send.append(text)
|
||||||
results_files += resultsFileName + " "
|
results_files += resultsFileName + " "
|
||||||
@@ -219,17 +245,18 @@ def test_commit(branch, commit, last_commit, args, testFilePaths, have_mutt, hav
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('testFileNames', help='file names list for speed benchmark')
|
parser.add_argument('testFileNames', help='file or directory names list for speed benchmark')
|
||||||
parser.add_argument('emails', help='list of e-mail addresses to send warnings')
|
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('--dictionary', '-D', help='path to the dictionary')
|
||||||
|
parser.add_argument('--message', '-m', help='attach an additional message to e-mail', default="")
|
||||||
parser.add_argument('--repoURL', help='changes default repository URL', default=default_repo_url)
|
parser.add_argument('--repoURL', help='changes default repository URL', default=default_repo_url)
|
||||||
parser.add_argument('--lowerLimit', type=float, help='send email if speed is lower than given limit', default=0.98)
|
parser.add_argument('--lowerLimit', '-l', type=float, help='send email if speed is lower than given limit', default=0.98)
|
||||||
parser.add_argument('--ratioLimit', type=float, help='send email if ratio is lower than given limit', default=0.999)
|
parser.add_argument('--ratioLimit', '-r', type=float, help='send email if ratio is lower than given limit', default=0.999)
|
||||||
parser.add_argument('--maxLoadAvg', type=float, help='maximum load average to start testing', default=0.75)
|
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('--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('--sleepTime', '-s', 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)
|
parser.add_argument('--dry-run', dest='dry_run', action='store_true', help='not build', default=False)
|
||||||
parser.add_argument('--verbose', action='store_true', help='more verbose logs', default=False)
|
parser.add_argument('--verbose', '-v', action='store_true', help='more verbose logs', default=False)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
verbose = args.verbose
|
verbose = args.verbose
|
||||||
|
|
||||||
@@ -238,10 +265,17 @@ if __name__ == '__main__':
|
|||||||
testFilePaths = []
|
testFilePaths = []
|
||||||
for fileName in testFileNames:
|
for fileName in testFileNames:
|
||||||
fileName = os.path.expanduser(fileName)
|
fileName = os.path.expanduser(fileName)
|
||||||
if os.path.isfile(fileName):
|
if os.path.isfile(fileName) or os.path.isdir(fileName):
|
||||||
testFilePaths.append(os.path.abspath(fileName))
|
testFilePaths.append(os.path.abspath(fileName))
|
||||||
else:
|
else:
|
||||||
log("ERROR: File not found: " + fileName)
|
log("ERROR: File/directory not found: " + fileName)
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
# check if dictionary is accessible
|
||||||
|
if args.dictionary:
|
||||||
|
args.dictionary = os.path.abspath(os.path.expanduser(args.dictionary))
|
||||||
|
if not os.path.isfile(args.dictionary):
|
||||||
|
log("ERROR: Dictionary not found: " + args.dictionary)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
# check availability of e-mail senders
|
# check availability of e-mail senders
|
||||||
@@ -251,6 +285,9 @@ if __name__ == '__main__':
|
|||||||
log("ERROR: e-mail senders 'mail' or 'mutt' not found")
|
log("ERROR: e-mail senders 'mail' or 'mutt' not found")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
clang_version = execute("clang -v 2>&1 | grep 'clang version' | sed -e 's:.*version \\([0-9.]*\\).*:\\1:' -e 's:\\.\\([0-9][0-9]\\):\\1:g'", verbose)[0];
|
||||||
|
gcc_version = execute("gcc -dumpversion", verbose)[0];
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
print("PARAMETERS:\nrepoURL=%s" % args.repoURL)
|
print("PARAMETERS:\nrepoURL=%s" % args.repoURL)
|
||||||
print("working_path=%s" % working_path)
|
print("working_path=%s" % working_path)
|
||||||
@@ -258,6 +295,7 @@ if __name__ == '__main__':
|
|||||||
print("testFilePath(%s)=%s" % (len(testFilePaths), testFilePaths))
|
print("testFilePath(%s)=%s" % (len(testFilePaths), testFilePaths))
|
||||||
print("message=%s" % args.message)
|
print("message=%s" % args.message)
|
||||||
print("emails=%s" % args.emails)
|
print("emails=%s" % args.emails)
|
||||||
|
print("dictionary=%s" % args.dictionary)
|
||||||
print("maxLoadAvg=%s" % args.maxLoadAvg)
|
print("maxLoadAvg=%s" % args.maxLoadAvg)
|
||||||
print("lowerLimit=%s" % args.lowerLimit)
|
print("lowerLimit=%s" % args.lowerLimit)
|
||||||
print("ratioLimit=%s" % args.ratioLimit)
|
print("ratioLimit=%s" % args.ratioLimit)
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""Test zstd interoperability between versions"""
|
"""Test zstd interoperability between versions"""
|
||||||
# Based on LZ4 version test script, by Takayuki Matsuoka
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This source code is licensed under the BSD-style license found in the
|
||||||
|
# LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
# of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
#
|
||||||
|
|
||||||
import filecmp
|
import filecmp
|
||||||
import glob
|
import glob
|
||||||
@@ -11,7 +19,7 @@ import sys
|
|||||||
import subprocess
|
import subprocess
|
||||||
from subprocess import Popen, PIPE
|
from subprocess import Popen, PIPE
|
||||||
|
|
||||||
repo_url = 'https://github.com/Cyan4973/zstd.git'
|
repo_url = 'https://github.com/facebook/zstd.git'
|
||||||
tmp_dir_name = 'tests/versionsTest'
|
tmp_dir_name = 'tests/versionsTest'
|
||||||
make_cmd = 'make'
|
make_cmd = 'make'
|
||||||
git_cmd = 'git'
|
git_cmd = 'git'
|
||||||
@@ -152,6 +160,7 @@ def decompress_zst(tag):
|
|||||||
print('OK ')
|
print('OK ')
|
||||||
else:
|
else:
|
||||||
print('command does not work')
|
print('command does not work')
|
||||||
|
dec_error = 1
|
||||||
return dec_error
|
return dec_error
|
||||||
|
|
||||||
|
|
||||||
@@ -203,7 +212,8 @@ if __name__ == '__main__':
|
|||||||
# Retrieve all release tags
|
# Retrieve all release tags
|
||||||
print('Retrieve all release tags :')
|
print('Retrieve all release tags :')
|
||||||
os.chdir(clone_dir)
|
os.chdir(clone_dir)
|
||||||
tags = get_git_tags() + [head]
|
alltags = get_git_tags() + [head]
|
||||||
|
tags = [t for t in alltags if t >= 'v0.4.0']
|
||||||
print(tags)
|
print(tags)
|
||||||
|
|
||||||
# Build all release zstd
|
# Build all release zstd
|
||||||
@@ -261,6 +271,6 @@ if __name__ == '__main__':
|
|||||||
print(zstd + ' : ' + repr(os.path.getsize(zstd)) + ', ' + sha1_of_file(zstd))
|
print(zstd + ' : ' + repr(os.path.getsize(zstd)) + ', ' + sha1_of_file(zstd))
|
||||||
|
|
||||||
if error_code != 0:
|
if error_code != 0:
|
||||||
print('==== ERROR !!! =====')
|
print('====== ERROR !!! =======')
|
||||||
|
|
||||||
sys.exit(error_code)
|
sys.exit(error_code)
|
||||||
|
|||||||
@@ -1,26 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
Fuzzer test tool for zstd_buffered
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2015-2016
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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 : https://www.zstd.net/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-************************************
|
/*-************************************
|
||||||
* Compiler specific
|
* Compiler specific
|
||||||
@@ -37,7 +23,7 @@
|
|||||||
**************************************/
|
**************************************/
|
||||||
#include <stdlib.h> /* free */
|
#include <stdlib.h> /* free */
|
||||||
#include <stdio.h> /* fgets, sscanf */
|
#include <stdio.h> /* fgets, sscanf */
|
||||||
#include <sys/timeb.h> /* timeb */
|
#include <time.h> /* clock_t, clock() */
|
||||||
#include <string.h> /* strcmp */
|
#include <string.h> /* strcmp */
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_maxCLevel */
|
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_maxCLevel */
|
||||||
@@ -72,13 +58,13 @@ static const U32 prime2 = 2246822519U;
|
|||||||
static U32 g_displayLevel = 2;
|
static U32 g_displayLevel = 2;
|
||||||
|
|
||||||
#define DISPLAYUPDATE(l, ...) if (g_displayLevel>=l) { \
|
#define DISPLAYUPDATE(l, ...) if (g_displayLevel>=l) { \
|
||||||
if ((FUZ_GetMilliSpan(g_displayTime) > g_refreshRate) || (g_displayLevel>=4)) \
|
if ((FUZ_GetClockSpan(g_displayClock) > g_refreshRate) || (g_displayLevel>=4)) \
|
||||||
{ g_displayTime = FUZ_GetMilliStart(); DISPLAY(__VA_ARGS__); \
|
{ g_displayClock = clock(); DISPLAY(__VA_ARGS__); \
|
||||||
if (g_displayLevel>=4) fflush(stdout); } }
|
if (g_displayLevel>=4) fflush(stdout); } }
|
||||||
static const U32 g_refreshRate = 150;
|
static const clock_t g_refreshRate = CLOCKS_PER_SEC * 15 / 100;
|
||||||
static U32 g_displayTime = 0;
|
static clock_t g_displayClock = 0;
|
||||||
|
|
||||||
static U32 g_testTime = 0;
|
static clock_t g_clockTime = 0;
|
||||||
|
|
||||||
|
|
||||||
/*-*******************************************************
|
/*-*******************************************************
|
||||||
@@ -86,23 +72,9 @@ static U32 g_testTime = 0;
|
|||||||
*********************************************************/
|
*********************************************************/
|
||||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||||
|
|
||||||
static U32 FUZ_GetMilliStart(void)
|
static clock_t FUZ_GetClockSpan(clock_t clockStart)
|
||||||
{
|
{
|
||||||
struct timeb tb;
|
return clock() - clockStart; /* works even when overflow. Max span ~ 30 mn */
|
||||||
U32 nCount;
|
|
||||||
ftime( &tb );
|
|
||||||
nCount = (U32) (((tb.time & 0xFFFFF) * 1000) + tb.millitm);
|
|
||||||
return nCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static U32 FUZ_GetMilliSpan(U32 nTimeStart)
|
|
||||||
{
|
|
||||||
U32 const nCurrent = FUZ_GetMilliStart();
|
|
||||||
U32 nSpan = nCurrent - nTimeStart;
|
|
||||||
if (nTimeStart > nCurrent)
|
|
||||||
nSpan += 0x100000 * 1000;
|
|
||||||
return nSpan;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! FUZ_rand() :
|
/*! FUZ_rand() :
|
||||||
@@ -183,7 +155,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
|
|||||||
cSize += genSize;
|
cSize += genSize;
|
||||||
genSize = compressedBufferSize - cSize;
|
genSize = compressedBufferSize - cSize;
|
||||||
{ size_t const r = ZBUFF_compressEnd(zc, ((char*)compressedBuffer)+cSize, &genSize);
|
{ size_t const r = ZBUFF_compressEnd(zc, ((char*)compressedBuffer)+cSize, &genSize);
|
||||||
if (r != 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);
|
||||||
|
|
||||||
@@ -305,7 +277,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
|
|||||||
U32 coreSeed = seed;
|
U32 coreSeed = seed;
|
||||||
ZBUFF_CCtx* zc;
|
ZBUFF_CCtx* zc;
|
||||||
ZBUFF_DCtx* zd;
|
ZBUFF_DCtx* zd;
|
||||||
U32 startTime = FUZ_GetMilliStart();
|
clock_t startClock = clock();
|
||||||
|
|
||||||
/* allocations */
|
/* allocations */
|
||||||
zc = ZBUFF_createCCtx();
|
zc = ZBUFF_createCCtx();
|
||||||
@@ -335,7 +307,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
|
|||||||
FUZ_rand(&coreSeed);
|
FUZ_rand(&coreSeed);
|
||||||
|
|
||||||
/* test loop */
|
/* test loop */
|
||||||
for ( ; (testNb <= nbTests) || (FUZ_GetMilliSpan(startTime) < g_testTime) ; testNb++ ) {
|
for ( ; (testNb <= nbTests) || (FUZ_GetClockSpan(startClock) < g_clockTime) ; testNb++ ) {
|
||||||
U32 lseed;
|
U32 lseed;
|
||||||
const BYTE* srcBuffer;
|
const BYTE* srcBuffer;
|
||||||
const BYTE* dict;
|
const BYTE* dict;
|
||||||
@@ -557,7 +529,7 @@ int main(int argc, const char** argv)
|
|||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
argument++;
|
argument++;
|
||||||
nbTests=0; g_testTime=0;
|
nbTests=0; g_clockTime=0;
|
||||||
while ((*argument>='0') && (*argument<='9')) {
|
while ((*argument>='0') && (*argument<='9')) {
|
||||||
nbTests *= 10;
|
nbTests *= 10;
|
||||||
nbTests += *argument - '0';
|
nbTests += *argument - '0';
|
||||||
@@ -567,15 +539,15 @@ int main(int argc, const char** argv)
|
|||||||
|
|
||||||
case 'T':
|
case 'T':
|
||||||
argument++;
|
argument++;
|
||||||
nbTests=0; g_testTime=0;
|
nbTests=0; g_clockTime=0;
|
||||||
while ((*argument>='0') && (*argument<='9')) {
|
while ((*argument>='0') && (*argument<='9')) {
|
||||||
g_testTime *= 10;
|
g_clockTime *= 10;
|
||||||
g_testTime += *argument - '0';
|
g_clockTime += *argument - '0';
|
||||||
argument++;
|
argument++;
|
||||||
}
|
}
|
||||||
if (*argument=='m') g_testTime *=60, argument++;
|
if (*argument=='m') g_clockTime *=60, argument++;
|
||||||
if (*argument=='n') argument++;
|
if (*argument=='n') argument++;
|
||||||
g_testTime *= 1000;
|
g_clockTime *= CLOCKS_PER_SEC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
@@ -619,7 +591,11 @@ int main(int argc, const char** argv)
|
|||||||
/* Get Seed */
|
/* Get Seed */
|
||||||
DISPLAY("Starting zstd_buffered tester (%i-bits, %s)\n", (int)(sizeof(size_t)*8), ZSTD_VERSION_STRING);
|
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) {
|
||||||
|
time_t const t = time(NULL);
|
||||||
|
U32 const h = XXH32(&t, sizeof(t), 1);
|
||||||
|
seed = h % 10000;
|
||||||
|
}
|
||||||
DISPLAY("Seed = %u\n", seed);
|
DISPLAY("Seed = %u\n", seed);
|
||||||
if (proba!=FUZ_COMPRESSIBILITY_DEFAULT) DISPLAY("Compressibility : %i%%\n", proba);
|
if (proba!=FUZ_COMPRESSIBILITY_DEFAULT) DISPLAY("Compressibility : %i%%\n", proba);
|
||||||
|
|
||||||
@@ -1,26 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
Fuzzer test tool for zstd streaming API
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||||
Copyright (C) Yann Collet 2016
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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 : https://www.zstd.net/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-************************************
|
/*-************************************
|
||||||
* Compiler specific
|
* Compiler specific
|
||||||
@@ -37,13 +23,13 @@
|
|||||||
**************************************/
|
**************************************/
|
||||||
#include <stdlib.h> /* free */
|
#include <stdlib.h> /* free */
|
||||||
#include <stdio.h> /* fgets, sscanf */
|
#include <stdio.h> /* fgets, sscanf */
|
||||||
#include <sys/timeb.h> /* timeb */
|
#include <time.h> /* clock_t, clock() */
|
||||||
#include <string.h> /* strcmp */
|
#include <string.h> /* strcmp */
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_maxCLevel */
|
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_maxCLevel, ZSTD_customMem */
|
||||||
#include "zstd.h" /* ZSTD_compressBound */
|
#include "zstd.h" /* ZSTD_compressBound */
|
||||||
#include "datagen.h" /* RDG_genBuffer */
|
#include "datagen.h" /* RDG_genBuffer */
|
||||||
#define XXH_STATIC_LINKING_ONLY
|
#define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
|
||||||
#include "xxhash.h" /* XXH64_* */
|
#include "xxhash.h" /* XXH64_* */
|
||||||
|
|
||||||
|
|
||||||
@@ -61,7 +47,6 @@ static const U32 prime1 = 2654435761U;
|
|||||||
static const U32 prime2 = 2246822519U;
|
static const U32 prime2 = 2246822519U;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-************************************
|
/*-************************************
|
||||||
* Display Macros
|
* Display Macros
|
||||||
**************************************/
|
**************************************/
|
||||||
@@ -70,13 +55,13 @@ static const U32 prime2 = 2246822519U;
|
|||||||
static U32 g_displayLevel = 2;
|
static U32 g_displayLevel = 2;
|
||||||
|
|
||||||
#define DISPLAYUPDATE(l, ...) if (g_displayLevel>=l) { \
|
#define DISPLAYUPDATE(l, ...) if (g_displayLevel>=l) { \
|
||||||
if ((FUZ_GetMilliSpan(g_displayTime) > g_refreshRate) || (g_displayLevel>=4)) \
|
if ((FUZ_GetClockSpan(g_displayClock) > g_refreshRate) || (g_displayLevel>=4)) \
|
||||||
{ g_displayTime = FUZ_GetMilliStart(); DISPLAY(__VA_ARGS__); \
|
{ g_displayClock = clock(); DISPLAY(__VA_ARGS__); \
|
||||||
if (g_displayLevel>=4) fflush(stdout); } }
|
if (g_displayLevel>=4) fflush(stdout); } }
|
||||||
static const U32 g_refreshRate = 150;
|
static const clock_t g_refreshRate = CLOCKS_PER_SEC / 6;
|
||||||
static U32 g_displayTime = 0;
|
static clock_t g_displayClock = 0;
|
||||||
|
|
||||||
static U32 g_testTime = 0;
|
static clock_t g_clockTime = 0;
|
||||||
|
|
||||||
|
|
||||||
/*-*******************************************************
|
/*-*******************************************************
|
||||||
@@ -84,23 +69,9 @@ static U32 g_testTime = 0;
|
|||||||
*********************************************************/
|
*********************************************************/
|
||||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||||
|
|
||||||
static U32 FUZ_GetMilliStart(void)
|
static clock_t FUZ_GetClockSpan(clock_t clockStart)
|
||||||
{
|
{
|
||||||
struct timeb tb;
|
return clock() - clockStart; /* works even when overflow. Max span ~ 30 mn */
|
||||||
U32 nCount;
|
|
||||||
ftime( &tb );
|
|
||||||
nCount = (U32) (((tb.time & 0xFFFFF) * 1000) + tb.millitm);
|
|
||||||
return nCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static U32 FUZ_GetMilliSpan(U32 nTimeStart)
|
|
||||||
{
|
|
||||||
U32 const nCurrent = FUZ_GetMilliStart();
|
|
||||||
U32 nSpan = nCurrent - nTimeStart;
|
|
||||||
if (nTimeStart > nCurrent)
|
|
||||||
nSpan += 0x100000 * 1000;
|
|
||||||
return nSpan;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! FUZ_rand() :
|
/*! FUZ_rand() :
|
||||||
@@ -117,7 +88,6 @@ unsigned int FUZ_rand(unsigned int* seedPtr)
|
|||||||
return rand32 >> 5;
|
return rand32 >> 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static unsigned FUZ_highbit32(U32 v32)
|
static unsigned FUZ_highbit32(U32 v32)
|
||||||
{
|
{
|
||||||
@@ -141,10 +111,14 @@ static void freeFunction(void* opaque, void* address)
|
|||||||
free(address);
|
free(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*======================================================
|
||||||
|
* Basic Unit tests
|
||||||
|
======================================================*/
|
||||||
|
|
||||||
static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem customMem)
|
static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem customMem)
|
||||||
{
|
{
|
||||||
int testResult = 0;
|
size_t const CNBufferSize = COMPRESSIBLE_NOISE_LENGTH;
|
||||||
size_t CNBufferSize = COMPRESSIBLE_NOISE_LENGTH;
|
|
||||||
void* CNBuffer = malloc(CNBufferSize);
|
void* CNBuffer = malloc(CNBufferSize);
|
||||||
size_t const skippableFrameSize = 11;
|
size_t const skippableFrameSize = 11;
|
||||||
size_t const compressedBufferSize = (8 + skippableFrameSize) + ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH);
|
size_t const compressedBufferSize = (8 + skippableFrameSize) + ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH);
|
||||||
@@ -152,6 +126,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
|
|||||||
size_t const decodedBufferSize = CNBufferSize;
|
size_t const decodedBufferSize = CNBufferSize;
|
||||||
void* decodedBuffer = malloc(decodedBufferSize);
|
void* decodedBuffer = malloc(decodedBufferSize);
|
||||||
size_t cSize;
|
size_t cSize;
|
||||||
|
int testResult = 0;
|
||||||
U32 testNb=0;
|
U32 testNb=0;
|
||||||
ZSTD_CStream* zc = ZSTD_createCStream_advanced(customMem);
|
ZSTD_CStream* zc = ZSTD_createCStream_advanced(customMem);
|
||||||
ZSTD_DStream* zd = ZSTD_createDStream_advanced(customMem);
|
ZSTD_DStream* zd = ZSTD_createDStream_advanced(customMem);
|
||||||
@@ -183,10 +158,16 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
|
|||||||
if (ZSTD_isError(r)) goto _output_error; }
|
if (ZSTD_isError(r)) goto _output_error; }
|
||||||
if (inBuff.pos != inBuff.size) goto _output_error; /* entire input should be consumed */
|
if (inBuff.pos != inBuff.size) goto _output_error; /* entire input should be consumed */
|
||||||
{ size_t const r = ZSTD_endStream(zc, &outBuff);
|
{ size_t const r = ZSTD_endStream(zc, &outBuff);
|
||||||
if (r != 0) goto _output_error; } /*< error, or some data not flushed */
|
if (r != 0) goto _output_error; } /* error, or some data not flushed */
|
||||||
cSize += outBuff.pos;
|
cSize += outBuff.pos;
|
||||||
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);
|
||||||
|
|
||||||
|
DISPLAYLEVEL(4, "test%3i : check CStream size : ", testNb++);
|
||||||
|
{ size_t const s = ZSTD_sizeof_CStream(zc);
|
||||||
|
if (ZSTD_isError(s)) goto _output_error;
|
||||||
|
DISPLAYLEVEL(4, "OK (%u bytes) \n", (U32)s);
|
||||||
|
}
|
||||||
|
|
||||||
/* skippable frame test */
|
/* skippable frame test */
|
||||||
DISPLAYLEVEL(4, "test%3i : decompress skippable frame : ", testNb++);
|
DISPLAYLEVEL(4, "test%3i : decompress skippable frame : ", testNb++);
|
||||||
ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
|
ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
|
||||||
@@ -204,6 +185,8 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
|
|||||||
/* 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);
|
||||||
ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
|
ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
|
||||||
|
{ size_t const r = ZSTD_setDStreamParameter(zd, ZSTDdsp_maxWindowSize, 1000000000); /* large limit */
|
||||||
|
if (ZSTD_isError(r)) goto _output_error; }
|
||||||
{ size_t const r = ZSTD_decompressStream(zd, &outBuff, &inBuff);
|
{ size_t const r = ZSTD_decompressStream(zd, &outBuff, &inBuff);
|
||||||
if (r != 0) goto _output_error; } /* should reach end of frame == 0; otherwise, some data left, or an error */
|
if (r != 0) goto _output_error; } /* should reach end of frame == 0; otherwise, some data left, or an error */
|
||||||
if (outBuff.pos != CNBufferSize) goto _output_error; /* should regenerate the same amount */
|
if (outBuff.pos != CNBufferSize) goto _output_error; /* should regenerate the same amount */
|
||||||
@@ -218,9 +201,16 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
|
|||||||
} }
|
} }
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
|
DISPLAYLEVEL(4, "test%3i : check DStream size : ", testNb++);
|
||||||
|
{ size_t const s = ZSTD_sizeof_DStream(zd);
|
||||||
|
if (ZSTD_isError(s)) goto _output_error;
|
||||||
|
DISPLAYLEVEL(4, "OK (%u bytes) \n", (U32)s);
|
||||||
|
}
|
||||||
|
|
||||||
/* 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++);
|
||||||
{ size_t r = 1;
|
{ /* skippable frame */
|
||||||
|
size_t r = 1;
|
||||||
ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
|
ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
|
||||||
inBuff.src = compressedBuffer;
|
inBuff.src = compressedBuffer;
|
||||||
outBuff.dst = decodedBuffer;
|
outBuff.dst = decodedBuffer;
|
||||||
@@ -232,9 +222,10 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
|
|||||||
r = ZSTD_decompressStream(zd, &outBuff, &inBuff);
|
r = ZSTD_decompressStream(zd, &outBuff, &inBuff);
|
||||||
if (ZSTD_isError(r)) goto _output_error;
|
if (ZSTD_isError(r)) goto _output_error;
|
||||||
}
|
}
|
||||||
|
/* normal frame */
|
||||||
ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
|
ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
|
||||||
r=1;
|
r=1;
|
||||||
while (r) { /* normal frame */
|
while (r) {
|
||||||
inBuff.size = inBuff.pos + 1;
|
inBuff.size = inBuff.pos + 1;
|
||||||
outBuff.size = outBuff.pos + 1;
|
outBuff.size = outBuff.pos + 1;
|
||||||
r = ZSTD_decompressStream(zd, &outBuff, &inBuff);
|
r = ZSTD_decompressStream(zd, &outBuff, &inBuff);
|
||||||
@@ -253,6 +244,71 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
|
|||||||
} }
|
} }
|
||||||
DISPLAYLEVEL(4, "OK \n");
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
|
/* Complex context re-use scenario */
|
||||||
|
DISPLAYLEVEL(4, "test%3i : context re-use : ", testNb++);
|
||||||
|
ZSTD_freeCStream(zc);
|
||||||
|
zc = ZSTD_createCStream_advanced(customMem);
|
||||||
|
if (zc==NULL) goto _output_error; /* memory allocation issue */
|
||||||
|
/* use 1 */
|
||||||
|
{ size_t const inSize = 513;
|
||||||
|
ZSTD_initCStream_advanced(zc, NULL, 0, ZSTD_getParams(19, inSize, 0), inSize); /* needs btopt + search3 to trigger hashLog3 */
|
||||||
|
inBuff.src = CNBuffer;
|
||||||
|
inBuff.size = inSize;
|
||||||
|
inBuff.pos = 0;
|
||||||
|
outBuff.dst = (char*)(compressedBuffer)+cSize;
|
||||||
|
outBuff.size = ZSTD_compressBound(inSize);
|
||||||
|
outBuff.pos = 0;
|
||||||
|
{ size_t const r = ZSTD_compressStream(zc, &outBuff, &inBuff);
|
||||||
|
if (ZSTD_isError(r)) goto _output_error; }
|
||||||
|
if (inBuff.pos != inBuff.size) goto _output_error; /* entire input should be consumed */
|
||||||
|
{ size_t const r = ZSTD_endStream(zc, &outBuff);
|
||||||
|
if (r != 0) goto _output_error; } /* error, or some data not flushed */
|
||||||
|
}
|
||||||
|
/* use 2 */
|
||||||
|
{ size_t const inSize = 1025; /* will not continue, because tables auto-adjust and are therefore different size */
|
||||||
|
ZSTD_initCStream_advanced(zc, NULL, 0, ZSTD_getParams(19, inSize, 0), inSize); /* needs btopt + search3 to trigger hashLog3 */
|
||||||
|
inBuff.src = CNBuffer;
|
||||||
|
inBuff.size = inSize;
|
||||||
|
inBuff.pos = 0;
|
||||||
|
outBuff.dst = (char*)(compressedBuffer)+cSize;
|
||||||
|
outBuff.size = ZSTD_compressBound(inSize);
|
||||||
|
outBuff.pos = 0;
|
||||||
|
{ size_t const r = ZSTD_compressStream(zc, &outBuff, &inBuff);
|
||||||
|
if (ZSTD_isError(r)) goto _output_error; }
|
||||||
|
if (inBuff.pos != inBuff.size) goto _output_error; /* entire input should be consumed */
|
||||||
|
{ size_t const r = ZSTD_endStream(zc, &outBuff);
|
||||||
|
if (r != 0) goto _output_error; } /* error, or some data not flushed */
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
|
DISPLAYLEVEL(4, "test%3i : check CStream size : ", testNb++);
|
||||||
|
{ size_t const s = ZSTD_sizeof_CStream(zc);
|
||||||
|
if (ZSTD_isError(s)) goto _output_error;
|
||||||
|
DISPLAYLEVEL(4, "OK (%u bytes) \n", (U32)s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* test ZSTD_setDStreamParameter() resilience */
|
||||||
|
DISPLAYLEVEL(4, "test%3i : wrong parameter for ZSTD_setDStreamParameter(): ", testNb++);
|
||||||
|
{ size_t const r = ZSTD_setDStreamParameter(zd, (ZSTD_DStreamParameter_e)999, 1); /* large limit */
|
||||||
|
if (!ZSTD_isError(r)) goto _output_error; }
|
||||||
|
DISPLAYLEVEL(4, "OK \n");
|
||||||
|
|
||||||
|
/* Memory restriction */
|
||||||
|
DISPLAYLEVEL(4, "test%3i : maxWindowSize < frame requirement : ", testNb++);
|
||||||
|
ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
|
||||||
|
{ size_t const r = ZSTD_setDStreamParameter(zd, ZSTDdsp_maxWindowSize, 1000); /* too small limit */
|
||||||
|
if (ZSTD_isError(r)) goto _output_error; }
|
||||||
|
inBuff.src = compressedBuffer;
|
||||||
|
inBuff.size = cSize;
|
||||||
|
inBuff.pos = 0;
|
||||||
|
outBuff.dst = decodedBuffer;
|
||||||
|
outBuff.size = CNBufferSize;
|
||||||
|
outBuff.pos = 0;
|
||||||
|
{ size_t const r = ZSTD_decompressStream(zd, &outBuff, &inBuff);
|
||||||
|
if (!ZSTD_isError(r)) goto _output_error; /* must fail : frame requires > 100 bytes */
|
||||||
|
DISPLAYLEVEL(4, "OK (%s)\n", ZSTD_getErrorName(r)); }
|
||||||
|
|
||||||
|
|
||||||
_end:
|
_end:
|
||||||
ZSTD_freeCStream(zc);
|
ZSTD_freeCStream(zc);
|
||||||
ZSTD_freeDStream(zd);
|
ZSTD_freeDStream(zd);
|
||||||
@@ -268,6 +324,8 @@ _output_error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ====== Fuzzer tests ====== */
|
||||||
|
|
||||||
static size_t findDiff(const void* buf1, const void* buf2, size_t max)
|
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;
|
||||||
@@ -300,34 +358,33 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
|
|||||||
{
|
{
|
||||||
static const U32 maxSrcLog = 24;
|
static const U32 maxSrcLog = 24;
|
||||||
static const U32 maxSampleLog = 19;
|
static const U32 maxSampleLog = 19;
|
||||||
|
size_t const srcBufferSize = (size_t)1<<maxSrcLog;
|
||||||
BYTE* cNoiseBuffer[5];
|
BYTE* cNoiseBuffer[5];
|
||||||
size_t srcBufferSize = (size_t)1<<maxSrcLog;
|
size_t const copyBufferSize= srcBufferSize + (1<<maxSampleLog);
|
||||||
BYTE* copyBuffer;
|
BYTE* const copyBuffer = (BYTE*)malloc (copyBufferSize);
|
||||||
size_t copyBufferSize= srcBufferSize + (1<<maxSampleLog);
|
size_t const cBufferSize = ZSTD_compressBound(srcBufferSize);
|
||||||
BYTE* cBuffer;
|
BYTE* const cBuffer = (BYTE*)malloc (cBufferSize);
|
||||||
size_t cBufferSize = ZSTD_compressBound(srcBufferSize);
|
size_t const dstBufferSize = srcBufferSize;
|
||||||
BYTE* dstBuffer;
|
BYTE* const dstBuffer = (BYTE*)malloc (dstBufferSize);
|
||||||
size_t dstBufferSize = srcBufferSize;
|
|
||||||
U32 result = 0;
|
U32 result = 0;
|
||||||
U32 testNb = 0;
|
U32 testNb = 0;
|
||||||
U32 coreSeed = seed;
|
U32 coreSeed = seed;
|
||||||
ZSTD_CStream* zc;
|
ZSTD_CStream* zc = ZSTD_createCStream(); /* will be reset sometimes */
|
||||||
ZSTD_DStream* zd;
|
ZSTD_DStream* zd = ZSTD_createDStream(); /* will be reset sometimes */
|
||||||
U32 startTime = FUZ_GetMilliStart();
|
ZSTD_DStream* const zd_noise = ZSTD_createDStream();
|
||||||
|
clock_t const startClock = clock();
|
||||||
|
const BYTE* dict=NULL; /* can keep same dict on 2 consecutive tests */
|
||||||
|
size_t dictSize = 0;
|
||||||
|
U32 oldTestLog = 0;
|
||||||
|
|
||||||
/* allocations */
|
/* allocations */
|
||||||
zc = ZSTD_createCStream();
|
|
||||||
zd = ZSTD_createDStream();
|
|
||||||
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);
|
||||||
copyBuffer= (BYTE*)malloc (copyBufferSize);
|
|
||||||
dstBuffer = (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] ||
|
||||||
!copyBuffer || !dstBuffer || !cBuffer || !zc || !zd,
|
!copyBuffer || !dstBuffer || !cBuffer || !zc || !zd || !zd_noise ,
|
||||||
"Not enough memory, fuzzer tests cancelled");
|
"Not enough memory, fuzzer tests cancelled");
|
||||||
|
|
||||||
/* Create initial samples */
|
/* Create initial samples */
|
||||||
@@ -337,21 +394,21 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
|
|||||||
RDG_genBuffer(cNoiseBuffer[3], srcBufferSize, 0.95, 0., coreSeed); /* highly compressible */
|
RDG_genBuffer(cNoiseBuffer[3], srcBufferSize, 0.95, 0., coreSeed); /* highly compressible */
|
||||||
RDG_genBuffer(cNoiseBuffer[4], srcBufferSize, 1.00, 0., coreSeed); /* sparse content */
|
RDG_genBuffer(cNoiseBuffer[4], srcBufferSize, 1.00, 0., coreSeed); /* sparse content */
|
||||||
memset(copyBuffer, 0x65, copyBufferSize); /* make copyBuffer considered initialized */
|
memset(copyBuffer, 0x65, copyBufferSize); /* make copyBuffer considered initialized */
|
||||||
|
ZSTD_initDStream_usingDict(zd, NULL, 0); /* ensure at least one init */
|
||||||
|
|
||||||
/* catch up testNb */
|
/* catch up testNb */
|
||||||
for (testNb=1; testNb < startTest; testNb++)
|
for (testNb=1; testNb < startTest; testNb++)
|
||||||
FUZ_rand(&coreSeed);
|
FUZ_rand(&coreSeed);
|
||||||
|
|
||||||
/* test loop */
|
/* test loop */
|
||||||
for ( ; (testNb <= nbTests) || (FUZ_GetMilliSpan(startTime) < g_testTime) ; testNb++ ) {
|
for ( ; (testNb <= nbTests) || (FUZ_GetClockSpan(startClock) < g_clockTime) ; testNb++ ) {
|
||||||
U32 lseed;
|
U32 lseed;
|
||||||
const BYTE* srcBuffer;
|
const BYTE* srcBuffer;
|
||||||
const BYTE* dict;
|
size_t totalTestSize, totalGenSize, cSize;
|
||||||
size_t maxTestSize, dictSize;
|
|
||||||
size_t cSize, totalTestSize, totalGenSize;
|
|
||||||
U32 n, nbChunks;
|
|
||||||
XXH64_state_t xxhState;
|
XXH64_state_t xxhState;
|
||||||
U64 crcOrig;
|
U64 crcOrig;
|
||||||
|
U32 resetAllowed = 1;
|
||||||
|
size_t maxTestSize;
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
DISPLAYUPDATE(2, "\r%6u", testNb);
|
DISPLAYUPDATE(2, "\r%6u", testNb);
|
||||||
@@ -359,10 +416,10 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
|
|||||||
FUZ_rand(&coreSeed);
|
FUZ_rand(&coreSeed);
|
||||||
lseed = coreSeed ^ prime1;
|
lseed = coreSeed ^ prime1;
|
||||||
|
|
||||||
/* states full reset (unsynchronized) */
|
/* states full reset (deliberately not synchronized) */
|
||||||
/* some issues only happen when reusing states in a specific sequence of parameters */
|
/* some issues can only happen when reusing states */
|
||||||
if ((FUZ_rand(&lseed) & 0xFF) == 131) { ZSTD_freeCStream(zc); zc = ZSTD_createCStream(); }
|
if ((FUZ_rand(&lseed) & 0xFF) == 131) { ZSTD_freeCStream(zc); zc = ZSTD_createCStream(); resetAllowed=0; }
|
||||||
if ((FUZ_rand(&lseed) & 0xFF) == 132) { ZSTD_freeDStream(zd); zd = ZSTD_createDStream(); }
|
if ((FUZ_rand(&lseed) & 0xFF) == 132) { ZSTD_freeDStream(zd); zd = ZSTD_createDStream(); ZSTD_initDStream_usingDict(zd, NULL, 0); /* ensure at least one init */ }
|
||||||
|
|
||||||
/* srcBuffer selection [0-4] */
|
/* srcBuffer selection [0-4] */
|
||||||
{ U32 buffNb = FUZ_rand(&lseed) & 0x7F;
|
{ U32 buffNb = FUZ_rand(&lseed) & 0x7F;
|
||||||
@@ -380,32 +437,44 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* compression init */
|
/* compression init */
|
||||||
{ U32 const testLog = FUZ_rand(&lseed) % maxSrcLog;
|
if ((FUZ_rand(&lseed)&1) /* at beginning, to keep same nb of rand */
|
||||||
|
&& oldTestLog /* at least one test happened */ && resetAllowed) {
|
||||||
|
maxTestSize = FUZ_randomLength(&lseed, oldTestLog+2);
|
||||||
|
if (maxTestSize >= srcBufferSize) maxTestSize = srcBufferSize-1;
|
||||||
|
{ U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? 0 : maxTestSize;
|
||||||
|
size_t const resetError = ZSTD_resetCStream(zc, pledgedSrcSize);
|
||||||
|
CHECK(ZSTD_isError(resetError), "ZSTD_resetCStream error : %s", ZSTD_getErrorName(resetError));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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;
|
oldTestLog = testLog;
|
||||||
/* random dictionary selection */
|
/* random dictionary selection */
|
||||||
|
dictSize = ((FUZ_rand(&lseed)&63)==1) ? FUZ_randomLength(&lseed, maxSampleLog) : 0;
|
||||||
{ size_t const dictStart = FUZ_rand(&lseed) % (srcBufferSize - dictSize);
|
{ size_t const dictStart = FUZ_rand(&lseed) % (srcBufferSize - dictSize);
|
||||||
dict = srcBuffer + dictStart;
|
dict = srcBuffer + dictStart;
|
||||||
}
|
}
|
||||||
{ ZSTD_parameters params = ZSTD_getParams(cLevel, 0, dictSize);
|
{ U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? 0 : maxTestSize;
|
||||||
|
ZSTD_parameters params = ZSTD_getParams(cLevel, pledgedSrcSize, dictSize);
|
||||||
params.fParams.checksumFlag = FUZ_rand(&lseed) & 1;
|
params.fParams.checksumFlag = FUZ_rand(&lseed) & 1;
|
||||||
params.fParams.noDictIDFlag = FUZ_rand(&lseed) & 1;
|
params.fParams.noDictIDFlag = FUZ_rand(&lseed) & 1;
|
||||||
{ size_t const initError = ZSTD_initCStream_advanced(zc, dict, dictSize, params, 0);
|
{ size_t const initError = ZSTD_initCStream_advanced(zc, dict, dictSize, params, pledgedSrcSize);
|
||||||
CHECK (ZSTD_isError(initError),"init error : %s", ZSTD_getErrorName(initError));
|
CHECK (ZSTD_isError(initError),"ZSTD_initCStream_advanced error : %s", ZSTD_getErrorName(initError));
|
||||||
} } }
|
} } }
|
||||||
|
|
||||||
/* multi-segments compression test */
|
/* multi-segments compression test */
|
||||||
XXH64_reset(&xxhState, 0);
|
XXH64_reset(&xxhState, 0);
|
||||||
nbChunks = (FUZ_rand(&lseed) & 127) + 2;
|
|
||||||
{ ZSTD_outBuffer outBuff = { cBuffer, cBufferSize, 0 } ;
|
{ ZSTD_outBuffer outBuff = { cBuffer, cBufferSize, 0 } ;
|
||||||
for (n=0, cSize=0, totalTestSize=0 ; (n<nbChunks) && (totalTestSize < maxTestSize) ; n++) {
|
U32 n;
|
||||||
|
for (n=0, cSize=0, totalTestSize=0 ; totalTestSize < maxTestSize ; n++) {
|
||||||
/* compress random chunk into random size dst buffer */
|
/* compress random chunk into random size dst buffer */
|
||||||
{ size_t const readChunkSize = FUZ_randomLength(&lseed, maxSampleLog);
|
{ size_t const randomSrcSize = FUZ_randomLength(&lseed, maxSampleLog);
|
||||||
size_t const srcStart = FUZ_rand(&lseed) % (srcBufferSize - readChunkSize);
|
size_t const srcSize = MIN (maxTestSize-totalTestSize, randomSrcSize);
|
||||||
|
size_t const srcStart = FUZ_rand(&lseed) % (srcBufferSize - srcSize);
|
||||||
size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
|
size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
|
||||||
size_t const dstBuffSize = MIN(cBufferSize - cSize, randomDstSize);
|
size_t const dstBuffSize = MIN(cBufferSize - cSize, randomDstSize);
|
||||||
ZSTD_inBuffer inBuff = { srcBuffer+srcStart, readChunkSize, 0 };
|
ZSTD_inBuffer inBuff = { srcBuffer+srcStart, srcSize, 0 };
|
||||||
outBuff.size = outBuff.pos + dstBuffSize;
|
outBuff.size = outBuff.pos + dstBuffSize;
|
||||||
|
|
||||||
{ size_t const compressionError = ZSTD_compressStream(zc, &outBuff, &inBuff);
|
{ size_t const compressionError = ZSTD_compressStream(zc, &outBuff, &inBuff);
|
||||||
@@ -441,7 +510,10 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* multi - fragments decompression test */
|
/* multi - fragments decompression test */
|
||||||
ZSTD_initDStream_usingDict(zd, dict, dictSize);
|
if (!dictSize /* don't reset if dictionary : could be different */ && (FUZ_rand(&lseed) & 1)) {
|
||||||
|
CHECK( ZSTD_isError(ZSTD_resetDStream(zd)), "ZSTD_resetDStream failed");
|
||||||
|
} else
|
||||||
|
ZSTD_initDStream_usingDict(zd, dict, dictSize);
|
||||||
{ size_t decompressionResult = 1;
|
{ size_t decompressionResult = 1;
|
||||||
ZSTD_inBuffer inBuff = { cBuffer, cSize, 0 };
|
ZSTD_inBuffer inBuff = { cBuffer, cSize, 0 };
|
||||||
ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 };
|
ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 };
|
||||||
@@ -475,7 +547,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
|
|||||||
} }
|
} }
|
||||||
|
|
||||||
/* try decompression on noisy data */
|
/* try decompression on noisy data */
|
||||||
ZSTD_initDStream(zd);
|
ZSTD_initDStream(zd_noise); /* note : no dictionary */
|
||||||
{ ZSTD_inBuffer inBuff = { cBuffer, cSize, 0 };
|
{ ZSTD_inBuffer inBuff = { cBuffer, cSize, 0 };
|
||||||
ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 };
|
ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 };
|
||||||
while (outBuff.pos < dstBufferSize) {
|
while (outBuff.pos < dstBufferSize) {
|
||||||
@@ -492,6 +564,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
|
|||||||
_cleanup:
|
_cleanup:
|
||||||
ZSTD_freeCStream(zc);
|
ZSTD_freeCStream(zc);
|
||||||
ZSTD_freeDStream(zd);
|
ZSTD_freeDStream(zd);
|
||||||
|
ZSTD_freeDStream(zd_noise);
|
||||||
free(cNoiseBuffer[0]);
|
free(cNoiseBuffer[0]);
|
||||||
free(cNoiseBuffer[1]);
|
free(cNoiseBuffer[1]);
|
||||||
free(cNoiseBuffer[2]);
|
free(cNoiseBuffer[2]);
|
||||||
@@ -571,7 +644,7 @@ int main(int argc, const char** argv)
|
|||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
argument++;
|
argument++;
|
||||||
nbTests=0; g_testTime=0;
|
nbTests=0; g_clockTime=0;
|
||||||
while ((*argument>='0') && (*argument<='9')) {
|
while ((*argument>='0') && (*argument<='9')) {
|
||||||
nbTests *= 10;
|
nbTests *= 10;
|
||||||
nbTests += *argument - '0';
|
nbTests += *argument - '0';
|
||||||
@@ -581,15 +654,15 @@ int main(int argc, const char** argv)
|
|||||||
|
|
||||||
case 'T':
|
case 'T':
|
||||||
argument++;
|
argument++;
|
||||||
nbTests=0; g_testTime=0;
|
nbTests=0; g_clockTime=0;
|
||||||
while ((*argument>='0') && (*argument<='9')) {
|
while ((*argument>='0') && (*argument<='9')) {
|
||||||
g_testTime *= 10;
|
g_clockTime *= 10;
|
||||||
g_testTime += *argument - '0';
|
g_clockTime += *argument - '0';
|
||||||
argument++;
|
argument++;
|
||||||
}
|
}
|
||||||
if (*argument=='m') g_testTime *=60, argument++;
|
if (*argument=='m') g_clockTime *=60, argument++;
|
||||||
if (*argument=='n') argument++;
|
if (*argument=='n') argument++;
|
||||||
g_testTime *= 1000;
|
g_clockTime *= CLOCKS_PER_SEC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
@@ -631,9 +704,14 @@ 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_STRING);
|
DISPLAY("Starting zstream 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 = FUZ_GetMilliStart() % 10000;
|
|
||||||
DISPLAY("Seed = %u\n", seed);
|
DISPLAY("Seed = %u\n", seed);
|
||||||
if (proba!=FUZ_COMPRESSIBILITY_DEFAULT) DISPLAY("Compressibility : %i%%\n", proba);
|
if (proba!=FUZ_COMPRESSIBILITY_DEFAULT) DISPLAY("Compressibility : %i%%\n", proba);
|
||||||
|
|
||||||
@@ -26,4 +26,4 @@ foo.gz
|
|||||||
# Misc files
|
# Misc files
|
||||||
*.bat
|
*.bat
|
||||||
*.zip
|
*.zip
|
||||||
examples/example2.c
|
*.txt
|
||||||
|
|||||||
+51
-28
@@ -1,54 +1,71 @@
|
|||||||
# Makefile for example of using zstd wrapper for zlib
|
# Makefile for example of using zstd wrapper for zlib
|
||||||
#
|
#
|
||||||
# make - compiles statically and dynamically linked examples/example.c
|
# make - compiles examples
|
||||||
# make test testdll - compiles and runs statically and dynamically linked examples/example.c
|
# make LOC=-DZWRAP_USE_ZSTD=1 - compiles examples with zstd compression turned on
|
||||||
# make LOC=-DZWRAP_USE_ZSTD=1 - compiles statically and dynamically linked examples/example.c with zstd compression turned on
|
# make test - runs examples
|
||||||
|
|
||||||
|
|
||||||
# Paths to static and dynamic zlib and zstd libraries
|
# Paths to static and dynamic zlib and zstd libraries
|
||||||
# Use "make ZLIBDIR=path/to/zlib" to select a path to library
|
# Use "make ZLIB_LIBRARY=path/to/zlib" to select a path to library
|
||||||
ifdef ZLIBDIR
|
ZLIB_LIBRARY ?= -lz
|
||||||
STATICLIB = $(ZLIBDIR)/libz.a ../lib/libzstd.a
|
|
||||||
IMPLIB = $(ZLIBDIR)/libz.dll.a ../lib/libzstd.a
|
|
||||||
else
|
|
||||||
STATICLIB = -static -lz ../lib/libzstd.a
|
|
||||||
IMPLIB = -lz ../lib/libzstd.a
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
ZSTDLIBDIR = ../lib
|
||||||
|
ZSTDLIBRARY = $(ZSTDLIBDIR)/libzstd.a
|
||||||
ZLIBWRAPPER_PATH = .
|
ZLIBWRAPPER_PATH = .
|
||||||
EXAMPLE_PATH = examples
|
EXAMPLE_PATH = examples
|
||||||
|
PROGRAMS_PATH = ../programs
|
||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
CFLAGS = $(LOC) -I../lib -I../lib/common -I$(ZLIBDIR) -I$(ZLIBWRAPPER_PATH) -O3 -std=gnu90
|
CFLAGS ?= -O3
|
||||||
|
CFLAGS += $(LOC) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) -std=gnu99
|
||||||
CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef
|
CFLAGS += -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: clean test testzstd
|
all: clean fitblk example zwrapbench
|
||||||
|
|
||||||
test: example
|
test: example fitblk example_zstd fitblk_zstd zwrapbench
|
||||||
./example
|
./example
|
||||||
|
|
||||||
testdll: example_d
|
|
||||||
./example_d
|
|
||||||
|
|
||||||
testzstd: example_zstd
|
|
||||||
./example_zstd
|
./example_zstd
|
||||||
|
./fitblk 10240 <../zstd_compression_format.md
|
||||||
|
./fitblk 40960 <../zstd_compression_format.md
|
||||||
|
./fitblk_zstd 10240 <../zstd_compression_format.md
|
||||||
|
./fitblk_zstd 40960 <../zstd_compression_format.md
|
||||||
|
./zwrapbench -qb3B1K ../zstd_compression_format.md
|
||||||
|
./zwrapbench -rqb1e5 ../lib ../programs ../tests
|
||||||
|
|
||||||
|
#valgrindTest: ZSTDLIBRARY = $(ZSTDLIBDIR)/libzstd.so
|
||||||
|
valgrindTest: VALGRIND = LD_LIBRARY_PATH=$(ZSTDLIBDIR) valgrind --track-origins=yes --leak-check=full --error-exitcode=1
|
||||||
|
valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench
|
||||||
|
@echo "\n ---- valgrind tests ----"
|
||||||
|
$(VALGRIND) ./example
|
||||||
|
$(VALGRIND) ./example_zstd
|
||||||
|
$(VALGRIND) ./fitblk 10240 <../zstd_compression_format.md
|
||||||
|
$(VALGRIND) ./fitblk 40960 <../zstd_compression_format.md
|
||||||
|
$(VALGRIND) ./fitblk_zstd 10240 <../zstd_compression_format.md
|
||||||
|
$(VALGRIND) ./fitblk_zstd 40960 <../zstd_compression_format.md
|
||||||
|
$(VALGRIND) ./zwrapbench -qb3B1K ../zstd_compression_format.md
|
||||||
|
$(VALGRIND) ./zwrapbench -rqb1e5 ../lib ../programs ../tests
|
||||||
|
|
||||||
.c.o:
|
.c.o:
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY)
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY)
|
||||||
|
|
||||||
example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o
|
example_zstd: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY)
|
||||||
$(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(STATICLIB)
|
$(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY)
|
||||||
|
|
||||||
example_d: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o
|
fitblk: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY)
|
||||||
$(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(IMPLIB)
|
$(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY)
|
||||||
|
|
||||||
example_zstd: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o
|
fitblk_zstd: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY)
|
||||||
$(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(STATICLIB)
|
$(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY)
|
||||||
|
|
||||||
$(EXAMPLE_PATH)/example.o: $(EXAMPLE_PATH)/example.c
|
zwrapbench: $(EXAMPLE_PATH)/zwrapbench.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(PROGRAMS_PATH)/datagen.o $(ZSTDLIBRARY)
|
||||||
$(CC) $(CFLAGS) -I. -c -o $@ $(EXAMPLE_PATH)/example.c
|
$(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/zwrapbench.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(PROGRAMS_PATH)/datagen.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY)
|
||||||
|
|
||||||
|
$(EXAMPLE_PATH)/zwrapbench.o: $(EXAMPLE_PATH)/zwrapbench.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
|
||||||
@@ -56,6 +73,12 @@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $
|
|||||||
$(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.h
|
$(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.h
|
||||||
$(CC) $(CFLAGS) -DZWRAP_USE_ZSTD=1 -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c
|
$(CC) $(CFLAGS) -DZWRAP_USE_ZSTD=1 -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c
|
||||||
|
|
||||||
|
$(ZSTDLIBDIR)/libzstd.a:
|
||||||
|
$(MAKE) -C $(ZSTDLIBDIR) all
|
||||||
|
|
||||||
|
$(ZSTDLIBDIR)/libzstd.so:
|
||||||
|
$(MAKE) -C $(ZSTDLIBDIR) all
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_d example_zstd
|
-$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_zstd fitblk fitblk_zstd zwrapbench
|
||||||
@echo Cleaning completed
|
@echo Cleaning completed
|
||||||
|
|||||||
+65
-11
@@ -1,4 +1,4 @@
|
|||||||
zstd wrapper for zlib
|
Zstandard wrapper for zlib
|
||||||
================================
|
================================
|
||||||
|
|
||||||
The main objective of creating a zstd wrapper for [zlib](http://zlib.net/) is to allow a quick and smooth transition to zstd for projects already using zlib.
|
The main objective of creating a zstd wrapper for [zlib](http://zlib.net/) is to allow a quick and smooth transition to zstd for projects already using zlib.
|
||||||
@@ -23,10 +23,10 @@ Let's assume that your project that uses zlib is compiled with:
|
|||||||
|
|
||||||
To compile the zstd wrapper with your project you have to do the following:
|
To compile the zstd wrapper with your project you have to do the following:
|
||||||
- change all references with ```#include "zlib.h"``` to ```#include "zstd_zlibwrapper.h"```
|
- change all references with ```#include "zlib.h"``` to ```#include "zstd_zlibwrapper.h"```
|
||||||
- compile your project with zlib_wrapper.c and a static or dynamic zstd library
|
- compile your project with `zstd_zlibwrapper.c` and a static or dynamic zstd library
|
||||||
|
|
||||||
The linking should be changed to:
|
The linking should be changed to:
|
||||||
```gcc project.o zlib_wrapper.o -lz -lzstd```
|
```gcc project.o zstd_zlibwrapper.o -lz -lzstd```
|
||||||
|
|
||||||
|
|
||||||
#### Enabling zstd compression within your project
|
#### Enabling zstd compression within your project
|
||||||
@@ -34,8 +34,10 @@ The linking should be changed to:
|
|||||||
After embedding the zstd wrapper within your project the zstd library is turned off by default.
|
After embedding the zstd wrapper within your project the zstd library is turned off by default.
|
||||||
Your project should work as before with zlib. There are two options to enable zstd compression:
|
Your project should work as before with zlib. There are two options to enable zstd compression:
|
||||||
- compilation with ```-DZWRAP_USE_ZSTD=1``` (or using ```#define ZWRAP_USE_ZSTD 1``` before ```#include "zstd_zlibwrapper.h"```)
|
- compilation with ```-DZWRAP_USE_ZSTD=1``` (or using ```#define ZWRAP_USE_ZSTD 1``` before ```#include "zstd_zlibwrapper.h"```)
|
||||||
- using the ```void useZSTD(int turn_on)``` function (declared in ```#include "zstd_zlibwrapper.h"```)
|
- using the ```void ZWRAP_useZSTDcompression(int turn_on)``` function (declared in ```#include "zstd_zlibwrapper.h"```)
|
||||||
There is no switch for zstd decompression because zlib and zstd streams are automatically detected and decompressed using a proper library.
|
|
||||||
|
During decompression zlib and zstd streams are automatically detected and decompressed using a proper library.
|
||||||
|
This behavior can be changed using `ZWRAP_setDecompressionType(ZWRAP_FORCE_ZLIB)` what will make zlib decompression slightly faster.
|
||||||
|
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
@@ -52,7 +54,7 @@ after inflateSync(): hello, hello!
|
|||||||
inflate with dictionary: hello, hello!
|
inflate with dictionary: hello, hello!
|
||||||
```
|
```
|
||||||
Then we have changed ```#include "zlib.h"``` to ```#include "zstd_zlibwrapper.h"```, compiled the [example.c](examples/example.c) file
|
Then we have changed ```#include "zlib.h"``` to ```#include "zstd_zlibwrapper.h"```, compiled the [example.c](examples/example.c) file
|
||||||
with ```-DZWRAP_USE_ZSTD=1``` and linked with additional ```zlib_wrapper.o -lzstd```.
|
with ```-DZWRAP_USE_ZSTD=1``` and linked with additional ```zstd_zlibwrapper.o -lzstd```.
|
||||||
We were forced to turn off the following functions: ```test_gzio```, ```test_flush```, ```test_sync``` which use currently unsupported features.
|
We were forced to turn off the following functions: ```test_gzio```, ```test_flush```, ```test_sync``` which use currently unsupported features.
|
||||||
After running it shows the following results:
|
After running it shows the following results:
|
||||||
```
|
```
|
||||||
@@ -65,18 +67,72 @@ inflate with dictionary: hello, hello!
|
|||||||
The script used for compilation can be found at [zlibWrapper/Makefile](Makefile).
|
The script used for compilation can be found at [zlibWrapper/Makefile](Makefile).
|
||||||
|
|
||||||
|
|
||||||
|
#### The measurement of performace of Zstandard wrapper for zlib
|
||||||
|
|
||||||
|
The zstd distribution contains a tool called `zwrapbench` which can measure speed and ratio of zlib, zstd, and the wrapper.
|
||||||
|
The benchmark is conducted using given filenames or synthetic data if filenames are not provided.
|
||||||
|
The files are read into memory and joined together.
|
||||||
|
It makes benchmark more precise as it eliminates I/O overhead.
|
||||||
|
Many filenames can be supplied as multiple parameters, parameters with wildcards or names of directories can be used as parameters with the -r option.
|
||||||
|
One can select compression levels starting from `-b` and ending with `-e`. The `-i` parameter selects minimal time used for each of tested levels.
|
||||||
|
With `-B` option bigger files can be divided into smaller, independently compressed blocks.
|
||||||
|
The benchmark tool can be compiled with `make zwrapbench` using [zlibWrapper/Makefile](Makefile).
|
||||||
|
|
||||||
|
|
||||||
|
#### Improving speed of streaming compression
|
||||||
|
|
||||||
|
During streaming compression the compressor never knows how big is data to compress.
|
||||||
|
Zstandard compression can be improved by providing size of source data to the compressor. By default streaming compressor assumes that data is bigger than 256 KB but it can hurt compression speed on smaller data.
|
||||||
|
The zstd wrapper provides the `ZWRAP_setPledgedSrcSize()` function that allows to change a pledged source size for a given compression stream.
|
||||||
|
The function will change zstd compression parameters what may improve compression speed and/or ratio.
|
||||||
|
It should be called just after `deflateInit()`or `deflateReset()` and before `deflate()` or `deflateSetDictionary()`. The function is only helpful when data is compressed in blocks. There will be no change in case of `deflateInit()` or `deflateReset()` immediately followed by `deflate(strm, Z_FINISH)`
|
||||||
|
as this case is automatically detected.
|
||||||
|
|
||||||
|
|
||||||
|
#### Reusing contexts
|
||||||
|
|
||||||
|
The ordinary zlib compression of two files/streams allocates two contexts:
|
||||||
|
- for the 1st file calls `deflateInit`, `deflate`, `...`, `deflate`, `defalateEnd`
|
||||||
|
- for the 2nd file calls `deflateInit`, `deflate`, `...`, `deflate`, `defalateEnd`
|
||||||
|
|
||||||
|
The speed of compression can be improved with reusing a single context with following steps:
|
||||||
|
- initialize the context with `deflateInit`
|
||||||
|
- for the 1st file call `deflate`, `...`, `deflate`
|
||||||
|
- for the 2nd file call `deflateReset`, `deflate`, `...`, `deflate`
|
||||||
|
- free the context with `deflateEnd`
|
||||||
|
|
||||||
|
To check the difference we made experiments using `zwrapbench -ri6b6` with zstd and zlib compression (both at level 6).
|
||||||
|
The input data was decompressed git repository downloaded from https://github.com/git/git/archive/master.zip which contains 2979 files.
|
||||||
|
The table below shows that reusing contexts has a minor influence on zlib but it gives improvement for zstd.
|
||||||
|
In our example (the last 2 lines) it gives 4% better compression speed and 5% better decompression speed.
|
||||||
|
|
||||||
|
| Compression type | Compression | Decompress.| Compr. size | Ratio |
|
||||||
|
| ------------------------------------------------- | ------------| -----------| ----------- | ----- |
|
||||||
|
| zlib 1.2.8 | 30.51 MB/s | 219.3 MB/s | 6819783 | 3.459 |
|
||||||
|
| zlib 1.2.8 not reusing a context | 30.22 MB/s | 218.1 MB/s | 6819783 | 3.459 |
|
||||||
|
| zlib 1.2.8 with zlibWrapper and reusing a context | 30.40 MB/s | 218.9 MB/s | 6819783 | 3.459 |
|
||||||
|
| zlib 1.2.8 with zlibWrapper not reusing a context | 30.28 MB/s | 218.1 MB/s | 6819783 | 3.459 |
|
||||||
|
| zstd 1.1.0 using ZSTD_CCtx | 68.35 MB/s | 430.9 MB/s | 6868521 | 3.435 |
|
||||||
|
| zstd 1.1.0 using ZSTD_CStream | 66.63 MB/s | 422.3 MB/s | 6868521 | 3.435 |
|
||||||
|
| zstd 1.1.0 with zlibWrapper and reusing a context | 54.01 MB/s | 403.2 MB/s | 6763482 | 3.488 |
|
||||||
|
| zstd 1.1.0 with zlibWrapper not reusing a context | 51.59 MB/s | 383.7 MB/s | 6763482 | 3.488 |
|
||||||
|
|
||||||
|
|
||||||
#### Compatibility issues
|
#### Compatibility issues
|
||||||
After enabling zstd compression not all native zlib functions are supported. When calling unsupported methods they print error message and return an error value.
|
After enabling zstd compression not all native zlib functions are supported. When calling unsupported methods they put error message into strm->msg and return Z_STREAM_ERROR.
|
||||||
|
|
||||||
Supported methods:
|
Supported methods:
|
||||||
- deflateInit
|
- deflateInit
|
||||||
- deflate (with exception of Z_FULL_FLUSH)
|
- deflate (with exception of Z_FULL_FLUSH, Z_BLOCK, and Z_TREES)
|
||||||
- deflateSetDictionary
|
- deflateSetDictionary
|
||||||
- deflateEnd
|
- deflateEnd
|
||||||
|
- deflateReset
|
||||||
- deflateBound
|
- deflateBound
|
||||||
- inflateInit
|
- inflateInit
|
||||||
- inflate
|
- inflate
|
||||||
- inflateSetDictionary
|
- inflateSetDictionary
|
||||||
|
- inflateReset
|
||||||
|
- inflateReset2
|
||||||
- compress
|
- compress
|
||||||
- compress2
|
- compress2
|
||||||
- compressBound
|
- compressBound
|
||||||
@@ -88,15 +144,13 @@ Ignored methods (they do nothing):
|
|||||||
Unsupported methods:
|
Unsupported methods:
|
||||||
- gzip file access functions
|
- gzip file access functions
|
||||||
- deflateCopy
|
- deflateCopy
|
||||||
- deflateReset
|
|
||||||
- deflateTune
|
- deflateTune
|
||||||
- deflatePending
|
- deflatePending
|
||||||
- deflatePrime
|
- deflatePrime
|
||||||
- deflateSetHeader
|
- deflateSetHeader
|
||||||
- inflateGetDictionary
|
- inflateGetDictionary
|
||||||
- inflateCopy
|
- inflateCopy
|
||||||
- inflateReset
|
- inflateSync
|
||||||
- inflateReset2
|
|
||||||
- inflatePrime
|
- inflatePrime
|
||||||
- inflateMark
|
- inflateMark
|
||||||
- inflateGetHeader
|
- inflateGetHeader
|
||||||
|
|||||||
@@ -1,8 +1,25 @@
|
|||||||
/* the file contains minimal changes required to be compiled with zstd wrapper for zlib */
|
|
||||||
|
|
||||||
/* example.c -- usage example of the zlib compression library
|
/* example.c -- usage example of the zlib compression library
|
||||||
* Copyright (C) 1995-2006, 2011 Jean-loup Gailly.
|
* the file contains minimal changes required to be compiled with zstd wrapper for zlib
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) 1995-2006, 2011 Jean-loup Gailly
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgement in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* @(#) $Id$ */
|
/* @(#) $Id$ */
|
||||||
@@ -28,12 +45,12 @@
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
z_const char hello[] = "hello, hello!";
|
z_const char hello[] = "hello, hello! I said hello, hello!";
|
||||||
/* "hello world" would be more standard, but the repeated "hello"
|
/* "hello world" would be more standard, but the repeated "hello"
|
||||||
* stresses the compression code better, sorry...
|
* stresses the compression code better, sorry...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const char dictionary[] = "hello";
|
const char dictionary[] = "hello, hello!";
|
||||||
uLong dictId; /* Adler32 value of the dictionary */
|
uLong dictId; /* Adler32 value of the dictionary */
|
||||||
|
|
||||||
void test_deflate OF((Byte *compr, uLong comprLen));
|
void test_deflate OF((Byte *compr, uLong comprLen));
|
||||||
@@ -139,7 +156,7 @@ void test_gzio(fname, uncompr, uncomprLen)
|
|||||||
fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
|
fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (gzprintf(file, ", %s!", "hello") != 8) {
|
if (gzprintf(file, ", %s! I said hello, hello!", "hello") != 8+21) {
|
||||||
fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
|
fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -165,7 +182,7 @@ void test_gzio(fname, uncompr, uncomprLen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pos = gzseek(file, -8L, SEEK_CUR);
|
pos = gzseek(file, -8L, SEEK_CUR);
|
||||||
if (pos != 6 || gztell(file) != pos) {
|
if (pos != 6+21 || gztell(file) != pos) {
|
||||||
fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
|
fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
|
||||||
(long)pos, (long)gztell(file));
|
(long)pos, (long)gztell(file));
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -186,7 +203,7 @@ void test_gzio(fname, uncompr, uncomprLen)
|
|||||||
fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
|
fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (strcmp((char*)uncompr, hello + 6)) {
|
if (strcmp((char*)uncompr, hello + 6+21)) {
|
||||||
fprintf(stderr, "bad gzgets after gzseek\n");
|
fprintf(stderr, "bad gzgets after gzseek\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
@@ -566,7 +583,7 @@ int main(argc, argv)
|
|||||||
|
|
||||||
printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
|
printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
|
||||||
ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
|
ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
|
||||||
if (isUsingZSTD()) printf("zstd version %s\n", zstdVersion());
|
if (ZWRAP_isUsingZSTDcompression()) printf("zstd version %s\n", zstdVersion());
|
||||||
|
|
||||||
compr = (Byte*)calloc((uInt)comprLen, 1);
|
compr = (Byte*)calloc((uInt)comprLen, 1);
|
||||||
uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
|
uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
|
||||||
@@ -583,7 +600,7 @@ int main(argc, argv)
|
|||||||
#else
|
#else
|
||||||
test_compress(compr, comprLen, uncompr, uncomprLen);
|
test_compress(compr, comprLen, uncompr, uncomprLen);
|
||||||
|
|
||||||
if (!isUsingZSTD())
|
if (!ZWRAP_isUsingZSTDcompression())
|
||||||
test_gzio((argc > 1 ? argv[1] : TESTFILE),
|
test_gzio((argc > 1 ? argv[1] : TESTFILE),
|
||||||
uncompr, uncomprLen);
|
uncompr, uncomprLen);
|
||||||
#endif
|
#endif
|
||||||
@@ -594,7 +611,7 @@ int main(argc, argv)
|
|||||||
test_large_deflate(compr, comprLen, uncompr, uncomprLen);
|
test_large_deflate(compr, comprLen, uncompr, uncomprLen);
|
||||||
test_large_inflate(compr, comprLen, uncompr, uncomprLen);
|
test_large_inflate(compr, comprLen, uncompr, uncomprLen);
|
||||||
|
|
||||||
if (!isUsingZSTD()) {
|
if (!ZWRAP_isUsingZSTDcompression()) {
|
||||||
test_flush(compr, &comprLen);
|
test_flush(compr, &comprLen);
|
||||||
test_sync(compr, comprLen, uncompr, uncomprLen);
|
test_sync(compr, comprLen, uncompr, uncomprLen);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,24 @@
|
|||||||
/* example.c -- usage example of the zlib compression library
|
/* example.c -- usage example of the zlib compression library
|
||||||
* Copyright (C) 1995-2006, 2011 Jean-loup Gailly.
|
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
Copyright (c) 1995-2006, 2011 Jean-loup Gailly
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgement in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
/* @(#) $Id$ */
|
/* @(#) $Id$ */
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,253 @@
|
|||||||
|
/* fitblk.c: example of fitting compressed output to a specified size
|
||||||
|
Not copyrighted -- provided to the public domain
|
||||||
|
Version 1.1 25 November 2004 Mark Adler */
|
||||||
|
|
||||||
|
/* Version history:
|
||||||
|
1.0 24 Nov 2004 First version
|
||||||
|
1.1 25 Nov 2004 Change deflateInit2() to deflateInit()
|
||||||
|
Use fixed-size, stack-allocated raw buffers
|
||||||
|
Simplify code moving compression to subroutines
|
||||||
|
Use assert() for internal errors
|
||||||
|
Add detailed description of approach
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Approach to just fitting a requested compressed size:
|
||||||
|
|
||||||
|
fitblk performs three compression passes on a portion of the input
|
||||||
|
data in order to determine how much of that input will compress to
|
||||||
|
nearly the requested output block size. The first pass generates
|
||||||
|
enough deflate blocks to produce output to fill the requested
|
||||||
|
output size plus a specfied excess amount (see the EXCESS define
|
||||||
|
below). The last deflate block may go quite a bit past that, but
|
||||||
|
is discarded. The second pass decompresses and recompresses just
|
||||||
|
the compressed data that fit in the requested plus excess sized
|
||||||
|
buffer. The deflate process is terminated after that amount of
|
||||||
|
input, which is less than the amount consumed on the first pass.
|
||||||
|
The last deflate block of the result will be of a comparable size
|
||||||
|
to the final product, so that the header for that deflate block and
|
||||||
|
the compression ratio for that block will be about the same as in
|
||||||
|
the final product. The third compression pass decompresses the
|
||||||
|
result of the second step, but only the compressed data up to the
|
||||||
|
requested size minus an amount to allow the compressed stream to
|
||||||
|
complete (see the MARGIN define below). That will result in a
|
||||||
|
final compressed stream whose length is less than or equal to the
|
||||||
|
requested size. Assuming sufficient input and a requested size
|
||||||
|
greater than a few hundred bytes, the shortfall will typically be
|
||||||
|
less than ten bytes.
|
||||||
|
|
||||||
|
If the input is short enough that the first compression completes
|
||||||
|
before filling the requested output size, then that compressed
|
||||||
|
stream is return with no recompression.
|
||||||
|
|
||||||
|
EXCESS is chosen to be just greater than the shortfall seen in a
|
||||||
|
two pass approach similar to the above. That shortfall is due to
|
||||||
|
the last deflate block compressing more efficiently with a smaller
|
||||||
|
header on the second pass. EXCESS is set to be large enough so
|
||||||
|
that there is enough uncompressed data for the second pass to fill
|
||||||
|
out the requested size, and small enough so that the final deflate
|
||||||
|
block of the second pass will be close in size to the final deflate
|
||||||
|
block of the third and final pass. MARGIN is chosen to be just
|
||||||
|
large enough to assure that the final compression has enough room
|
||||||
|
to complete in all cases.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
//#include "zlib.h"
|
||||||
|
#include "zstd_zlibwrapper.h"
|
||||||
|
|
||||||
|
#define LOG_FITBLK(...) /*printf(__VA_ARGS__)*/
|
||||||
|
#define local static
|
||||||
|
|
||||||
|
/* print nastygram and leave */
|
||||||
|
local void quit(char *why)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "fitblk abort: %s\n", why);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RAWLEN 4096 /* intermediate uncompressed buffer size */
|
||||||
|
|
||||||
|
/* compress from file to def until provided buffer is full or end of
|
||||||
|
input reached; return last deflate() return value, or Z_ERRNO if
|
||||||
|
there was read error on the file */
|
||||||
|
local int partcompress(FILE *in, z_streamp def)
|
||||||
|
{
|
||||||
|
int ret, flush;
|
||||||
|
unsigned char raw[RAWLEN];
|
||||||
|
|
||||||
|
flush = Z_SYNC_FLUSH;
|
||||||
|
do {
|
||||||
|
def->avail_in = fread(raw, 1, RAWLEN, in);
|
||||||
|
if (ferror(in))
|
||||||
|
return Z_ERRNO;
|
||||||
|
def->next_in = raw;
|
||||||
|
if (feof(in))
|
||||||
|
flush = Z_FINISH;
|
||||||
|
LOG_FITBLK("partcompress1 avail_in=%d total_in=%d avail_out=%d total_out=%d\n", (int)def->avail_in, (int)def->total_in, (int)def->avail_out, (int)def->total_out);
|
||||||
|
ret = deflate(def, flush);
|
||||||
|
LOG_FITBLK("partcompress2 avail_in=%d total_in=%d avail_out=%d total_out=%d\n", (int)def->avail_in, (int)def->total_in, (int)def->avail_out, (int)def->total_out);
|
||||||
|
assert(ret != Z_STREAM_ERROR);
|
||||||
|
} while (def->avail_out != 0 && flush == Z_SYNC_FLUSH);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* recompress from inf's input to def's output; the input for inf and
|
||||||
|
the output for def are set in those structures before calling;
|
||||||
|
return last deflate() return value, or Z_MEM_ERROR if inflate()
|
||||||
|
was not able to allocate enough memory when it needed to */
|
||||||
|
local int recompress(z_streamp inf, z_streamp def)
|
||||||
|
{
|
||||||
|
int ret, flush;
|
||||||
|
unsigned char raw[RAWLEN];
|
||||||
|
|
||||||
|
flush = Z_NO_FLUSH;
|
||||||
|
do {
|
||||||
|
/* decompress */
|
||||||
|
inf->avail_out = RAWLEN;
|
||||||
|
inf->next_out = raw;
|
||||||
|
LOG_FITBLK("recompress1inflate avail_in=%d total_in=%d avail_out=%d total_out=%d\n", (int)inf->avail_in, (int)inf->total_in, (int)inf->avail_out, (int)inf->total_out);
|
||||||
|
ret = inflate(inf, Z_NO_FLUSH);
|
||||||
|
LOG_FITBLK("recompress2inflate avail_in=%d total_in=%d avail_out=%d total_out=%d\n", (int)inf->avail_in, (int)inf->total_in, (int)inf->avail_out, (int)inf->total_out);
|
||||||
|
assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR &&
|
||||||
|
ret != Z_NEED_DICT);
|
||||||
|
if (ret == Z_MEM_ERROR)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* compress what was decompresed until done or no room */
|
||||||
|
def->avail_in = RAWLEN - inf->avail_out;
|
||||||
|
def->next_in = raw;
|
||||||
|
if (inf->avail_out != 0)
|
||||||
|
flush = Z_FINISH;
|
||||||
|
LOG_FITBLK("recompress1deflate avail_in=%d total_in=%d avail_out=%d total_out=%d\n", (int)def->avail_in, (int)def->total_in, (int)def->avail_out, (int)def->total_out);
|
||||||
|
ret = deflate(def, flush);
|
||||||
|
LOG_FITBLK("recompress2deflate avail_in=%d total_in=%d avail_out=%d total_out=%d\n", (int)def->avail_in, (int)def->total_in, (int)def->avail_out, (int)def->total_out);
|
||||||
|
assert(ret != Z_STREAM_ERROR);
|
||||||
|
} while (ret != Z_STREAM_END && def->avail_out != 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXCESS 256 /* empirically determined stream overage */
|
||||||
|
#define MARGIN 8 /* amount to back off for completion */
|
||||||
|
|
||||||
|
/* compress from stdin to fixed-size block on stdout */
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret; /* return code */
|
||||||
|
unsigned size; /* requested fixed output block size */
|
||||||
|
unsigned have; /* bytes written by deflate() call */
|
||||||
|
unsigned char *blk; /* intermediate and final stream */
|
||||||
|
unsigned char *tmp; /* close to desired size stream */
|
||||||
|
z_stream def, inf; /* zlib deflate and inflate states */
|
||||||
|
|
||||||
|
/* get requested output size */
|
||||||
|
if (argc != 2)
|
||||||
|
quit("need one argument: size of output block");
|
||||||
|
ret = strtol(argv[1], argv + 1, 10);
|
||||||
|
if (argv[1][0] != 0)
|
||||||
|
quit("argument must be a number");
|
||||||
|
if (ret < 8) /* 8 is minimum zlib stream size */
|
||||||
|
quit("need positive size of 8 or greater");
|
||||||
|
size = (unsigned)ret;
|
||||||
|
|
||||||
|
printf("zlib version %s\n", ZLIB_VERSION);
|
||||||
|
if (ZWRAP_isUsingZSTDcompression()) printf("zstd version %s\n", zstdVersion());
|
||||||
|
|
||||||
|
/* allocate memory for buffers and compression engine */
|
||||||
|
blk = malloc(size + EXCESS);
|
||||||
|
def.zalloc = Z_NULL;
|
||||||
|
def.zfree = Z_NULL;
|
||||||
|
def.opaque = Z_NULL;
|
||||||
|
ret = deflateInit(&def, Z_DEFAULT_COMPRESSION);
|
||||||
|
if (ret != Z_OK || blk == NULL)
|
||||||
|
quit("out of memory");
|
||||||
|
ret = ZWRAP_setPledgedSrcSize(&def, 1<<16);
|
||||||
|
if (ret != Z_OK)
|
||||||
|
quit("ZWRAP_setPledgedSrcSize");
|
||||||
|
|
||||||
|
/* compress from stdin until output full, or no more input */
|
||||||
|
def.avail_out = size + EXCESS;
|
||||||
|
def.next_out = blk;
|
||||||
|
LOG_FITBLK("partcompress1 total_in=%d total_out=%d\n", (int)def.total_in, (int)def.total_out);
|
||||||
|
ret = partcompress(stdin, &def);
|
||||||
|
printf("partcompress total_in=%d total_out=%d\n", (int)def.total_in, (int)def.total_out);
|
||||||
|
if (ret == Z_ERRNO)
|
||||||
|
quit("error reading input");
|
||||||
|
|
||||||
|
/* if it all fit, then size was undersubscribed -- done! */
|
||||||
|
if (ret == Z_STREAM_END && def.avail_out >= EXCESS) {
|
||||||
|
/* write block to stdout */
|
||||||
|
have = size + EXCESS - def.avail_out;
|
||||||
|
// if (fwrite(blk, 1, have, stdout) != have || ferror(stdout))
|
||||||
|
// quit("error writing output");
|
||||||
|
|
||||||
|
/* clean up and print results to stderr */
|
||||||
|
ret = deflateEnd(&def);
|
||||||
|
assert(ret != Z_STREAM_ERROR);
|
||||||
|
free(blk);
|
||||||
|
fprintf(stderr,
|
||||||
|
"%u bytes unused out of %u requested (all input)\n",
|
||||||
|
size - have, size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* it didn't all fit -- set up for recompression */
|
||||||
|
inf.zalloc = Z_NULL;
|
||||||
|
inf.zfree = Z_NULL;
|
||||||
|
inf.opaque = Z_NULL;
|
||||||
|
inf.avail_in = 0;
|
||||||
|
inf.next_in = Z_NULL;
|
||||||
|
ret = inflateInit(&inf);
|
||||||
|
tmp = malloc(size + EXCESS);
|
||||||
|
if (ret != Z_OK || tmp == NULL)
|
||||||
|
quit("out of memory");
|
||||||
|
ret = deflateReset(&def);
|
||||||
|
assert(ret != Z_STREAM_ERROR);
|
||||||
|
|
||||||
|
/* do first recompression close to the right amount */
|
||||||
|
inf.avail_in = size + EXCESS;
|
||||||
|
inf.next_in = blk;
|
||||||
|
def.avail_out = size + EXCESS;
|
||||||
|
def.next_out = tmp;
|
||||||
|
LOG_FITBLK("recompress1 inf.total_in=%d def.total_out=%d\n", (int)inf.total_in, (int)def.total_out);
|
||||||
|
ret = recompress(&inf, &def);
|
||||||
|
LOG_FITBLK("recompress1 inf.total_in=%d def.total_out=%d\n", (int)inf.total_in, (int)def.total_out);
|
||||||
|
if (ret == Z_MEM_ERROR)
|
||||||
|
quit("out of memory");
|
||||||
|
|
||||||
|
/* set up for next reocmpression */
|
||||||
|
ret = inflateReset(&inf);
|
||||||
|
assert(ret != Z_STREAM_ERROR);
|
||||||
|
ret = deflateReset(&def);
|
||||||
|
assert(ret != Z_STREAM_ERROR);
|
||||||
|
|
||||||
|
/* do second and final recompression (third compression) */
|
||||||
|
inf.avail_in = size - MARGIN; /* assure stream will complete */
|
||||||
|
inf.next_in = tmp;
|
||||||
|
def.avail_out = size;
|
||||||
|
def.next_out = blk;
|
||||||
|
LOG_FITBLK("recompress2 inf.total_in=%d def.total_out=%d\n", (int)inf.total_in, (int)def.total_out);
|
||||||
|
ret = recompress(&inf, &def);
|
||||||
|
LOG_FITBLK("recompress2 inf.total_in=%d def.total_out=%d\n", (int)inf.total_in, (int)def.total_out);
|
||||||
|
if (ret == Z_MEM_ERROR)
|
||||||
|
quit("out of memory");
|
||||||
|
assert(ret == Z_STREAM_END); /* otherwise MARGIN too small */
|
||||||
|
|
||||||
|
/* done -- write block to stdout */
|
||||||
|
have = size - def.avail_out;
|
||||||
|
// if (fwrite(blk, 1, have, stdout) != have || ferror(stdout))
|
||||||
|
// quit("error writing output");
|
||||||
|
|
||||||
|
/* clean up and print results to stderr */
|
||||||
|
free(tmp);
|
||||||
|
ret = inflateEnd(&inf);
|
||||||
|
assert(ret != Z_STREAM_ERROR);
|
||||||
|
ret = deflateEnd(&def);
|
||||||
|
assert(ret != Z_STREAM_ERROR);
|
||||||
|
free(blk);
|
||||||
|
fprintf(stderr,
|
||||||
|
"%u bytes unused out of %u requested (%lu input)\n",
|
||||||
|
size - have, size, def.total_in);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,233 @@
|
|||||||
|
/* fitblk.c: example of fitting compressed output to a specified size
|
||||||
|
Not copyrighted -- provided to the public domain
|
||||||
|
Version 1.1 25 November 2004 Mark Adler */
|
||||||
|
|
||||||
|
/* Version history:
|
||||||
|
1.0 24 Nov 2004 First version
|
||||||
|
1.1 25 Nov 2004 Change deflateInit2() to deflateInit()
|
||||||
|
Use fixed-size, stack-allocated raw buffers
|
||||||
|
Simplify code moving compression to subroutines
|
||||||
|
Use assert() for internal errors
|
||||||
|
Add detailed description of approach
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Approach to just fitting a requested compressed size:
|
||||||
|
|
||||||
|
fitblk performs three compression passes on a portion of the input
|
||||||
|
data in order to determine how much of that input will compress to
|
||||||
|
nearly the requested output block size. The first pass generates
|
||||||
|
enough deflate blocks to produce output to fill the requested
|
||||||
|
output size plus a specfied excess amount (see the EXCESS define
|
||||||
|
below). The last deflate block may go quite a bit past that, but
|
||||||
|
is discarded. The second pass decompresses and recompresses just
|
||||||
|
the compressed data that fit in the requested plus excess sized
|
||||||
|
buffer. The deflate process is terminated after that amount of
|
||||||
|
input, which is less than the amount consumed on the first pass.
|
||||||
|
The last deflate block of the result will be of a comparable size
|
||||||
|
to the final product, so that the header for that deflate block and
|
||||||
|
the compression ratio for that block will be about the same as in
|
||||||
|
the final product. The third compression pass decompresses the
|
||||||
|
result of the second step, but only the compressed data up to the
|
||||||
|
requested size minus an amount to allow the compressed stream to
|
||||||
|
complete (see the MARGIN define below). That will result in a
|
||||||
|
final compressed stream whose length is less than or equal to the
|
||||||
|
requested size. Assuming sufficient input and a requested size
|
||||||
|
greater than a few hundred bytes, the shortfall will typically be
|
||||||
|
less than ten bytes.
|
||||||
|
|
||||||
|
If the input is short enough that the first compression completes
|
||||||
|
before filling the requested output size, then that compressed
|
||||||
|
stream is return with no recompression.
|
||||||
|
|
||||||
|
EXCESS is chosen to be just greater than the shortfall seen in a
|
||||||
|
two pass approach similar to the above. That shortfall is due to
|
||||||
|
the last deflate block compressing more efficiently with a smaller
|
||||||
|
header on the second pass. EXCESS is set to be large enough so
|
||||||
|
that there is enough uncompressed data for the second pass to fill
|
||||||
|
out the requested size, and small enough so that the final deflate
|
||||||
|
block of the second pass will be close in size to the final deflate
|
||||||
|
block of the third and final pass. MARGIN is chosen to be just
|
||||||
|
large enough to assure that the final compression has enough room
|
||||||
|
to complete in all cases.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "zlib.h"
|
||||||
|
|
||||||
|
#define local static
|
||||||
|
|
||||||
|
/* print nastygram and leave */
|
||||||
|
local void quit(char *why)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "fitblk abort: %s\n", why);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RAWLEN 4096 /* intermediate uncompressed buffer size */
|
||||||
|
|
||||||
|
/* compress from file to def until provided buffer is full or end of
|
||||||
|
input reached; return last deflate() return value, or Z_ERRNO if
|
||||||
|
there was read error on the file */
|
||||||
|
local int partcompress(FILE *in, z_streamp def)
|
||||||
|
{
|
||||||
|
int ret, flush;
|
||||||
|
unsigned char raw[RAWLEN];
|
||||||
|
|
||||||
|
flush = Z_NO_FLUSH;
|
||||||
|
do {
|
||||||
|
def->avail_in = fread(raw, 1, RAWLEN, in);
|
||||||
|
if (ferror(in))
|
||||||
|
return Z_ERRNO;
|
||||||
|
def->next_in = raw;
|
||||||
|
if (feof(in))
|
||||||
|
flush = Z_FINISH;
|
||||||
|
ret = deflate(def, flush);
|
||||||
|
assert(ret != Z_STREAM_ERROR);
|
||||||
|
} while (def->avail_out != 0 && flush == Z_NO_FLUSH);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* recompress from inf's input to def's output; the input for inf and
|
||||||
|
the output for def are set in those structures before calling;
|
||||||
|
return last deflate() return value, or Z_MEM_ERROR if inflate()
|
||||||
|
was not able to allocate enough memory when it needed to */
|
||||||
|
local int recompress(z_streamp inf, z_streamp def)
|
||||||
|
{
|
||||||
|
int ret, flush;
|
||||||
|
unsigned char raw[RAWLEN];
|
||||||
|
|
||||||
|
flush = Z_NO_FLUSH;
|
||||||
|
do {
|
||||||
|
/* decompress */
|
||||||
|
inf->avail_out = RAWLEN;
|
||||||
|
inf->next_out = raw;
|
||||||
|
ret = inflate(inf, Z_NO_FLUSH);
|
||||||
|
assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR &&
|
||||||
|
ret != Z_NEED_DICT);
|
||||||
|
if (ret == Z_MEM_ERROR)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* compress what was decompresed until done or no room */
|
||||||
|
def->avail_in = RAWLEN - inf->avail_out;
|
||||||
|
def->next_in = raw;
|
||||||
|
if (inf->avail_out != 0)
|
||||||
|
flush = Z_FINISH;
|
||||||
|
ret = deflate(def, flush);
|
||||||
|
assert(ret != Z_STREAM_ERROR);
|
||||||
|
} while (ret != Z_STREAM_END && def->avail_out != 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXCESS 256 /* empirically determined stream overage */
|
||||||
|
#define MARGIN 8 /* amount to back off for completion */
|
||||||
|
|
||||||
|
/* compress from stdin to fixed-size block on stdout */
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret; /* return code */
|
||||||
|
unsigned size; /* requested fixed output block size */
|
||||||
|
unsigned have; /* bytes written by deflate() call */
|
||||||
|
unsigned char *blk; /* intermediate and final stream */
|
||||||
|
unsigned char *tmp; /* close to desired size stream */
|
||||||
|
z_stream def, inf; /* zlib deflate and inflate states */
|
||||||
|
|
||||||
|
/* get requested output size */
|
||||||
|
if (argc != 2)
|
||||||
|
quit("need one argument: size of output block");
|
||||||
|
ret = strtol(argv[1], argv + 1, 10);
|
||||||
|
if (argv[1][0] != 0)
|
||||||
|
quit("argument must be a number");
|
||||||
|
if (ret < 8) /* 8 is minimum zlib stream size */
|
||||||
|
quit("need positive size of 8 or greater");
|
||||||
|
size = (unsigned)ret;
|
||||||
|
|
||||||
|
/* allocate memory for buffers and compression engine */
|
||||||
|
blk = malloc(size + EXCESS);
|
||||||
|
def.zalloc = Z_NULL;
|
||||||
|
def.zfree = Z_NULL;
|
||||||
|
def.opaque = Z_NULL;
|
||||||
|
ret = deflateInit(&def, Z_DEFAULT_COMPRESSION);
|
||||||
|
if (ret != Z_OK || blk == NULL)
|
||||||
|
quit("out of memory");
|
||||||
|
|
||||||
|
/* compress from stdin until output full, or no more input */
|
||||||
|
def.avail_out = size + EXCESS;
|
||||||
|
def.next_out = blk;
|
||||||
|
ret = partcompress(stdin, &def);
|
||||||
|
if (ret == Z_ERRNO)
|
||||||
|
quit("error reading input");
|
||||||
|
|
||||||
|
/* if it all fit, then size was undersubscribed -- done! */
|
||||||
|
if (ret == Z_STREAM_END && def.avail_out >= EXCESS) {
|
||||||
|
/* write block to stdout */
|
||||||
|
have = size + EXCESS - def.avail_out;
|
||||||
|
if (fwrite(blk, 1, have, stdout) != have || ferror(stdout))
|
||||||
|
quit("error writing output");
|
||||||
|
|
||||||
|
/* clean up and print results to stderr */
|
||||||
|
ret = deflateEnd(&def);
|
||||||
|
assert(ret != Z_STREAM_ERROR);
|
||||||
|
free(blk);
|
||||||
|
fprintf(stderr,
|
||||||
|
"%u bytes unused out of %u requested (all input)\n",
|
||||||
|
size - have, size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* it didn't all fit -- set up for recompression */
|
||||||
|
inf.zalloc = Z_NULL;
|
||||||
|
inf.zfree = Z_NULL;
|
||||||
|
inf.opaque = Z_NULL;
|
||||||
|
inf.avail_in = 0;
|
||||||
|
inf.next_in = Z_NULL;
|
||||||
|
ret = inflateInit(&inf);
|
||||||
|
tmp = malloc(size + EXCESS);
|
||||||
|
if (ret != Z_OK || tmp == NULL)
|
||||||
|
quit("out of memory");
|
||||||
|
ret = deflateReset(&def);
|
||||||
|
assert(ret != Z_STREAM_ERROR);
|
||||||
|
|
||||||
|
/* do first recompression close to the right amount */
|
||||||
|
inf.avail_in = size + EXCESS;
|
||||||
|
inf.next_in = blk;
|
||||||
|
def.avail_out = size + EXCESS;
|
||||||
|
def.next_out = tmp;
|
||||||
|
ret = recompress(&inf, &def);
|
||||||
|
if (ret == Z_MEM_ERROR)
|
||||||
|
quit("out of memory");
|
||||||
|
|
||||||
|
/* set up for next reocmpression */
|
||||||
|
ret = inflateReset(&inf);
|
||||||
|
assert(ret != Z_STREAM_ERROR);
|
||||||
|
ret = deflateReset(&def);
|
||||||
|
assert(ret != Z_STREAM_ERROR);
|
||||||
|
|
||||||
|
/* do second and final recompression (third compression) */
|
||||||
|
inf.avail_in = size - MARGIN; /* assure stream will complete */
|
||||||
|
inf.next_in = tmp;
|
||||||
|
def.avail_out = size;
|
||||||
|
def.next_out = blk;
|
||||||
|
ret = recompress(&inf, &def);
|
||||||
|
if (ret == Z_MEM_ERROR)
|
||||||
|
quit("out of memory");
|
||||||
|
assert(ret == Z_STREAM_END); /* otherwise MARGIN too small */
|
||||||
|
|
||||||
|
/* done -- write block to stdout */
|
||||||
|
have = size - def.avail_out;
|
||||||
|
if (fwrite(blk, 1, have, stdout) != have || ferror(stdout))
|
||||||
|
quit("error writing output");
|
||||||
|
|
||||||
|
/* clean up and print results to stderr */
|
||||||
|
free(tmp);
|
||||||
|
ret = inflateEnd(&inf);
|
||||||
|
assert(ret != Z_STREAM_ERROR);
|
||||||
|
ret = deflateEnd(&def);
|
||||||
|
assert(ret != Z_STREAM_ERROR);
|
||||||
|
free(blk);
|
||||||
|
fprintf(stderr,
|
||||||
|
"%u bytes unused out of %u requested (%lu input)\n",
|
||||||
|
size - have, size, def.total_in);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,1002 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Yann Collet, Przemyslaw Skibinski, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* Includes
|
||||||
|
***************************************/
|
||||||
|
#include "util.h" /* Compiler options, UTIL_GetFileSize, UTIL_sleep */
|
||||||
|
#include <stdlib.h> /* malloc, free */
|
||||||
|
#include <string.h> /* memset */
|
||||||
|
#include <stdio.h> /* fprintf, fopen, ftello64 */
|
||||||
|
#include <time.h> /* clock_t, clock, CLOCKS_PER_SEC */
|
||||||
|
#include <ctype.h> /* toupper */
|
||||||
|
|
||||||
|
#include "mem.h"
|
||||||
|
#define ZSTD_STATIC_LINKING_ONLY
|
||||||
|
#include "zstd.h"
|
||||||
|
#include "datagen.h" /* RDG_genBuffer */
|
||||||
|
#include "xxhash.h"
|
||||||
|
|
||||||
|
#include "zstd_zlibwrapper.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-************************************
|
||||||
|
* Tuning parameters
|
||||||
|
**************************************/
|
||||||
|
#ifndef ZSTDCLI_CLEVEL_DEFAULT
|
||||||
|
# define ZSTDCLI_CLEVEL_DEFAULT 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-************************************
|
||||||
|
* Constants
|
||||||
|
**************************************/
|
||||||
|
#define COMPRESSOR_NAME "Zstandard wrapper for zlib command line interface"
|
||||||
|
#ifndef ZSTD_VERSION
|
||||||
|
# define ZSTD_VERSION "v" ZSTD_VERSION_STRING
|
||||||
|
#endif
|
||||||
|
#define AUTHOR "Yann Collet"
|
||||||
|
#define WELCOME_MESSAGE "*** %s %i-bits %s, by %s ***\n", COMPRESSOR_NAME, (int)(sizeof(size_t)*8), ZSTD_VERSION, AUTHOR
|
||||||
|
|
||||||
|
#ifndef ZSTD_GIT_COMMIT
|
||||||
|
# define ZSTD_GIT_COMMIT_STRING ""
|
||||||
|
#else
|
||||||
|
# define ZSTD_GIT_COMMIT_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_GIT_COMMIT)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NBLOOPS 3
|
||||||
|
#define TIMELOOP_MICROSEC 1*1000000ULL /* 1 second */
|
||||||
|
#define ACTIVEPERIOD_MICROSEC 70*1000000ULL /* 70 seconds */
|
||||||
|
#define COOLPERIOD_SEC 10
|
||||||
|
|
||||||
|
#define KB *(1 <<10)
|
||||||
|
#define MB *(1 <<20)
|
||||||
|
#define GB *(1U<<30)
|
||||||
|
|
||||||
|
static const size_t maxMemory = (sizeof(size_t)==4) ? (2 GB - 64 MB) : (size_t)(1ULL << ((sizeof(size_t)*8)-31));
|
||||||
|
|
||||||
|
static U32 g_compressibilityDefault = 50;
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* console display
|
||||||
|
***************************************/
|
||||||
|
#define DEFAULT_DISPLAY_LEVEL 2
|
||||||
|
#define DISPLAY(...) fprintf(displayOut, __VA_ARGS__)
|
||||||
|
#define DISPLAYLEVEL(l, ...) if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); }
|
||||||
|
static U32 g_displayLevel = DEFAULT_DISPLAY_LEVEL; /* 0 : no display; 1: errors; 2 : + result + interaction + warnings; 3 : + progression; 4 : + information */
|
||||||
|
static FILE* displayOut;
|
||||||
|
|
||||||
|
#define DISPLAYUPDATE(l, ...) if (g_displayLevel>=l) { \
|
||||||
|
if ((clock() - g_time > refreshRate) || (g_displayLevel>=4)) \
|
||||||
|
{ g_time = clock(); DISPLAY(__VA_ARGS__); \
|
||||||
|
if (g_displayLevel>=4) fflush(stdout); } }
|
||||||
|
static const clock_t refreshRate = CLOCKS_PER_SEC * 15 / 100;
|
||||||
|
static clock_t g_time = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* Exceptions
|
||||||
|
***************************************/
|
||||||
|
#ifndef DEBUG
|
||||||
|
# define DEBUG 0
|
||||||
|
#endif
|
||||||
|
#define DEBUGOUTPUT(...) if (DEBUG) DISPLAY(__VA_ARGS__);
|
||||||
|
#define EXM_THROW(error, ...) \
|
||||||
|
{ \
|
||||||
|
DEBUGOUTPUT("Error defined at %s, line %i : \n", __FILE__, __LINE__); \
|
||||||
|
DISPLAYLEVEL(1, "Error %i : ", error); \
|
||||||
|
DISPLAYLEVEL(1, __VA_ARGS__); \
|
||||||
|
DISPLAYLEVEL(1, "\n"); \
|
||||||
|
exit(error); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* Benchmark Parameters
|
||||||
|
***************************************/
|
||||||
|
static U32 g_nbIterations = NBLOOPS;
|
||||||
|
static size_t g_blockSize = 0;
|
||||||
|
int g_additionalParam = 0;
|
||||||
|
|
||||||
|
void BMK_setNotificationLevel(unsigned level) { g_displayLevel=level; }
|
||||||
|
|
||||||
|
void BMK_setAdditionalParam(int additionalParam) { g_additionalParam=additionalParam; }
|
||||||
|
|
||||||
|
void BMK_SetNbIterations(unsigned nbLoops)
|
||||||
|
{
|
||||||
|
g_nbIterations = nbLoops;
|
||||||
|
DISPLAYLEVEL(3, "- test >= %u seconds per compression / decompression -\n", g_nbIterations);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BMK_SetBlockSize(size_t blockSize)
|
||||||
|
{
|
||||||
|
g_blockSize = blockSize;
|
||||||
|
DISPLAYLEVEL(2, "using blocks of size %u KB \n", (U32)(blockSize>>10));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ********************************************************
|
||||||
|
* Bench functions
|
||||||
|
**********************************************************/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const char* srcPtr;
|
||||||
|
size_t srcSize;
|
||||||
|
char* cPtr;
|
||||||
|
size_t cRoom;
|
||||||
|
size_t cSize;
|
||||||
|
char* resPtr;
|
||||||
|
size_t resSize;
|
||||||
|
} blockParam_t;
|
||||||
|
|
||||||
|
typedef enum { BMK_ZSTD, BMK_ZSTD_STREAM, BMK_ZLIB, BMK_ZWRAP_ZLIB, BMK_ZWRAP_ZSTD, BMK_ZLIB_REUSE, BMK_ZWRAP_ZLIB_REUSE, BMK_ZWRAP_ZSTD_REUSE } BMK_compressor;
|
||||||
|
|
||||||
|
|
||||||
|
#define MIN(a,b) ((a)<(b) ? (a) : (b))
|
||||||
|
#define MAX(a,b) ((a)>(b) ? (a) : (b))
|
||||||
|
|
||||||
|
static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
||||||
|
const char* displayName, int cLevel,
|
||||||
|
const size_t* fileSizes, U32 nbFiles,
|
||||||
|
const void* dictBuffer, size_t dictBufferSize, BMK_compressor compressor)
|
||||||
|
{
|
||||||
|
size_t const blockSize = (g_blockSize>=32 ? g_blockSize : srcSize) + (!srcSize) /* avoid div by 0 */ ;
|
||||||
|
size_t const avgSize = MIN(g_blockSize, (srcSize / nbFiles));
|
||||||
|
U32 const maxNbBlocks = (U32) ((srcSize + (blockSize-1)) / blockSize) + nbFiles;
|
||||||
|
blockParam_t* const blockTable = (blockParam_t*) malloc(maxNbBlocks * sizeof(blockParam_t));
|
||||||
|
size_t const maxCompressedSize = ZSTD_compressBound(srcSize) + (maxNbBlocks * 1024); /* add some room for safety */
|
||||||
|
void* const compressedBuffer = malloc(maxCompressedSize);
|
||||||
|
void* const resultBuffer = malloc(srcSize);
|
||||||
|
ZSTD_CCtx* const ctx = ZSTD_createCCtx();
|
||||||
|
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
|
||||||
|
U32 nbBlocks;
|
||||||
|
UTIL_time_t ticksPerSecond;
|
||||||
|
|
||||||
|
/* checks */
|
||||||
|
if (!compressedBuffer || !resultBuffer || !blockTable || !ctx || !dctx)
|
||||||
|
EXM_THROW(31, "allocation error : not enough memory");
|
||||||
|
|
||||||
|
/* init */
|
||||||
|
if (strlen(displayName)>17) displayName += strlen(displayName)-17; /* can only display 17 characters */
|
||||||
|
UTIL_initTimer(&ticksPerSecond);
|
||||||
|
|
||||||
|
/* Init blockTable data */
|
||||||
|
{ const char* srcPtr = (const char*)srcBuffer;
|
||||||
|
char* cPtr = (char*)compressedBuffer;
|
||||||
|
char* resPtr = (char*)resultBuffer;
|
||||||
|
U32 fileNb;
|
||||||
|
for (nbBlocks=0, fileNb=0; fileNb<nbFiles; fileNb++) {
|
||||||
|
size_t remaining = fileSizes[fileNb];
|
||||||
|
U32 const nbBlocksforThisFile = (U32)((remaining + (blockSize-1)) / blockSize);
|
||||||
|
U32 const blockEnd = nbBlocks + nbBlocksforThisFile;
|
||||||
|
for ( ; nbBlocks<blockEnd; nbBlocks++) {
|
||||||
|
size_t const thisBlockSize = MIN(remaining, blockSize);
|
||||||
|
blockTable[nbBlocks].srcPtr = srcPtr;
|
||||||
|
blockTable[nbBlocks].cPtr = cPtr;
|
||||||
|
blockTable[nbBlocks].resPtr = resPtr;
|
||||||
|
blockTable[nbBlocks].srcSize = thisBlockSize;
|
||||||
|
blockTable[nbBlocks].cRoom = ZSTD_compressBound(thisBlockSize);
|
||||||
|
srcPtr += thisBlockSize;
|
||||||
|
cPtr += blockTable[nbBlocks].cRoom;
|
||||||
|
resPtr += thisBlockSize;
|
||||||
|
remaining -= thisBlockSize;
|
||||||
|
} } }
|
||||||
|
|
||||||
|
/* warmimg up memory */
|
||||||
|
RDG_genBuffer(compressedBuffer, maxCompressedSize, 0.10, 0.50, 1);
|
||||||
|
|
||||||
|
/* Bench */
|
||||||
|
{ U64 fastestC = (U64)(-1LL), fastestD = (U64)(-1LL);
|
||||||
|
U64 const crcOrig = XXH64(srcBuffer, srcSize, 0);
|
||||||
|
UTIL_time_t coolTime;
|
||||||
|
U64 const maxTime = (g_nbIterations * TIMELOOP_MICROSEC) + 100;
|
||||||
|
U64 totalCTime=0, totalDTime=0;
|
||||||
|
U32 cCompleted=0, dCompleted=0;
|
||||||
|
# define NB_MARKS 4
|
||||||
|
const char* const marks[NB_MARKS] = { " |", " /", " =", "\\" };
|
||||||
|
U32 markNb = 0;
|
||||||
|
size_t cSize = 0;
|
||||||
|
double ratio = 0.;
|
||||||
|
|
||||||
|
UTIL_getTime(&coolTime);
|
||||||
|
DISPLAYLEVEL(2, "\r%79s\r", "");
|
||||||
|
while (!cCompleted | !dCompleted) {
|
||||||
|
UTIL_time_t clockStart;
|
||||||
|
U64 clockLoop = g_nbIterations ? TIMELOOP_MICROSEC : 1;
|
||||||
|
|
||||||
|
/* overheat protection */
|
||||||
|
if (UTIL_clockSpanMicro(coolTime, ticksPerSecond) > ACTIVEPERIOD_MICROSEC) {
|
||||||
|
DISPLAYLEVEL(2, "\rcooling down ... \r");
|
||||||
|
UTIL_sleep(COOLPERIOD_SEC);
|
||||||
|
UTIL_getTime(&coolTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compression */
|
||||||
|
DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->\r", marks[markNb], displayName, (U32)srcSize);
|
||||||
|
if (!cCompleted) memset(compressedBuffer, 0xE5, maxCompressedSize); /* warm up and erase result buffer */
|
||||||
|
|
||||||
|
UTIL_sleepMilli(1); /* give processor time to other processes */
|
||||||
|
UTIL_waitForNextTick(ticksPerSecond);
|
||||||
|
UTIL_getTime(&clockStart);
|
||||||
|
|
||||||
|
if (!cCompleted) { /* still some time to do compression tests */
|
||||||
|
U32 nbLoops = 0;
|
||||||
|
if (compressor == BMK_ZSTD) {
|
||||||
|
ZSTD_parameters const zparams = ZSTD_getParams(cLevel, avgSize, dictBufferSize);
|
||||||
|
ZSTD_customMem const cmem = { NULL, NULL, NULL };
|
||||||
|
ZSTD_CDict* cdict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, zparams, cmem);
|
||||||
|
if (cdict==NULL) EXM_THROW(1, "ZSTD_createCDict_advanced() allocation failure");
|
||||||
|
|
||||||
|
do {
|
||||||
|
U32 blockNb;
|
||||||
|
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
|
||||||
|
size_t const rSize = ZSTD_compress_usingCDict(ctx,
|
||||||
|
blockTable[blockNb].cPtr, blockTable[blockNb].cRoom,
|
||||||
|
blockTable[blockNb].srcPtr,blockTable[blockNb].srcSize,
|
||||||
|
cdict);
|
||||||
|
if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_compress_usingCDict() failed : %s", ZSTD_getErrorName(rSize));
|
||||||
|
blockTable[blockNb].cSize = rSize;
|
||||||
|
}
|
||||||
|
nbLoops++;
|
||||||
|
} while (UTIL_clockSpanMicro(clockStart, ticksPerSecond) < clockLoop);
|
||||||
|
ZSTD_freeCDict(cdict);
|
||||||
|
} else if (compressor == BMK_ZSTD_STREAM) {
|
||||||
|
ZSTD_parameters const zparams = ZSTD_getParams(cLevel, avgSize, dictBufferSize);
|
||||||
|
ZSTD_inBuffer inBuffer;
|
||||||
|
ZSTD_outBuffer outBuffer;
|
||||||
|
ZSTD_CStream* zbc = ZSTD_createCStream();
|
||||||
|
size_t rSize;
|
||||||
|
if (zbc == NULL) EXM_THROW(1, "ZSTD_createCStream() allocation failure");
|
||||||
|
rSize = ZSTD_initCStream_advanced(zbc, dictBuffer, dictBufferSize, zparams, avgSize);
|
||||||
|
if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_initCStream_advanced() failed : %s", ZSTD_getErrorName(rSize));
|
||||||
|
do {
|
||||||
|
U32 blockNb;
|
||||||
|
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
|
||||||
|
rSize = ZSTD_resetCStream(zbc, blockTable[blockNb].srcSize);
|
||||||
|
if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_resetCStream() failed : %s", ZSTD_getErrorName(rSize));
|
||||||
|
inBuffer.src = blockTable[blockNb].srcPtr;
|
||||||
|
inBuffer.size = blockTable[blockNb].srcSize;
|
||||||
|
inBuffer.pos = 0;
|
||||||
|
outBuffer.dst = blockTable[blockNb].cPtr;
|
||||||
|
outBuffer.size = blockTable[blockNb].cRoom;
|
||||||
|
outBuffer.pos = 0;
|
||||||
|
rSize = ZSTD_compressStream(zbc, &outBuffer, &inBuffer);
|
||||||
|
if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_compressStream() failed : %s", ZSTD_getErrorName(rSize));
|
||||||
|
rSize = ZSTD_endStream(zbc, &outBuffer);
|
||||||
|
if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_endStream() failed : %s", ZSTD_getErrorName(rSize));
|
||||||
|
blockTable[blockNb].cSize = outBuffer.pos;
|
||||||
|
}
|
||||||
|
nbLoops++;
|
||||||
|
} while (UTIL_clockSpanMicro(clockStart, ticksPerSecond) < clockLoop);
|
||||||
|
ZSTD_freeCStream(zbc);
|
||||||
|
} else if (compressor == BMK_ZWRAP_ZLIB_REUSE || compressor == BMK_ZWRAP_ZSTD_REUSE || compressor == BMK_ZLIB_REUSE) {
|
||||||
|
z_stream def;
|
||||||
|
int ret;
|
||||||
|
int useSetDict = (dictBuffer != NULL);
|
||||||
|
if (compressor == BMK_ZLIB_REUSE || compressor == BMK_ZWRAP_ZLIB_REUSE) ZWRAP_useZSTDcompression(0);
|
||||||
|
else ZWRAP_useZSTDcompression(1);
|
||||||
|
def.zalloc = Z_NULL;
|
||||||
|
def.zfree = Z_NULL;
|
||||||
|
def.opaque = Z_NULL;
|
||||||
|
ret = deflateInit(&def, cLevel);
|
||||||
|
if (ret != Z_OK) EXM_THROW(1, "deflateInit failure");
|
||||||
|
/* if (ZWRAP_isUsingZSTDcompression()) {
|
||||||
|
ret = ZWRAP_setPledgedSrcSize(&def, avgSize);
|
||||||
|
if (ret != Z_OK) EXM_THROW(1, "ZWRAP_setPledgedSrcSize failure");
|
||||||
|
} */
|
||||||
|
do {
|
||||||
|
U32 blockNb;
|
||||||
|
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
|
||||||
|
if (ZWRAP_isUsingZSTDcompression())
|
||||||
|
ret = ZWRAP_deflateReset_keepDict(&def); /* reuse dictionary to make compression faster */
|
||||||
|
else
|
||||||
|
ret = deflateReset(&def);
|
||||||
|
if (ret != Z_OK) EXM_THROW(1, "deflateReset failure");
|
||||||
|
if (useSetDict) {
|
||||||
|
ret = deflateSetDictionary(&def, dictBuffer, dictBufferSize);
|
||||||
|
if (ret != Z_OK) EXM_THROW(1, "deflateSetDictionary failure");
|
||||||
|
if (ZWRAP_isUsingZSTDcompression()) useSetDict = 0; /* zstd doesn't require deflateSetDictionary after ZWRAP_deflateReset_keepDict */
|
||||||
|
}
|
||||||
|
def.next_in = (const void*) blockTable[blockNb].srcPtr;
|
||||||
|
def.avail_in = blockTable[blockNb].srcSize;
|
||||||
|
def.total_in = 0;
|
||||||
|
def.next_out = (void*) blockTable[blockNb].cPtr;
|
||||||
|
def.avail_out = blockTable[blockNb].cRoom;
|
||||||
|
def.total_out = 0;
|
||||||
|
ret = deflate(&def, Z_FINISH);
|
||||||
|
if (ret != Z_STREAM_END) EXM_THROW(1, "deflate failure ret=%d srcSize=%d" , ret, (int)blockTable[blockNb].srcSize);
|
||||||
|
blockTable[blockNb].cSize = def.total_out;
|
||||||
|
}
|
||||||
|
nbLoops++;
|
||||||
|
} while (UTIL_clockSpanMicro(clockStart, ticksPerSecond) < clockLoop);
|
||||||
|
ret = deflateEnd(&def);
|
||||||
|
if (ret != Z_OK) EXM_THROW(1, "deflateEnd failure");
|
||||||
|
} else {
|
||||||
|
z_stream def;
|
||||||
|
if (compressor == BMK_ZLIB || compressor == BMK_ZWRAP_ZLIB) ZWRAP_useZSTDcompression(0);
|
||||||
|
else ZWRAP_useZSTDcompression(1);
|
||||||
|
do {
|
||||||
|
U32 blockNb;
|
||||||
|
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
|
||||||
|
int ret;
|
||||||
|
def.zalloc = Z_NULL;
|
||||||
|
def.zfree = Z_NULL;
|
||||||
|
def.opaque = Z_NULL;
|
||||||
|
ret = deflateInit(&def, cLevel);
|
||||||
|
if (ret != Z_OK) EXM_THROW(1, "deflateInit failure");
|
||||||
|
if (dictBuffer) {
|
||||||
|
ret = deflateSetDictionary(&def, dictBuffer, dictBufferSize);
|
||||||
|
if (ret != Z_OK) EXM_THROW(1, "deflateSetDictionary failure");
|
||||||
|
}
|
||||||
|
def.next_in = (const void*) blockTable[blockNb].srcPtr;
|
||||||
|
def.avail_in = blockTable[blockNb].srcSize;
|
||||||
|
def.total_in = 0;
|
||||||
|
def.next_out = (void*) blockTable[blockNb].cPtr;
|
||||||
|
def.avail_out = blockTable[blockNb].cRoom;
|
||||||
|
def.total_out = 0;
|
||||||
|
ret = deflate(&def, Z_FINISH);
|
||||||
|
if (ret != Z_STREAM_END) EXM_THROW(1, "deflate failure");
|
||||||
|
ret = deflateEnd(&def);
|
||||||
|
if (ret != Z_OK) EXM_THROW(1, "deflateEnd failure");
|
||||||
|
blockTable[blockNb].cSize = def.total_out;
|
||||||
|
}
|
||||||
|
nbLoops++;
|
||||||
|
} while (UTIL_clockSpanMicro(clockStart, ticksPerSecond) < clockLoop);
|
||||||
|
}
|
||||||
|
{ U64 const clockSpan = UTIL_clockSpanMicro(clockStart, ticksPerSecond);
|
||||||
|
if (clockSpan < fastestC*nbLoops) fastestC = clockSpan / nbLoops;
|
||||||
|
totalCTime += clockSpan;
|
||||||
|
cCompleted = totalCTime>maxTime;
|
||||||
|
} }
|
||||||
|
|
||||||
|
cSize = 0;
|
||||||
|
{ U32 blockNb; for (blockNb=0; blockNb<nbBlocks; blockNb++) cSize += blockTable[blockNb].cSize; }
|
||||||
|
ratio = (double)srcSize / (double)cSize;
|
||||||
|
markNb = (markNb+1) % NB_MARKS;
|
||||||
|
DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.3f),%6.1f MB/s\r",
|
||||||
|
marks[markNb], displayName, (U32)srcSize, (U32)cSize, ratio,
|
||||||
|
(double)srcSize / fastestC );
|
||||||
|
|
||||||
|
(void)fastestD; (void)crcOrig; /* unused when decompression disabled */
|
||||||
|
#if 1
|
||||||
|
/* Decompression */
|
||||||
|
if (!dCompleted) memset(resultBuffer, 0xD6, srcSize); /* warm result buffer */
|
||||||
|
|
||||||
|
UTIL_sleepMilli(1); /* give processor time to other processes */
|
||||||
|
UTIL_waitForNextTick(ticksPerSecond);
|
||||||
|
UTIL_getTime(&clockStart);
|
||||||
|
|
||||||
|
if (!dCompleted) {
|
||||||
|
U32 nbLoops = 0;
|
||||||
|
if (compressor == BMK_ZSTD) {
|
||||||
|
ZSTD_DDict* ddict = ZSTD_createDDict(dictBuffer, dictBufferSize);
|
||||||
|
if (!ddict) EXM_THROW(2, "ZSTD_createDDict() allocation failure");
|
||||||
|
do {
|
||||||
|
U32 blockNb;
|
||||||
|
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
|
||||||
|
size_t const regenSize = ZSTD_decompress_usingDDict(dctx,
|
||||||
|
blockTable[blockNb].resPtr, blockTable[blockNb].srcSize,
|
||||||
|
blockTable[blockNb].cPtr, blockTable[blockNb].cSize,
|
||||||
|
ddict);
|
||||||
|
if (ZSTD_isError(regenSize)) {
|
||||||
|
DISPLAY("ZSTD_decompress_usingDDict() failed on block %u : %s \n",
|
||||||
|
blockNb, ZSTD_getErrorName(regenSize));
|
||||||
|
clockLoop = 0; /* force immediate test end */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
blockTable[blockNb].resSize = regenSize;
|
||||||
|
}
|
||||||
|
nbLoops++;
|
||||||
|
} while (UTIL_clockSpanMicro(clockStart, ticksPerSecond) < clockLoop);
|
||||||
|
ZSTD_freeDDict(ddict);
|
||||||
|
} else if (compressor == BMK_ZSTD_STREAM) {
|
||||||
|
ZSTD_inBuffer inBuffer;
|
||||||
|
ZSTD_outBuffer outBuffer;
|
||||||
|
ZSTD_DStream* zbd = ZSTD_createDStream();
|
||||||
|
size_t rSize;
|
||||||
|
if (zbd == NULL) EXM_THROW(1, "ZSTD_createDStream() allocation failure");
|
||||||
|
rSize = ZSTD_initDStream_usingDict(zbd, dictBuffer, dictBufferSize);
|
||||||
|
if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_initDStream() failed : %s", ZSTD_getErrorName(rSize));
|
||||||
|
do {
|
||||||
|
U32 blockNb;
|
||||||
|
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
|
||||||
|
rSize = ZSTD_resetDStream(zbd);
|
||||||
|
if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_resetDStream() failed : %s", ZSTD_getErrorName(rSize));
|
||||||
|
inBuffer.src = blockTable[blockNb].cPtr;
|
||||||
|
inBuffer.size = blockTable[blockNb].cSize;
|
||||||
|
inBuffer.pos = 0;
|
||||||
|
outBuffer.dst = blockTable[blockNb].resPtr;
|
||||||
|
outBuffer.size = blockTable[blockNb].srcSize;
|
||||||
|
outBuffer.pos = 0;
|
||||||
|
rSize = ZSTD_decompressStream(zbd, &outBuffer, &inBuffer);
|
||||||
|
if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_decompressStream() failed : %s", ZSTD_getErrorName(rSize));
|
||||||
|
blockTable[blockNb].resSize = outBuffer.pos;
|
||||||
|
}
|
||||||
|
nbLoops++;
|
||||||
|
} while (UTIL_clockSpanMicro(clockStart, ticksPerSecond) < clockLoop);
|
||||||
|
ZSTD_freeDStream(zbd);
|
||||||
|
} else if (compressor == BMK_ZWRAP_ZLIB_REUSE || compressor == BMK_ZWRAP_ZSTD_REUSE || compressor == BMK_ZLIB_REUSE) {
|
||||||
|
z_stream inf;
|
||||||
|
int ret;
|
||||||
|
if (compressor == BMK_ZLIB_REUSE) ZWRAP_setDecompressionType(ZWRAP_FORCE_ZLIB);
|
||||||
|
else ZWRAP_setDecompressionType(ZWRAP_AUTO);
|
||||||
|
inf.zalloc = Z_NULL;
|
||||||
|
inf.zfree = Z_NULL;
|
||||||
|
inf.opaque = Z_NULL;
|
||||||
|
ret = inflateInit(&inf);
|
||||||
|
if (ret != Z_OK) EXM_THROW(1, "inflateInit failure");
|
||||||
|
do {
|
||||||
|
U32 blockNb;
|
||||||
|
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
|
||||||
|
if (ZWRAP_isUsingZSTDdecompression(&inf))
|
||||||
|
ret = ZWRAP_inflateReset_keepDict(&inf); /* reuse dictionary to make decompression faster; inflate will return Z_NEED_DICT only for the first time */
|
||||||
|
else
|
||||||
|
ret = inflateReset(&inf);
|
||||||
|
if (ret != Z_OK) EXM_THROW(1, "inflateReset failure");
|
||||||
|
inf.next_in = (const void*) blockTable[blockNb].cPtr;
|
||||||
|
inf.avail_in = blockTable[blockNb].cSize;
|
||||||
|
inf.total_in = 0;
|
||||||
|
inf.next_out = (void*) blockTable[blockNb].resPtr;
|
||||||
|
inf.avail_out = blockTable[blockNb].srcSize;
|
||||||
|
inf.total_out = 0;
|
||||||
|
ret = inflate(&inf, Z_FINISH);
|
||||||
|
if (ret == Z_NEED_DICT) {
|
||||||
|
ret = inflateSetDictionary(&inf, dictBuffer, dictBufferSize);
|
||||||
|
if (ret != Z_OK) EXM_THROW(1, "inflateSetDictionary failure");
|
||||||
|
ret = inflate(&inf, Z_FINISH);
|
||||||
|
}
|
||||||
|
if (ret != Z_STREAM_END) EXM_THROW(1, "inflate failure");
|
||||||
|
blockTable[blockNb].resSize = inf.total_out;
|
||||||
|
}
|
||||||
|
nbLoops++;
|
||||||
|
} while (UTIL_clockSpanMicro(clockStart, ticksPerSecond) < clockLoop);
|
||||||
|
ret = inflateEnd(&inf);
|
||||||
|
if (ret != Z_OK) EXM_THROW(1, "inflateEnd failure");
|
||||||
|
} else {
|
||||||
|
z_stream inf;
|
||||||
|
if (compressor == BMK_ZLIB) ZWRAP_setDecompressionType(ZWRAP_FORCE_ZLIB);
|
||||||
|
else ZWRAP_setDecompressionType(ZWRAP_AUTO);
|
||||||
|
do {
|
||||||
|
U32 blockNb;
|
||||||
|
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
|
||||||
|
int ret;
|
||||||
|
inf.zalloc = Z_NULL;
|
||||||
|
inf.zfree = Z_NULL;
|
||||||
|
inf.opaque = Z_NULL;
|
||||||
|
ret = inflateInit(&inf);
|
||||||
|
if (ret != Z_OK) EXM_THROW(1, "inflateInit failure");
|
||||||
|
inf.next_in = (const void*) blockTable[blockNb].cPtr;
|
||||||
|
inf.avail_in = blockTable[blockNb].cSize;
|
||||||
|
inf.total_in = 0;
|
||||||
|
inf.next_out = (void*) blockTable[blockNb].resPtr;
|
||||||
|
inf.avail_out = blockTable[blockNb].srcSize;
|
||||||
|
inf.total_out = 0;
|
||||||
|
ret = inflate(&inf, Z_FINISH);
|
||||||
|
if (ret == Z_NEED_DICT) {
|
||||||
|
ret = inflateSetDictionary(&inf, dictBuffer, dictBufferSize);
|
||||||
|
if (ret != Z_OK) EXM_THROW(1, "inflateSetDictionary failure");
|
||||||
|
ret = inflate(&inf, Z_FINISH);
|
||||||
|
}
|
||||||
|
if (ret != Z_STREAM_END) EXM_THROW(1, "inflate failure");
|
||||||
|
ret = inflateEnd(&inf);
|
||||||
|
if (ret != Z_OK) EXM_THROW(1, "inflateEnd failure");
|
||||||
|
blockTable[blockNb].resSize = inf.total_out;
|
||||||
|
}
|
||||||
|
nbLoops++;
|
||||||
|
} while (UTIL_clockSpanMicro(clockStart, ticksPerSecond) < clockLoop);
|
||||||
|
}
|
||||||
|
{ U64 const clockSpan = UTIL_clockSpanMicro(clockStart, ticksPerSecond);
|
||||||
|
if (clockSpan < fastestD*nbLoops) fastestD = clockSpan / nbLoops;
|
||||||
|
totalDTime += clockSpan;
|
||||||
|
dCompleted = totalDTime>maxTime;
|
||||||
|
} }
|
||||||
|
|
||||||
|
markNb = (markNb+1) % NB_MARKS;
|
||||||
|
DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.3f),%6.1f MB/s ,%6.1f MB/s\r",
|
||||||
|
marks[markNb], displayName, (U32)srcSize, (U32)cSize, ratio,
|
||||||
|
(double)srcSize / fastestC,
|
||||||
|
(double)srcSize / fastestD );
|
||||||
|
|
||||||
|
/* CRC Checking */
|
||||||
|
{ U64 const crcCheck = XXH64(resultBuffer, srcSize, 0);
|
||||||
|
if (crcOrig!=crcCheck) {
|
||||||
|
size_t u;
|
||||||
|
DISPLAY("!!! WARNING !!! %14s : Invalid Checksum : %x != %x \n", displayName, (unsigned)crcOrig, (unsigned)crcCheck);
|
||||||
|
for (u=0; u<srcSize; u++) {
|
||||||
|
if (((const BYTE*)srcBuffer)[u] != ((const BYTE*)resultBuffer)[u]) {
|
||||||
|
U32 segNb, bNb, pos;
|
||||||
|
size_t bacc = 0;
|
||||||
|
DISPLAY("Decoding error at pos %u ", (U32)u);
|
||||||
|
for (segNb = 0; segNb < nbBlocks; segNb++) {
|
||||||
|
if (bacc + blockTable[segNb].srcSize > u) break;
|
||||||
|
bacc += blockTable[segNb].srcSize;
|
||||||
|
}
|
||||||
|
pos = (U32)(u - bacc);
|
||||||
|
bNb = pos / (128 KB);
|
||||||
|
DISPLAY("(block %u, sub %u, pos %u) \n", segNb, bNb, pos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (u==srcSize-1) { /* should never happen */
|
||||||
|
DISPLAY("no difference detected\n");
|
||||||
|
} }
|
||||||
|
break;
|
||||||
|
} } /* CRC Checking */
|
||||||
|
#endif
|
||||||
|
} /* for (testNb = 1; testNb <= (g_nbIterations + !g_nbIterations); testNb++) */
|
||||||
|
|
||||||
|
if (g_displayLevel == 1) {
|
||||||
|
double cSpeed = (double)srcSize / fastestC;
|
||||||
|
double dSpeed = (double)srcSize / fastestD;
|
||||||
|
if (g_additionalParam)
|
||||||
|
DISPLAY("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s (param=%d)\n", cLevel, (int)cSize, ratio, cSpeed, dSpeed, displayName, g_additionalParam);
|
||||||
|
else
|
||||||
|
DISPLAY("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s\n", cLevel, (int)cSize, ratio, cSpeed, dSpeed, displayName);
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(2, "%2i#\n", cLevel);
|
||||||
|
} /* Bench */
|
||||||
|
|
||||||
|
/* clean up */
|
||||||
|
free(blockTable);
|
||||||
|
free(compressedBuffer);
|
||||||
|
free(resultBuffer);
|
||||||
|
ZSTD_freeCCtx(ctx);
|
||||||
|
ZSTD_freeDCtx(dctx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t BMK_findMaxMem(U64 requiredMem)
|
||||||
|
{
|
||||||
|
size_t const step = 64 MB;
|
||||||
|
BYTE* testmem = NULL;
|
||||||
|
|
||||||
|
requiredMem = (((requiredMem >> 26) + 1) << 26);
|
||||||
|
requiredMem += step;
|
||||||
|
if (requiredMem > maxMemory) requiredMem = maxMemory;
|
||||||
|
|
||||||
|
do {
|
||||||
|
testmem = (BYTE*)malloc((size_t)requiredMem);
|
||||||
|
requiredMem -= step;
|
||||||
|
} while (!testmem);
|
||||||
|
|
||||||
|
free(testmem);
|
||||||
|
return (size_t)(requiredMem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize,
|
||||||
|
const char* displayName, int cLevel, int cLevelLast,
|
||||||
|
const size_t* fileSizes, unsigned nbFiles,
|
||||||
|
const void* dictBuffer, size_t dictBufferSize)
|
||||||
|
{
|
||||||
|
int l;
|
||||||
|
|
||||||
|
const char* pch = strrchr(displayName, '\\'); /* Windows */
|
||||||
|
if (!pch) pch = strrchr(displayName, '/'); /* Linux */
|
||||||
|
if (pch) displayName = pch+1;
|
||||||
|
|
||||||
|
SET_HIGH_PRIORITY;
|
||||||
|
|
||||||
|
if (g_displayLevel == 1 && !g_additionalParam)
|
||||||
|
DISPLAY("bench %s %s: input %u bytes, %u seconds, %u KB blocks\n", ZSTD_VERSION_STRING, ZSTD_GIT_COMMIT_STRING, (U32)benchedSize, g_nbIterations, (U32)(g_blockSize>>10));
|
||||||
|
|
||||||
|
if (cLevelLast < cLevel) cLevelLast = cLevel;
|
||||||
|
|
||||||
|
DISPLAY("benchmarking zstd %s (using ZSTD_CCtx)\n", ZSTD_VERSION_STRING);
|
||||||
|
for (l=cLevel; l <= cLevelLast; l++) {
|
||||||
|
BMK_benchMem(srcBuffer, benchedSize,
|
||||||
|
displayName, l,
|
||||||
|
fileSizes, nbFiles,
|
||||||
|
dictBuffer, dictBufferSize, BMK_ZSTD);
|
||||||
|
}
|
||||||
|
|
||||||
|
DISPLAY("benchmarking zstd %s (using ZSTD_CStream)\n", ZSTD_VERSION_STRING);
|
||||||
|
for (l=cLevel; l <= cLevelLast; l++) {
|
||||||
|
BMK_benchMem(srcBuffer, benchedSize,
|
||||||
|
displayName, l,
|
||||||
|
fileSizes, nbFiles,
|
||||||
|
dictBuffer, dictBufferSize, BMK_ZSTD_STREAM);
|
||||||
|
}
|
||||||
|
|
||||||
|
DISPLAY("benchmarking zstd %s (using zlibWrapper)\n", ZSTD_VERSION_STRING);
|
||||||
|
for (l=cLevel; l <= cLevelLast; l++) {
|
||||||
|
BMK_benchMem(srcBuffer, benchedSize,
|
||||||
|
displayName, l,
|
||||||
|
fileSizes, nbFiles,
|
||||||
|
dictBuffer, dictBufferSize, BMK_ZWRAP_ZSTD_REUSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
DISPLAY("benchmarking zstd %s (zlibWrapper not reusing a context)\n", ZSTD_VERSION_STRING);
|
||||||
|
for (l=cLevel; l <= cLevelLast; l++) {
|
||||||
|
BMK_benchMem(srcBuffer, benchedSize,
|
||||||
|
displayName, l,
|
||||||
|
fileSizes, nbFiles,
|
||||||
|
dictBuffer, dictBufferSize, BMK_ZWRAP_ZSTD);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (cLevelLast > Z_BEST_COMPRESSION) cLevelLast = Z_BEST_COMPRESSION;
|
||||||
|
|
||||||
|
DISPLAY("\n");
|
||||||
|
DISPLAY("benchmarking zlib %s\n", ZLIB_VERSION);
|
||||||
|
for (l=cLevel; l <= cLevelLast; l++) {
|
||||||
|
BMK_benchMem(srcBuffer, benchedSize,
|
||||||
|
displayName, l,
|
||||||
|
fileSizes, nbFiles,
|
||||||
|
dictBuffer, dictBufferSize, BMK_ZLIB_REUSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
DISPLAY("benchmarking zlib %s (zlib not reusing a context)\n", ZLIB_VERSION);
|
||||||
|
for (l=cLevel; l <= cLevelLast; l++) {
|
||||||
|
BMK_benchMem(srcBuffer, benchedSize,
|
||||||
|
displayName, l,
|
||||||
|
fileSizes, nbFiles,
|
||||||
|
dictBuffer, dictBufferSize, BMK_ZLIB);
|
||||||
|
}
|
||||||
|
|
||||||
|
DISPLAY("benchmarking zlib %s (using zlibWrapper)\n", ZLIB_VERSION);
|
||||||
|
for (l=cLevel; l <= cLevelLast; l++) {
|
||||||
|
BMK_benchMem(srcBuffer, benchedSize,
|
||||||
|
displayName, l,
|
||||||
|
fileSizes, nbFiles,
|
||||||
|
dictBuffer, dictBufferSize, BMK_ZWRAP_ZLIB_REUSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
DISPLAY("benchmarking zlib %s (zlibWrapper not reusing a context)\n", ZLIB_VERSION);
|
||||||
|
for (l=cLevel; l <= cLevelLast; l++) {
|
||||||
|
BMK_benchMem(srcBuffer, benchedSize,
|
||||||
|
displayName, l,
|
||||||
|
fileSizes, nbFiles,
|
||||||
|
dictBuffer, dictBufferSize, BMK_ZWRAP_ZLIB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! BMK_loadFiles() :
|
||||||
|
Loads `buffer` with content of files listed within `fileNamesTable`.
|
||||||
|
At most, fills `buffer` entirely */
|
||||||
|
static void BMK_loadFiles(void* buffer, size_t bufferSize,
|
||||||
|
size_t* fileSizes,
|
||||||
|
const char** fileNamesTable, unsigned nbFiles)
|
||||||
|
{
|
||||||
|
size_t pos = 0, totalSize = 0;
|
||||||
|
unsigned n;
|
||||||
|
for (n=0; n<nbFiles; n++) {
|
||||||
|
FILE* f;
|
||||||
|
U64 fileSize = UTIL_getFileSize(fileNamesTable[n]);
|
||||||
|
if (UTIL_isDirectory(fileNamesTable[n])) {
|
||||||
|
DISPLAYLEVEL(2, "Ignoring %s directory... \n", fileNamesTable[n]);
|
||||||
|
fileSizes[n] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
f = fopen(fileNamesTable[n], "rb");
|
||||||
|
if (f==NULL) EXM_THROW(10, "impossible to open file %s", fileNamesTable[n]);
|
||||||
|
DISPLAYUPDATE(2, "Loading %s... \r", fileNamesTable[n]);
|
||||||
|
if (fileSize > bufferSize-pos) fileSize = bufferSize-pos, nbFiles=n; /* buffer too small - stop after this file */
|
||||||
|
{ size_t const readSize = fread(((char*)buffer)+pos, 1, (size_t)fileSize, f);
|
||||||
|
if (readSize != (size_t)fileSize) EXM_THROW(11, "could not read %s", fileNamesTable[n]);
|
||||||
|
pos += readSize; }
|
||||||
|
fileSizes[n] = (size_t)fileSize;
|
||||||
|
totalSize += (size_t)fileSize;
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totalSize == 0) EXM_THROW(12, "no data to bench");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BMK_benchFileTable(const char** fileNamesTable, unsigned nbFiles,
|
||||||
|
const char* dictFileName, int cLevel, int cLevelLast)
|
||||||
|
{
|
||||||
|
void* srcBuffer;
|
||||||
|
size_t benchedSize;
|
||||||
|
void* dictBuffer = NULL;
|
||||||
|
size_t dictBufferSize = 0;
|
||||||
|
size_t* fileSizes = (size_t*)malloc(nbFiles * sizeof(size_t));
|
||||||
|
U64 const totalSizeToLoad = UTIL_getTotalFileSize(fileNamesTable, nbFiles);
|
||||||
|
char mfName[20] = {0};
|
||||||
|
|
||||||
|
if (!fileSizes) EXM_THROW(12, "not enough memory for fileSizes");
|
||||||
|
|
||||||
|
/* Load dictionary */
|
||||||
|
if (dictFileName != NULL) {
|
||||||
|
U64 dictFileSize = UTIL_getFileSize(dictFileName);
|
||||||
|
if (dictFileSize > 64 MB) EXM_THROW(10, "dictionary file %s too large", dictFileName);
|
||||||
|
dictBufferSize = (size_t)dictFileSize;
|
||||||
|
dictBuffer = malloc(dictBufferSize);
|
||||||
|
if (dictBuffer==NULL) EXM_THROW(11, "not enough memory for dictionary (%u bytes)", (U32)dictBufferSize);
|
||||||
|
BMK_loadFiles(dictBuffer, dictBufferSize, fileSizes, &dictFileName, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Memory allocation & restrictions */
|
||||||
|
benchedSize = BMK_findMaxMem(totalSizeToLoad * 3) / 3;
|
||||||
|
if ((U64)benchedSize > totalSizeToLoad) benchedSize = (size_t)totalSizeToLoad;
|
||||||
|
if (benchedSize < totalSizeToLoad)
|
||||||
|
DISPLAY("Not enough memory; testing %u MB only...\n", (U32)(benchedSize >> 20));
|
||||||
|
srcBuffer = malloc(benchedSize);
|
||||||
|
if (!srcBuffer) EXM_THROW(12, "not enough memory");
|
||||||
|
|
||||||
|
/* Load input buffer */
|
||||||
|
BMK_loadFiles(srcBuffer, benchedSize, fileSizes, fileNamesTable, nbFiles);
|
||||||
|
|
||||||
|
/* Bench */
|
||||||
|
snprintf (mfName, sizeof(mfName), " %u files", nbFiles);
|
||||||
|
{ const char* displayName = (nbFiles > 1) ? mfName : fileNamesTable[0];
|
||||||
|
BMK_benchCLevel(srcBuffer, benchedSize,
|
||||||
|
displayName, cLevel, cLevelLast,
|
||||||
|
fileSizes, nbFiles,
|
||||||
|
dictBuffer, dictBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean up */
|
||||||
|
free(srcBuffer);
|
||||||
|
free(dictBuffer);
|
||||||
|
free(fileSizes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void BMK_syntheticTest(int cLevel, int cLevelLast, double compressibility)
|
||||||
|
{
|
||||||
|
char name[20] = {0};
|
||||||
|
size_t benchedSize = 10000000;
|
||||||
|
void* const srcBuffer = malloc(benchedSize);
|
||||||
|
|
||||||
|
/* Memory allocation */
|
||||||
|
if (!srcBuffer) EXM_THROW(21, "not enough memory");
|
||||||
|
|
||||||
|
/* Fill input buffer */
|
||||||
|
RDG_genBuffer(srcBuffer, benchedSize, compressibility, 0.0, 0);
|
||||||
|
|
||||||
|
/* Bench */
|
||||||
|
snprintf (name, sizeof(name), "Synthetic %2u%%", (unsigned)(compressibility*100));
|
||||||
|
BMK_benchCLevel(srcBuffer, benchedSize, name, cLevel, cLevelLast, &benchedSize, 1, NULL, 0);
|
||||||
|
|
||||||
|
/* clean up */
|
||||||
|
free(srcBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles,
|
||||||
|
const char* dictFileName, int cLevel, int cLevelLast)
|
||||||
|
{
|
||||||
|
double const compressibility = (double)g_compressibilityDefault / 100;
|
||||||
|
|
||||||
|
if (nbFiles == 0)
|
||||||
|
BMK_syntheticTest(cLevel, cLevelLast, compressibility);
|
||||||
|
else
|
||||||
|
BMK_benchFileTable(fileNamesTable, nbFiles, dictFileName, cLevel, cLevelLast);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-************************************
|
||||||
|
* Command Line
|
||||||
|
**************************************/
|
||||||
|
static int usage(const char* programName)
|
||||||
|
{
|
||||||
|
DISPLAY(WELCOME_MESSAGE);
|
||||||
|
DISPLAY( "Usage :\n");
|
||||||
|
DISPLAY( " %s [args] [FILE(s)] [-o file]\n", programName);
|
||||||
|
DISPLAY( "\n");
|
||||||
|
DISPLAY( "FILE : a filename\n");
|
||||||
|
DISPLAY( " with no FILE, or when FILE is - , read standard input\n");
|
||||||
|
DISPLAY( "Arguments :\n");
|
||||||
|
DISPLAY( " -D file: use `file` as Dictionary \n");
|
||||||
|
DISPLAY( " -h/-H : display help/long help and exit\n");
|
||||||
|
DISPLAY( " -V : display Version number and exit\n");
|
||||||
|
DISPLAY( " -v : verbose mode; specify multiple times to increase log level (default:%d)\n", DEFAULT_DISPLAY_LEVEL);
|
||||||
|
DISPLAY( " -q : suppress warnings; specify twice to suppress errors too\n");
|
||||||
|
#ifdef UTIL_HAS_CREATEFILELIST
|
||||||
|
DISPLAY( " -r : operate recursively on directories\n");
|
||||||
|
#endif
|
||||||
|
DISPLAY( "\n");
|
||||||
|
DISPLAY( "Benchmark arguments :\n");
|
||||||
|
DISPLAY( " -b# : benchmark file(s), using # compression level (default : %d) \n", ZSTDCLI_CLEVEL_DEFAULT);
|
||||||
|
DISPLAY( " -e# : test all compression levels from -bX to # (default: %d)\n", ZSTDCLI_CLEVEL_DEFAULT);
|
||||||
|
DISPLAY( " -i# : minimum evaluation time in seconds (default : 3s)\n");
|
||||||
|
DISPLAY( " -B# : cut file into independent blocks of size # (default: no block)\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int badusage(const char* programName)
|
||||||
|
{
|
||||||
|
DISPLAYLEVEL(1, "Incorrect parameters\n");
|
||||||
|
if (g_displayLevel >= 1) usage(programName);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void waitEnter(void)
|
||||||
|
{
|
||||||
|
int unused;
|
||||||
|
DISPLAY("Press enter to continue...\n");
|
||||||
|
unused = getchar();
|
||||||
|
(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 digit string > MAX_UINT */
|
||||||
|
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; }
|
||||||
|
|
||||||
|
int main(int argCount, char** argv)
|
||||||
|
{
|
||||||
|
int argNb,
|
||||||
|
main_pause=0,
|
||||||
|
nextEntryIsDictionary=0,
|
||||||
|
operationResult=0,
|
||||||
|
nextArgumentIsFile=0;
|
||||||
|
int cLevel = ZSTDCLI_CLEVEL_DEFAULT;
|
||||||
|
int cLevelLast = 1;
|
||||||
|
unsigned recursive = 0;
|
||||||
|
const char** filenameTable = (const char**)malloc(argCount * sizeof(const char*)); /* argCount >= 1 */
|
||||||
|
unsigned filenameIdx = 0;
|
||||||
|
const char* programName = argv[0];
|
||||||
|
const char* dictFileName = NULL;
|
||||||
|
char* dynNameSpace = NULL;
|
||||||
|
#ifdef UTIL_HAS_CREATEFILELIST
|
||||||
|
const char** fileNamesTable = NULL;
|
||||||
|
char* fileNamesBuf = NULL;
|
||||||
|
unsigned fileNamesNb;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* init */
|
||||||
|
if (filenameTable==NULL) { DISPLAY("zstd: %s \n", strerror(errno)); exit(1); }
|
||||||
|
displayOut = stderr;
|
||||||
|
|
||||||
|
/* Pick out program name from path. Don't rely on stdlib because of conflicting behavior */
|
||||||
|
{ size_t pos;
|
||||||
|
for (pos = (int)strlen(programName); pos > 0; pos--) { if (programName[pos] == '/') { pos++; break; } }
|
||||||
|
programName += pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* command switches */
|
||||||
|
for(argNb=1; argNb<argCount; argNb++) {
|
||||||
|
const char* argument = argv[argNb];
|
||||||
|
if(!argument) continue; /* Protection if argument empty */
|
||||||
|
|
||||||
|
if (nextArgumentIsFile==0) {
|
||||||
|
|
||||||
|
/* long commands (--long-word) */
|
||||||
|
if (!strcmp(argument, "--")) { nextArgumentIsFile=1; continue; }
|
||||||
|
if (!strcmp(argument, "--version")) { displayOut=stdout; DISPLAY(WELCOME_MESSAGE); CLEAN_RETURN(0); }
|
||||||
|
if (!strcmp(argument, "--help")) { displayOut=stdout; CLEAN_RETURN(usage(programName)); }
|
||||||
|
if (!strcmp(argument, "--verbose")) { g_displayLevel++; continue; }
|
||||||
|
if (!strcmp(argument, "--quiet")) { g_displayLevel--; continue; }
|
||||||
|
|
||||||
|
/* Decode commands (note : aggregated commands are allowed) */
|
||||||
|
if (argument[0]=='-') {
|
||||||
|
argument++;
|
||||||
|
|
||||||
|
while (argument[0]!=0) {
|
||||||
|
switch(argument[0])
|
||||||
|
{
|
||||||
|
/* Display help */
|
||||||
|
case 'V': displayOut=stdout; DISPLAY(WELCOME_MESSAGE); CLEAN_RETURN(0); /* Version Only */
|
||||||
|
case 'H':
|
||||||
|
case 'h': displayOut=stdout; CLEAN_RETURN(usage(programName));
|
||||||
|
|
||||||
|
/* Use file content as dictionary */
|
||||||
|
case 'D': nextEntryIsDictionary = 1; argument++; break;
|
||||||
|
|
||||||
|
/* Verbose mode */
|
||||||
|
case 'v': g_displayLevel++; argument++; break;
|
||||||
|
|
||||||
|
/* Quiet mode */
|
||||||
|
case 'q': g_displayLevel--; argument++; break;
|
||||||
|
|
||||||
|
#ifdef UTIL_HAS_CREATEFILELIST
|
||||||
|
/* recursive */
|
||||||
|
case 'r': recursive=1; argument++; break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Benchmark */
|
||||||
|
case 'b':
|
||||||
|
/* first compression Level */
|
||||||
|
argument++;
|
||||||
|
cLevel = readU32FromChar(&argument);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* range bench (benchmark only) */
|
||||||
|
case 'e':
|
||||||
|
/* last compression Level */
|
||||||
|
argument++;
|
||||||
|
cLevelLast = readU32FromChar(&argument);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Modify Nb Iterations (benchmark only) */
|
||||||
|
case 'i':
|
||||||
|
argument++;
|
||||||
|
{ U32 const iters = readU32FromChar(&argument);
|
||||||
|
BMK_setNotificationLevel(g_displayLevel);
|
||||||
|
BMK_SetNbIterations(iters);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* cut input into blocks (benchmark only) */
|
||||||
|
case 'B':
|
||||||
|
argument++;
|
||||||
|
{ size_t bSize = readU32FromChar(&argument);
|
||||||
|
if (toupper(*argument)=='K') bSize<<=10, argument++; /* allows using KB notation */
|
||||||
|
if (toupper(*argument)=='M') bSize<<=20, argument++;
|
||||||
|
if (toupper(*argument)=='B') argument++;
|
||||||
|
BMK_setNotificationLevel(g_displayLevel);
|
||||||
|
BMK_SetBlockSize(bSize);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Pause at the end (-p) or set an additional param (-p#) (hidden option) */
|
||||||
|
case 'p': argument++;
|
||||||
|
if ((*argument>='0') && (*argument<='9')) {
|
||||||
|
BMK_setAdditionalParam(readU32FromChar(&argument));
|
||||||
|
} else
|
||||||
|
main_pause=1;
|
||||||
|
break;
|
||||||
|
/* unknown command */
|
||||||
|
default : CLEAN_RETURN(badusage(programName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} /* if (argument[0]=='-') */
|
||||||
|
|
||||||
|
} /* if (nextArgumentIsAFile==0) */
|
||||||
|
|
||||||
|
if (nextEntryIsDictionary) {
|
||||||
|
nextEntryIsDictionary = 0;
|
||||||
|
dictFileName = argument;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add filename to list */
|
||||||
|
filenameTable[filenameIdx++] = argument;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Welcome message (if verbose) */
|
||||||
|
DISPLAYLEVEL(3, WELCOME_MESSAGE);
|
||||||
|
|
||||||
|
#ifdef UTIL_HAS_CREATEFILELIST
|
||||||
|
if (recursive) {
|
||||||
|
fileNamesTable = UTIL_createFileList(filenameTable, filenameIdx, &fileNamesBuf, &fileNamesNb);
|
||||||
|
if (fileNamesTable) {
|
||||||
|
unsigned u;
|
||||||
|
for (u=0; u<fileNamesNb; u++) DISPLAYLEVEL(4, "%u %s\n", u, fileNamesTable[u]);
|
||||||
|
free((void*)filenameTable);
|
||||||
|
filenameTable = fileNamesTable;
|
||||||
|
filenameIdx = fileNamesNb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BMK_setNotificationLevel(g_displayLevel);
|
||||||
|
BMK_benchFiles(filenameTable, filenameIdx, dictFileName, cLevel, cLevelLast);
|
||||||
|
|
||||||
|
_end:
|
||||||
|
if (main_pause) waitEnter();
|
||||||
|
free(dynNameSpace);
|
||||||
|
#ifdef UTIL_HAS_CREATEFILELIST
|
||||||
|
if (fileNamesTable)
|
||||||
|
UTIL_freeFileList(fileNamesTable, fileNamesBuf);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
free((void*)filenameTable);
|
||||||
|
return operationResult;
|
||||||
|
}
|
||||||
+569
-323
@@ -1,33 +1,12 @@
|
|||||||
/*
|
/**
|
||||||
zstd_zlibwrapper.c - zstd wrapper for zlib
|
* Copyright (c) 2016-present, Przemyslaw Skibinski, Facebook, Inc.
|
||||||
Copyright (C) 2016, Przemyslaw Skibinski.
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h> /* vsprintf */
|
#include <stdio.h> /* vsprintf */
|
||||||
#include <stdarg.h> /* va_list, for z_gzprintf */
|
#include <stdarg.h> /* va_list, for z_gzprintf */
|
||||||
@@ -35,50 +14,48 @@
|
|||||||
#include "zstd_zlibwrapper.h"
|
#include "zstd_zlibwrapper.h"
|
||||||
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_MAGICNUMBER */
|
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_MAGICNUMBER */
|
||||||
#include "zstd.h"
|
#include "zstd.h"
|
||||||
#define ZBUFF_STATIC_LINKING_ONLY /* ZBUFF_createCCtx_advanced */
|
|
||||||
#include "zbuff.h"
|
|
||||||
#include "zstd_internal.h" /* defaultCustomMem */
|
#include "zstd_internal.h" /* defaultCustomMem */
|
||||||
|
|
||||||
|
|
||||||
#define Z_INFLATE_SYNC 8
|
#define Z_INFLATE_SYNC 8
|
||||||
#define ZWRAP_HEADERSIZE 4
|
#define ZLIB_HEADERSIZE 4
|
||||||
#define ZWRAP_DEFAULT_CLEVEL 5 /* Z_DEFAULT_COMPRESSION is translated to ZWRAP_DEFAULT_CLEVEL for zstd */
|
#define ZSTD_HEADERSIZE ZSTD_frameHeaderSize_min
|
||||||
|
#define ZWRAP_DEFAULT_CLEVEL 3 /* Z_DEFAULT_COMPRESSION is translated to ZWRAP_DEFAULT_CLEVEL for zstd */
|
||||||
|
|
||||||
#define LOG_WRAPPER(...) // printf(__VA_ARGS__)
|
#define LOG_WRAPPERC(...) /* printf(__VA_ARGS__) */
|
||||||
|
#define LOG_WRAPPERD(...) /* printf(__VA_ARGS__) */
|
||||||
|
|
||||||
|
#define FINISH_WITH_GZ_ERR(msg) { (void)msg; return Z_STREAM_ERROR; }
|
||||||
|
#define FINISH_WITH_NULL_ERR(msg) { (void)msg; return NULL; }
|
||||||
|
|
||||||
|
|
||||||
#define FINISH_WITH_GZ_ERR(msg) { \
|
|
||||||
(void)msg; \
|
|
||||||
return Z_MEM_ERROR; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FINISH_WITH_ERR(strm, message) { \
|
|
||||||
strm->msg = message; \
|
|
||||||
return Z_MEM_ERROR; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FINISH_WITH_NULL_ERR(msg) { \
|
|
||||||
(void)msg; \
|
|
||||||
return NULL; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef ZWRAP_USE_ZSTD
|
#ifndef ZWRAP_USE_ZSTD
|
||||||
#define ZWRAP_USE_ZSTD 0
|
#define ZWRAP_USE_ZSTD 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int g_useZSTD = ZWRAP_USE_ZSTD; /* 0 = don't use ZSTD */
|
static int g_ZWRAP_useZSTDcompression = ZWRAP_USE_ZSTD; /* 0 = don't use ZSTD */
|
||||||
|
|
||||||
|
void ZWRAP_useZSTDcompression(int turn_on) { g_ZWRAP_useZSTDcompression = turn_on; }
|
||||||
|
|
||||||
|
int ZWRAP_isUsingZSTDcompression(void) { return g_ZWRAP_useZSTDcompression; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void useZSTD(int turn_on) { g_useZSTD = turn_on; }
|
static ZWRAP_decompress_type g_ZWRAPdecompressionType = ZWRAP_AUTO;
|
||||||
|
|
||||||
|
void ZWRAP_setDecompressionType(ZWRAP_decompress_type type) { g_ZWRAPdecompressionType = type; };
|
||||||
|
|
||||||
|
ZWRAP_decompress_type ZWRAP_getDecompressionType(void) { return g_ZWRAPdecompressionType; }
|
||||||
|
|
||||||
|
|
||||||
int isUsingZSTD(void) { return g_useZSTD; }
|
|
||||||
|
|
||||||
const char * zstdVersion(void) { 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)
|
static void* ZWRAP_allocFunction(void* opaque, size_t size)
|
||||||
{
|
{
|
||||||
z_streamp strm = (z_streamp) opaque;
|
z_streamp strm = (z_streamp) opaque;
|
||||||
@@ -97,20 +74,24 @@ static void ZWRAP_freeFunction(void* opaque, void* address)
|
|||||||
|
|
||||||
|
|
||||||
/* *** Compression *** */
|
/* *** Compression *** */
|
||||||
|
typedef enum { ZWRAP_useInit, ZWRAP_useReset, ZWRAP_streamEnd } ZWRAP_state_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ZBUFF_CCtx* zbc;
|
ZSTD_CStream* zbc;
|
||||||
size_t bytesLeft;
|
|
||||||
int compressionLevel;
|
int compressionLevel;
|
||||||
ZSTD_customMem customMem;
|
ZSTD_customMem customMem;
|
||||||
z_stream allocFunc; /* copy of zalloc, zfree, opaque */
|
z_stream allocFunc; /* copy of zalloc, zfree, opaque */
|
||||||
|
ZSTD_inBuffer inBuffer;
|
||||||
|
ZSTD_outBuffer outBuffer;
|
||||||
|
ZWRAP_state_t comprState;
|
||||||
|
unsigned long long pledgedSrcSize;
|
||||||
} ZWRAP_CCtx;
|
} ZWRAP_CCtx;
|
||||||
|
|
||||||
|
|
||||||
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);
|
if (zwc->zbc) ZSTD_freeCStream(zwc->zbc);
|
||||||
zwc->customMem.customFree(zwc->customMem.opaque, zwc);
|
zwc->customMem.customFree(zwc->customMem.opaque, zwc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -135,36 +116,77 @@ ZWRAP_CCtx* ZWRAP_createCCtx(z_streamp strm)
|
|||||||
memcpy(&zwc->customMem, &defaultCustomMem, sizeof(ZSTD_customMem));
|
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;
|
return zwc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ZWRAP_initializeCStream(ZWRAP_CCtx* zwc, const void* dict, size_t dictSize, unsigned long long pledgedSrcSize)
|
||||||
|
{
|
||||||
|
LOG_WRAPPERC("- ZWRAP_initializeCStream=%p\n", zwc);
|
||||||
|
if (zwc == NULL || zwc->zbc == NULL) return Z_STREAM_ERROR;
|
||||||
|
|
||||||
|
if (!pledgedSrcSize) pledgedSrcSize = zwc->pledgedSrcSize;
|
||||||
|
{ ZSTD_parameters const params = ZSTD_getParams(zwc->compressionLevel, pledgedSrcSize, dictSize);
|
||||||
|
size_t errorCode;
|
||||||
|
LOG_WRAPPERC("pledgedSrcSize=%d windowLog=%d chainLog=%d hashLog=%d searchLog=%d searchLength=%d strategy=%d\n", (int)pledgedSrcSize, params.cParams.windowLog, params.cParams.chainLog, params.cParams.hashLog, params.cParams.searchLog, params.cParams.searchLength, params.cParams.strategy);
|
||||||
|
errorCode = ZSTD_initCStream_advanced(zwc->zbc, dict, dictSize, params, pledgedSrcSize);
|
||||||
|
if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR; }
|
||||||
|
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ZWRAPC_finishWithError(ZWRAP_CCtx* zwc, z_streamp strm, int error)
|
||||||
|
{
|
||||||
|
LOG_WRAPPERC("- ZWRAPC_finishWithError=%d\n", error);
|
||||||
|
if (zwc) ZWRAP_freeCCtx(zwc);
|
||||||
|
if (strm) strm->state = NULL;
|
||||||
|
return (error) ? error : Z_STREAM_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ZWRAPC_finishWithErrorMsg(z_streamp strm, char* message)
|
||||||
|
{
|
||||||
|
ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
|
||||||
|
strm->msg = message;
|
||||||
|
if (zwc == NULL) return Z_STREAM_ERROR;
|
||||||
|
|
||||||
|
return ZWRAPC_finishWithError(zwc, strm, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ZWRAP_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize)
|
||||||
|
{
|
||||||
|
ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
|
||||||
|
if (zwc == NULL) return Z_STREAM_ERROR;
|
||||||
|
|
||||||
|
zwc->pledgedSrcSize = pledgedSrcSize;
|
||||||
|
zwc->comprState = ZWRAP_useInit;
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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))
|
||||||
{
|
{
|
||||||
ZWRAP_CCtx* zwc;
|
ZWRAP_CCtx* zwc;
|
||||||
|
|
||||||
if (!g_useZSTD) {
|
LOG_WRAPPERC("- deflateInit level=%d\n", level);
|
||||||
LOG_WRAPPER("- deflateInit level=%d\n", level);
|
if (!g_ZWRAP_useZSTDcompression) {
|
||||||
return deflateInit_((strm), (level), version, stream_size);
|
return deflateInit_((strm), (level), version, stream_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_WRAPPER("- deflateInit level=%d\n", level);
|
|
||||||
zwc = ZWRAP_createCCtx(strm);
|
zwc = ZWRAP_createCCtx(strm);
|
||||||
if (zwc == NULL) return Z_MEM_ERROR;
|
if (zwc == NULL) return Z_MEM_ERROR;
|
||||||
|
|
||||||
if (level == Z_DEFAULT_COMPRESSION)
|
if (level == Z_DEFAULT_COMPRESSION)
|
||||||
level = ZWRAP_DEFAULT_CLEVEL;
|
level = ZWRAP_DEFAULT_CLEVEL;
|
||||||
|
|
||||||
{ size_t const errorCode = ZBUFF_compressInit(zwc->zbc, level);
|
|
||||||
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; }
|
|
||||||
|
|
||||||
zwc->compressionLevel = level;
|
zwc->compressionLevel = level;
|
||||||
strm->state = (struct internal_state*) zwc; /* use state which in not used by user */
|
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;
|
||||||
|
strm->adler = 0;
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,26 +196,62 @@ ZEXTERN int ZEXPORT z_deflateInit2_ OF((z_streamp strm, int level, int method,
|
|||||||
int strategy, const char *version,
|
int strategy, const char *version,
|
||||||
int stream_size))
|
int stream_size))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return deflateInit2_(strm, level, method, windowBits, memLevel, strategy, version, stream_size);
|
return deflateInit2_(strm, level, method, windowBits, memLevel, strategy, version, stream_size);
|
||||||
|
|
||||||
return z_deflateInit_ (strm, level, version, stream_size);
|
return z_deflateInit_ (strm, level, version, stream_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ZWRAP_deflateReset_keepDict(z_streamp strm)
|
||||||
|
{
|
||||||
|
LOG_WRAPPERC("- ZWRAP_deflateReset_keepDict\n");
|
||||||
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
|
return deflateReset(strm);
|
||||||
|
|
||||||
|
strm->total_in = 0;
|
||||||
|
strm->total_out = 0;
|
||||||
|
strm->adler = 0;
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm))
|
||||||
|
{
|
||||||
|
LOG_WRAPPERC("- deflateReset\n");
|
||||||
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
|
return deflateReset(strm);
|
||||||
|
|
||||||
|
ZWRAP_deflateReset_keepDict(strm);
|
||||||
|
|
||||||
|
{ ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
|
||||||
|
if (zwc) zwc->comprState = 0;
|
||||||
|
}
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm,
|
ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm,
|
||||||
const Bytef *dictionary,
|
const Bytef *dictionary,
|
||||||
uInt dictLength))
|
uInt dictLength))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression) {
|
||||||
|
LOG_WRAPPERC("- deflateSetDictionary\n");
|
||||||
return deflateSetDictionary(strm, dictionary, dictLength);
|
return deflateSetDictionary(strm, dictionary, dictLength);
|
||||||
|
}
|
||||||
|
|
||||||
{ ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
|
{ ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
|
||||||
LOG_WRAPPER("- deflateSetDictionary level=%d\n", (int)strm->data_type);
|
LOG_WRAPPERC("- deflateSetDictionary level=%d\n", (int)zwc->compressionLevel);
|
||||||
{ size_t const errorCode = ZBUFF_compressInitDictionary(zwc->zbc, dictionary, dictLength, zwc->compressionLevel);
|
if (!zwc) return Z_STREAM_ERROR;
|
||||||
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; }
|
if (zwc->zbc == NULL) {
|
||||||
|
zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem);
|
||||||
|
if (zwc->zbc == NULL) return ZWRAPC_finishWithError(zwc, strm, 0);
|
||||||
|
}
|
||||||
|
{ int res = ZWRAP_initializeCStream(zwc, dictionary, dictLength, 0);
|
||||||
|
if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); }
|
||||||
|
zwc->comprState = ZWRAP_useReset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,76 +260,102 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush))
|
|||||||
{
|
{
|
||||||
ZWRAP_CCtx* zwc;
|
ZWRAP_CCtx* zwc;
|
||||||
|
|
||||||
if (!g_useZSTD) {
|
if (!g_ZWRAP_useZSTDcompression) {
|
||||||
int res = deflate(strm, flush);
|
int res;
|
||||||
LOG_WRAPPER("- avail_in=%d total_in=%d total_out=%d\n", (int)strm->avail_in, (int)strm->total_in, (int)strm->total_out);
|
LOG_WRAPPERC("- deflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
|
||||||
|
res = deflate(strm, flush);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
zwc = (ZWRAP_CCtx*) strm->state;
|
zwc = (ZWRAP_CCtx*) strm->state;
|
||||||
|
if (zwc == NULL) { LOG_WRAPPERC("zwc == NULL\n"); return Z_STREAM_ERROR; }
|
||||||
|
|
||||||
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 (zwc->zbc == NULL) {
|
||||||
if (strm->avail_in > 0) {
|
int res;
|
||||||
size_t dstCapacity = strm->avail_out;
|
zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem);
|
||||||
size_t srcSize = strm->avail_in;
|
if (zwc->zbc == NULL) return ZWRAPC_finishWithError(zwc, strm, 0);
|
||||||
size_t const errorCode = ZBUFF_compressContinue(zwc->zbc, strm->next_out, &dstCapacity, strm->next_in, &srcSize);
|
res = ZWRAP_initializeCStream(zwc, NULL, 0, (flush == Z_FINISH) ? strm->avail_in : 0);
|
||||||
LOG_WRAPPER("ZBUFF_compressContinue srcSize=%d dstCapacity=%d\n", (int)srcSize, (int)dstCapacity);
|
if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res);
|
||||||
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
|
if (flush != Z_FINISH) zwc->comprState = ZWRAP_useReset;
|
||||||
strm->next_out += dstCapacity;
|
} else {
|
||||||
strm->total_out += dstCapacity;
|
if (strm->total_in == 0) {
|
||||||
strm->avail_out -= dstCapacity;
|
if (zwc->comprState == ZWRAP_useReset) {
|
||||||
strm->total_in += srcSize;
|
size_t const errorCode = ZSTD_resetCStream(zwc->zbc, (flush == Z_FINISH) ? strm->avail_in : zwc->pledgedSrcSize);
|
||||||
strm->next_in += srcSize;
|
if (ZSTD_isError(errorCode)) { LOG_WRAPPERC("ERROR: ZSTD_resetCStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); return ZWRAPC_finishWithError(zwc, strm, 0); }
|
||||||
strm->avail_in -= srcSize;
|
} else {
|
||||||
|
int res = ZWRAP_initializeCStream(zwc, NULL, 0, (flush == Z_FINISH) ? strm->avail_in : 0);
|
||||||
|
if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res);
|
||||||
|
if (flush != Z_FINISH) zwc->comprState = ZWRAP_useReset;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flush == Z_FULL_FLUSH) FINISH_WITH_ERR(strm, "Z_FULL_FLUSH is not supported!");
|
LOG_WRAPPERC("- deflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
|
||||||
|
if (strm->avail_in > 0) {
|
||||||
|
zwc->inBuffer.src = strm->next_in;
|
||||||
|
zwc->inBuffer.size = strm->avail_in;
|
||||||
|
zwc->inBuffer.pos = 0;
|
||||||
|
zwc->outBuffer.dst = strm->next_out;
|
||||||
|
zwc->outBuffer.size = strm->avail_out;
|
||||||
|
zwc->outBuffer.pos = 0;
|
||||||
|
{ size_t const errorCode = ZSTD_compressStream(zwc->zbc, &zwc->outBuffer, &zwc->inBuffer);
|
||||||
|
LOG_WRAPPERC("deflate ZSTD_compressStream srcSize=%d dstCapacity=%d\n", (int)zwc->inBuffer.size, (int)zwc->outBuffer.size);
|
||||||
|
if (ZSTD_isError(errorCode)) return ZWRAPC_finishWithError(zwc, strm, 0);
|
||||||
|
}
|
||||||
|
strm->next_out += zwc->outBuffer.pos;
|
||||||
|
strm->total_out += zwc->outBuffer.pos;
|
||||||
|
strm->avail_out -= zwc->outBuffer.pos;
|
||||||
|
strm->total_in += zwc->inBuffer.pos;
|
||||||
|
strm->next_in += zwc->inBuffer.pos;
|
||||||
|
strm->avail_in -= zwc->inBuffer.pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flush == Z_FULL_FLUSH || flush == Z_BLOCK || flush == Z_TREES) return ZWRAPC_finishWithErrorMsg(strm, "Z_FULL_FLUSH, Z_BLOCK and Z_TREES are not supported!");
|
||||||
|
|
||||||
if (flush == Z_FINISH) {
|
if (flush == Z_FINISH) {
|
||||||
size_t bytesLeft;
|
size_t bytesLeft;
|
||||||
size_t dstCapacity = strm->avail_out;
|
zwc->outBuffer.dst = strm->next_out;
|
||||||
if (zwc->bytesLeft) {
|
zwc->outBuffer.size = strm->avail_out;
|
||||||
bytesLeft = ZBUFF_compressFlush(zwc->zbc, strm->next_out, &dstCapacity);
|
zwc->outBuffer.pos = 0;
|
||||||
LOG_WRAPPER("ZBUFF_compressFlush avail_out=%d dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)dstCapacity, (int)bytesLeft);
|
bytesLeft = ZSTD_endStream(zwc->zbc, &zwc->outBuffer);
|
||||||
} else {
|
LOG_WRAPPERC("deflate ZSTD_endStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft);
|
||||||
bytesLeft = ZBUFF_compressEnd(zwc->zbc, strm->next_out, &dstCapacity);
|
if (ZSTD_isError(bytesLeft)) return ZWRAPC_finishWithError(zwc, strm, 0);
|
||||||
LOG_WRAPPER("ZBUFF_compressEnd dstCapacity=%d bytesLeft=%d\n", (int)dstCapacity, (int)bytesLeft);
|
strm->next_out += zwc->outBuffer.pos;
|
||||||
// { size_t const errorCode = ZBUFF_compressInit(zwc->zbc, 1);
|
strm->total_out += zwc->outBuffer.pos;
|
||||||
// if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; }
|
strm->avail_out -= zwc->outBuffer.pos;
|
||||||
}
|
if (bytesLeft == 0) { LOG_WRAPPERC("Z_STREAM_END2 strm->total_in=%d strm->avail_out=%d strm->total_out=%d\n", (int)strm->total_in, (int)strm->avail_out, (int)strm->total_out); return Z_STREAM_END; }
|
||||||
if (ZSTD_isError(bytesLeft)) return Z_MEM_ERROR;
|
|
||||||
strm->next_out += dstCapacity;
|
|
||||||
strm->total_out += dstCapacity;
|
|
||||||
strm->avail_out -= dstCapacity;
|
|
||||||
if (flush == Z_FINISH && bytesLeft == 0) return Z_STREAM_END;
|
|
||||||
zwc->bytesLeft = bytesLeft;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (flush == Z_SYNC_FLUSH) {
|
if (flush == Z_SYNC_FLUSH || flush == Z_PARTIAL_FLUSH) {
|
||||||
size_t bytesLeft;
|
size_t bytesLeft;
|
||||||
size_t dstCapacity = strm->avail_out;
|
zwc->outBuffer.dst = strm->next_out;
|
||||||
bytesLeft = ZBUFF_compressFlush(zwc->zbc, strm->next_out, &dstCapacity);
|
zwc->outBuffer.size = strm->avail_out;
|
||||||
LOG_WRAPPER("ZBUFF_compressFlush avail_out=%d dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)dstCapacity, (int)bytesLeft);
|
zwc->outBuffer.pos = 0;
|
||||||
if (ZSTD_isError(bytesLeft)) return Z_MEM_ERROR;
|
bytesLeft = ZSTD_flushStream(zwc->zbc, &zwc->outBuffer);
|
||||||
strm->next_out += dstCapacity;
|
LOG_WRAPPERC("deflate ZSTD_flushStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft);
|
||||||
strm->total_out += dstCapacity;
|
if (ZSTD_isError(bytesLeft)) return ZWRAPC_finishWithError(zwc, strm, 0);
|
||||||
strm->avail_out -= dstCapacity;
|
strm->next_out += zwc->outBuffer.pos;
|
||||||
zwc->bytesLeft = bytesLeft;
|
strm->total_out += zwc->outBuffer.pos;
|
||||||
|
strm->avail_out -= zwc->outBuffer.pos;
|
||||||
}
|
}
|
||||||
|
LOG_WRAPPERC("- deflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_deflateEnd OF((z_streamp strm))
|
ZEXTERN int ZEXPORT z_deflateEnd OF((z_streamp strm))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD) {
|
if (!g_ZWRAP_useZSTDcompression) {
|
||||||
LOG_WRAPPER("- deflateEnd\n");
|
LOG_WRAPPERC("- deflateEnd\n");
|
||||||
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_WRAPPERC("- deflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out));
|
||||||
{ ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
|
{ size_t errorCode;
|
||||||
size_t const errorCode = ZWRAP_freeCCtx(zwc);
|
ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
|
||||||
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
|
if (zwc == NULL) return Z_OK; /* structures are already freed */
|
||||||
|
strm->state = NULL;
|
||||||
|
errorCode = ZWRAP_freeCCtx(zwc);
|
||||||
|
if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR;
|
||||||
}
|
}
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
@@ -280,7 +364,7 @@ ZEXTERN int ZEXPORT z_deflateEnd OF((z_streamp strm))
|
|||||||
ZEXTERN uLong ZEXPORT z_deflateBound OF((z_streamp strm,
|
ZEXTERN uLong ZEXPORT z_deflateBound OF((z_streamp strm,
|
||||||
uLong sourceLen))
|
uLong sourceLen))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return deflateBound(strm, sourceLen);
|
return deflateBound(strm, sourceLen);
|
||||||
|
|
||||||
return ZSTD_compressBound(sourceLen);
|
return ZSTD_compressBound(sourceLen);
|
||||||
@@ -291,8 +375,8 @@ ZEXTERN int ZEXPORT z_deflateParams OF((z_streamp strm,
|
|||||||
int level,
|
int level,
|
||||||
int strategy))
|
int strategy))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD) {
|
if (!g_ZWRAP_useZSTDcompression) {
|
||||||
LOG_WRAPPER("- deflateParams level=%d strategy=%d\n", level, strategy);
|
LOG_WRAPPERC("- deflateParams level=%d strategy=%d\n", level, strategy);
|
||||||
return deflateParams(strm, level, strategy);
|
return deflateParams(strm, level, strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,12 +388,16 @@ ZEXTERN int ZEXPORT z_deflateParams OF((z_streamp strm,
|
|||||||
|
|
||||||
|
|
||||||
/* *** Decompression *** */
|
/* *** Decompression *** */
|
||||||
|
typedef enum { ZWRAP_ZLIB_STREAM, ZWRAP_ZSTD_STREAM, ZWRAP_UNKNOWN_STREAM } ZWRAP_stream_type;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ZBUFF_DCtx* zbd;
|
ZSTD_DStream* zbd;
|
||||||
char headerBuf[ZWRAP_HEADERSIZE];
|
char headerBuf[16]; /* should be equal or bigger than ZSTD_frameHeaderSize_min */
|
||||||
int errorCount;
|
int errorCount;
|
||||||
|
ZWRAP_state_t decompState;
|
||||||
|
ZSTD_inBuffer inBuffer;
|
||||||
|
ZSTD_outBuffer outBuffer;
|
||||||
|
|
||||||
/* zlib params */
|
/* zlib params */
|
||||||
int stream_size;
|
int stream_size;
|
||||||
char *version;
|
char *version;
|
||||||
@@ -319,6 +407,21 @@ typedef struct {
|
|||||||
} ZWRAP_DCtx;
|
} ZWRAP_DCtx;
|
||||||
|
|
||||||
|
|
||||||
|
int ZWRAP_isUsingZSTDdecompression(z_streamp strm)
|
||||||
|
{
|
||||||
|
if (strm == NULL) return 0;
|
||||||
|
return (strm->reserved == ZWRAP_ZSTD_STREAM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ZWRAP_initDCtx(ZWRAP_DCtx* zwd)
|
||||||
|
{
|
||||||
|
zwd->errorCount = 0;
|
||||||
|
zwd->outBuffer.pos = 0;
|
||||||
|
zwd->outBuffer.size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm)
|
ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm)
|
||||||
{
|
{
|
||||||
ZWRAP_DCtx* zwd;
|
ZWRAP_DCtx* zwd;
|
||||||
@@ -338,6 +441,8 @@ ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm)
|
|||||||
memcpy(&zwd->customMem, &defaultCustomMem, sizeof(ZSTD_customMem));
|
memcpy(&zwd->customMem, &defaultCustomMem, sizeof(ZSTD_customMem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MEM_STATIC_ASSERT(sizeof(zwd->headerBuf) >= ZSTD_frameHeaderSize_min); /* if compilation fails here, assertion is false */
|
||||||
|
ZWRAP_initDCtx(zwd);
|
||||||
return zwd;
|
return zwd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,29 +450,56 @@ ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm)
|
|||||||
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 */
|
||||||
ZBUFF_freeDCtx(zwd->zbd);
|
if (zwd->zbd) ZSTD_freeDStream(zwd->zbd);
|
||||||
if (zwd->version) zwd->customMem.customFree(zwd->customMem.opaque, zwd->version);
|
if (zwd->version) zwd->customMem.customFree(zwd->customMem.opaque, zwd->version);
|
||||||
zwd->customMem.customFree(zwd->customMem.opaque, zwd);
|
zwd->customMem.customFree(zwd->customMem.opaque, zwd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ZWRAPD_finishWithError(ZWRAP_DCtx* zwd, z_streamp strm, int error)
|
||||||
|
{
|
||||||
|
LOG_WRAPPERD("- ZWRAPD_finishWithError=%d\n", error);
|
||||||
|
if (zwd) ZWRAP_freeDCtx(zwd);
|
||||||
|
if (strm) strm->state = NULL;
|
||||||
|
return (error) ? error : Z_STREAM_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ZWRAPD_finishWithErrorMsg(z_streamp strm, char* message)
|
||||||
|
{
|
||||||
|
ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
|
||||||
|
strm->msg = message;
|
||||||
|
if (zwd == NULL) return Z_STREAM_ERROR;
|
||||||
|
|
||||||
|
return ZWRAPD_finishWithError(zwd, strm, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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))
|
||||||
{
|
{
|
||||||
|
if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB) {
|
||||||
|
strm->reserved = ZWRAP_ZLIB_STREAM; /* mark as zlib stream */
|
||||||
|
return inflateInit(strm);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
ZWRAP_DCtx* zwd = ZWRAP_createDCtx(strm);
|
ZWRAP_DCtx* zwd = ZWRAP_createDCtx(strm);
|
||||||
LOG_WRAPPER("- inflateInit\n");
|
LOG_WRAPPERD("- inflateInit\n");
|
||||||
if (zwd == NULL) { strm->state = NULL; return Z_MEM_ERROR; }
|
if (zwd == NULL) return ZWRAPD_finishWithError(zwd, strm, 0);
|
||||||
|
|
||||||
zwd->version = zwd->customMem.customAlloc(zwd->customMem.opaque, strlen(version) + 1);
|
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; }
|
if (zwd->version == NULL) return ZWRAPD_finishWithError(zwd, strm, 0);
|
||||||
strcpy(zwd->version, version);
|
strcpy(zwd->version, version);
|
||||||
|
|
||||||
zwd->stream_size = stream_size;
|
zwd->stream_size = stream_size;
|
||||||
strm->state = (struct internal_state*) zwd; /* use state which in not used by user */
|
strm->state = (struct internal_state*) zwd; /* use state which in not used by user */
|
||||||
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 = ZWRAP_UNKNOWN_STREAM; /* mark as unknown steam */
|
||||||
|
strm->adler = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
@@ -376,38 +508,102 @@ ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm,
|
|||||||
ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int windowBits,
|
ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int windowBits,
|
||||||
const char *version, int stream_size))
|
const char *version, int stream_size))
|
||||||
{
|
{
|
||||||
|
if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB) {
|
||||||
|
return inflateInit2_(strm, windowBits, version, stream_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
int ret = z_inflateInit_ (strm, version, stream_size);
|
int ret = z_inflateInit_ (strm, version, stream_size);
|
||||||
if (ret == Z_OK) {
|
if (ret == Z_OK) {
|
||||||
ZWRAP_DCtx* zwd = (ZWRAP_DCtx*)strm->state;
|
ZWRAP_DCtx* zwd = (ZWRAP_DCtx*)strm->state;
|
||||||
|
if (zwd == NULL) return Z_STREAM_ERROR;
|
||||||
zwd->windowBits = windowBits;
|
zwd->windowBits = windowBits;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ZWRAP_inflateReset_keepDict(z_streamp strm)
|
||||||
|
{
|
||||||
|
LOG_WRAPPERD("- ZWRAP_inflateReset_keepDict\n");
|
||||||
|
if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
|
||||||
|
return inflateReset(strm);
|
||||||
|
|
||||||
|
{ ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
|
||||||
|
if (zwd == NULL) return Z_STREAM_ERROR;
|
||||||
|
ZWRAP_initDCtx(zwd);
|
||||||
|
zwd->decompState = ZWRAP_useReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
strm->total_in = 0;
|
||||||
|
strm->total_out = 0;
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm))
|
||||||
|
{
|
||||||
|
LOG_WRAPPERD("- inflateReset\n");
|
||||||
|
if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
|
||||||
|
return inflateReset(strm);
|
||||||
|
|
||||||
|
{ int ret = ZWRAP_inflateReset_keepDict(strm);
|
||||||
|
if (ret != Z_OK) return ret; }
|
||||||
|
|
||||||
|
{ ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
|
||||||
|
if (zwd == NULL) return Z_STREAM_ERROR;
|
||||||
|
zwd->decompState = ZWRAP_useInit; }
|
||||||
|
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if ZLIB_VERNUM >= 0x1240
|
||||||
|
ZEXTERN int ZEXPORT z_inflateReset2 OF((z_streamp strm,
|
||||||
|
int windowBits))
|
||||||
|
{
|
||||||
|
if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
|
||||||
|
return inflateReset2(strm, windowBits);
|
||||||
|
|
||||||
|
{ int ret = z_inflateReset (strm);
|
||||||
|
if (ret == Z_OK) {
|
||||||
|
ZWRAP_DCtx* zwd = (ZWRAP_DCtx*)strm->state;
|
||||||
|
if (zwd == NULL) return Z_STREAM_ERROR;
|
||||||
|
zwd->windowBits = windowBits;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
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))
|
||||||
{
|
{
|
||||||
if (!strm->reserved)
|
LOG_WRAPPERD("- inflateSetDictionary\n");
|
||||||
|
if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
|
||||||
return inflateSetDictionary(strm, dictionary, dictLength);
|
return inflateSetDictionary(strm, dictionary, dictLength);
|
||||||
|
|
||||||
LOG_WRAPPER("- inflateSetDictionary\n");
|
|
||||||
{ size_t errorCode;
|
{ size_t errorCode;
|
||||||
ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
|
ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
|
||||||
if (strm->state == NULL) return Z_MEM_ERROR;
|
if (zwd == NULL || zwd->zbd == NULL) return Z_STREAM_ERROR;
|
||||||
errorCode = ZBUFF_decompressInitDictionary(zwd->zbd, dictionary, dictLength);
|
errorCode = ZSTD_initDStream_usingDict(zwd->zbd, dictionary, dictLength);
|
||||||
if (ZSTD_isError(errorCode)) { ZWRAP_freeDCtx(zwd); strm->state = NULL; return Z_MEM_ERROR; }
|
if (ZSTD_isError(errorCode)) return ZWRAPD_finishWithError(zwd, strm, 0);
|
||||||
|
zwd->decompState = ZWRAP_useReset;
|
||||||
if (strm->total_in == ZSTD_frameHeaderSize_min) {
|
|
||||||
size_t dstCapacity = 0;
|
if (strm->total_in == ZSTD_HEADERSIZE) {
|
||||||
size_t srcSize = strm->total_in;
|
zwd->inBuffer.src = zwd->headerBuf;
|
||||||
errorCode = ZBUFF_decompressContinue(zwd->zbd, strm->next_out, &dstCapacity, zwd->headerBuf, &srcSize);
|
zwd->inBuffer.size = strm->total_in;
|
||||||
LOG_WRAPPER("ZBUFF_decompressContinue3 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)srcSize, (int)dstCapacity);
|
zwd->inBuffer.pos = 0;
|
||||||
if (dstCapacity > 0 || ZSTD_isError(errorCode)) {
|
zwd->outBuffer.dst = strm->next_out;
|
||||||
LOG_WRAPPER("ERROR: ZBUFF_decompressContinue %s\n", ZSTD_getErrorName(errorCode));
|
zwd->outBuffer.size = 0;
|
||||||
ZWRAP_freeDCtx(zwd); strm->state = NULL;
|
zwd->outBuffer.pos = 0;
|
||||||
return Z_MEM_ERROR;
|
errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer);
|
||||||
|
LOG_WRAPPERD("inflateSetDictionary ZSTD_decompressStream errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size);
|
||||||
|
if (zwd->inBuffer.pos < zwd->outBuffer.size || ZSTD_isError(errorCode)) {
|
||||||
|
LOG_WRAPPERD("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode));
|
||||||
|
return ZWRAPD_finishWithError(zwd, strm, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -416,143 +612,214 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush))
|
ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush))
|
||||||
{
|
{
|
||||||
if (!strm->reserved)
|
ZWRAP_DCtx* zwd;
|
||||||
return inflate(strm, flush);
|
int res;
|
||||||
|
if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) {
|
||||||
|
LOG_WRAPPERD("- inflate1 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);
|
||||||
|
res = inflate(strm, flush);
|
||||||
|
LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
if (strm->avail_in > 0) {
|
if (strm->avail_in <= 0) return Z_OK;
|
||||||
size_t errorCode, dstCapacity, srcSize;
|
|
||||||
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);
|
|
||||||
if (strm->total_in < ZWRAP_HEADERSIZE)
|
|
||||||
{
|
|
||||||
srcSize = MIN(strm->avail_in, ZWRAP_HEADERSIZE - strm->total_in);
|
|
||||||
memcpy(zwd->headerBuf+strm->total_in, strm->next_in, srcSize);
|
|
||||||
strm->total_in += srcSize;
|
|
||||||
strm->next_in += srcSize;
|
|
||||||
strm->avail_in -= srcSize;
|
|
||||||
if (strm->total_in < ZWRAP_HEADERSIZE) return Z_OK;
|
|
||||||
|
|
||||||
if (MEM_readLE32(zwd->headerBuf) != ZSTD_MAGICNUMBER) {
|
{ size_t errorCode, srcSize;
|
||||||
z_stream strm2;
|
zwd = (ZWRAP_DCtx*) strm->state;
|
||||||
strm2.next_in = strm->next_in;
|
LOG_WRAPPERD("- inflate1 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);
|
||||||
strm2.avail_in = strm->avail_in;
|
|
||||||
strm2.next_out = strm->next_out;
|
|
||||||
strm2.avail_out = strm->avail_out;
|
|
||||||
|
|
||||||
if (zwd->windowBits)
|
if (zwd == NULL) return Z_STREAM_ERROR;
|
||||||
errorCode = inflateInit2_(strm, zwd->windowBits, zwd->version, zwd->stream_size);
|
if (zwd->decompState == ZWRAP_streamEnd) return Z_STREAM_END;
|
||||||
else
|
|
||||||
errorCode = inflateInit_(strm, zwd->version, zwd->stream_size);
|
|
||||||
LOG_WRAPPER("ZLIB inflateInit errorCode=%d\n", (int)errorCode);
|
|
||||||
if (errorCode != Z_OK) { ZWRAP_freeDCtx(zwd); strm->state = NULL; return errorCode; }
|
|
||||||
|
|
||||||
/* inflate header */
|
if (strm->total_in < ZLIB_HEADERSIZE) {
|
||||||
strm->next_in = (unsigned char*)zwd->headerBuf;
|
if (strm->total_in == 0 && strm->avail_in >= ZLIB_HEADERSIZE) {
|
||||||
strm->avail_in = ZWRAP_HEADERSIZE;
|
if (MEM_readLE32(strm->next_in) != ZSTD_MAGICNUMBER) {
|
||||||
strm->avail_out = 0;
|
if (zwd->windowBits)
|
||||||
errorCode = inflate(strm, Z_NO_FLUSH);
|
errorCode = inflateInit2_(strm, zwd->windowBits, zwd->version, zwd->stream_size);
|
||||||
LOG_WRAPPER("ZLIB inflate errorCode=%d strm->avail_in=%d\n", (int)errorCode, (int)strm->avail_in);
|
else
|
||||||
if (errorCode != Z_OK) { ZWRAP_freeDCtx(zwd); strm->state = NULL; return errorCode; }
|
errorCode = inflateInit_(strm, zwd->version, zwd->stream_size);
|
||||||
if (strm->avail_in > 0) goto error;
|
|
||||||
|
|
||||||
strm->next_in = strm2.next_in;
|
|
||||||
strm->avail_in = strm2.avail_in;
|
|
||||||
strm->next_out = strm2.next_out;
|
|
||||||
strm->avail_out = strm2.avail_out;
|
|
||||||
|
|
||||||
strm->reserved = 0; /* mark as zlib stream */
|
strm->reserved = ZWRAP_ZLIB_STREAM; /* mark as zlib stream */
|
||||||
errorCode = ZWRAP_freeDCtx(zwd);
|
errorCode = ZWRAP_freeDCtx(zwd);
|
||||||
if (ZSTD_isError(errorCode)) goto error;
|
if (ZSTD_isError(errorCode)) goto error;
|
||||||
|
|
||||||
if (flush == Z_INFLATE_SYNC) return inflateSync(strm);
|
if (flush == Z_INFLATE_SYNC) res = inflateSync(strm);
|
||||||
return inflate(strm, flush);
|
else res = inflate(strm, flush);
|
||||||
|
LOG_WRAPPERD("- inflate3 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
srcSize = MIN(strm->avail_in, ZLIB_HEADERSIZE - strm->total_in);
|
||||||
|
memcpy(zwd->headerBuf+strm->total_in, strm->next_in, srcSize);
|
||||||
|
strm->total_in += srcSize;
|
||||||
|
strm->next_in += srcSize;
|
||||||
|
strm->avail_in -= srcSize;
|
||||||
|
if (strm->total_in < ZLIB_HEADERSIZE) return Z_OK;
|
||||||
|
|
||||||
|
if (MEM_readLE32(zwd->headerBuf) != ZSTD_MAGICNUMBER) {
|
||||||
|
z_stream strm2;
|
||||||
|
strm2.next_in = strm->next_in;
|
||||||
|
strm2.avail_in = strm->avail_in;
|
||||||
|
strm2.next_out = strm->next_out;
|
||||||
|
strm2.avail_out = strm->avail_out;
|
||||||
|
|
||||||
|
if (zwd->windowBits)
|
||||||
|
errorCode = inflateInit2_(strm, zwd->windowBits, zwd->version, zwd->stream_size);
|
||||||
|
else
|
||||||
|
errorCode = inflateInit_(strm, zwd->version, zwd->stream_size);
|
||||||
|
LOG_WRAPPERD("ZLIB inflateInit errorCode=%d\n", (int)errorCode);
|
||||||
|
if (errorCode != Z_OK) return ZWRAPD_finishWithError(zwd, strm, (int)errorCode);
|
||||||
|
|
||||||
|
/* inflate header */
|
||||||
|
strm->next_in = (unsigned char*)zwd->headerBuf;
|
||||||
|
strm->avail_in = ZLIB_HEADERSIZE;
|
||||||
|
strm->avail_out = 0;
|
||||||
|
errorCode = inflate(strm, Z_NO_FLUSH);
|
||||||
|
LOG_WRAPPERD("ZLIB inflate errorCode=%d strm->avail_in=%d\n", (int)errorCode, (int)strm->avail_in);
|
||||||
|
if (errorCode != Z_OK) return ZWRAPD_finishWithError(zwd, strm, (int)errorCode);
|
||||||
|
if (strm->avail_in > 0) goto error;
|
||||||
|
|
||||||
|
strm->next_in = strm2.next_in;
|
||||||
|
strm->avail_in = strm2.avail_in;
|
||||||
|
strm->next_out = strm2.next_out;
|
||||||
|
strm->avail_out = strm2.avail_out;
|
||||||
|
|
||||||
|
strm->reserved = ZWRAP_ZLIB_STREAM; /* mark as zlib stream */
|
||||||
|
errorCode = ZWRAP_freeDCtx(zwd);
|
||||||
|
if (ZSTD_isError(errorCode)) goto error;
|
||||||
|
|
||||||
|
if (flush == Z_INFLATE_SYNC) res = inflateSync(strm);
|
||||||
|
else res = inflate(strm, flush);
|
||||||
|
LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
zwd->zbd = ZBUFF_createDCtx_advanced(zwd->customMem);
|
|
||||||
if (zwd->zbd == NULL) goto error;
|
|
||||||
|
|
||||||
errorCode = ZBUFF_decompressInit(zwd->zbd);
|
|
||||||
if (ZSTD_isError(errorCode)) goto error;
|
|
||||||
|
|
||||||
srcSize = ZWRAP_HEADERSIZE;
|
|
||||||
dstCapacity = 0;
|
|
||||||
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);
|
|
||||||
if (ZSTD_isError(errorCode)) {
|
|
||||||
LOG_WRAPPER("ERROR: ZBUFF_decompressContinue %s\n", ZSTD_getErrorName(errorCode));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (strm->avail_in == 0) return Z_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
srcSize = strm->avail_in;
|
strm->reserved = ZWRAP_ZSTD_STREAM; /* mark as zstd steam */
|
||||||
dstCapacity = strm->avail_out;
|
|
||||||
errorCode = ZBUFF_decompressContinue(zwd->zbd, strm->next_out, &dstCapacity, strm->next_in, &srcSize);
|
if (flush == Z_INFLATE_SYNC) { strm->msg = "inflateSync is not supported!"; goto error; }
|
||||||
LOG_WRAPPER("ZBUFF_decompressContinue2 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)srcSize, (int)dstCapacity);
|
|
||||||
|
if (!zwd->zbd) {
|
||||||
|
zwd->zbd = ZSTD_createDStream_advanced(zwd->customMem);
|
||||||
|
if (zwd->zbd == NULL) { LOG_WRAPPERD("ERROR: ZSTD_createDStream_advanced\n"); goto error; }
|
||||||
|
zwd->decompState = ZWRAP_useInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strm->total_in < ZSTD_HEADERSIZE)
|
||||||
|
{
|
||||||
|
if (strm->total_in == 0 && strm->avail_in >= ZSTD_HEADERSIZE) {
|
||||||
|
if (zwd->decompState == ZWRAP_useInit) {
|
||||||
|
errorCode = ZSTD_initDStream(zwd->zbd);
|
||||||
|
if (ZSTD_isError(errorCode)) { LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); goto error; }
|
||||||
|
} else {
|
||||||
|
errorCode = ZSTD_resetDStream(zwd->zbd);
|
||||||
|
if (ZSTD_isError(errorCode)) goto error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
srcSize = MIN(strm->avail_in, ZSTD_HEADERSIZE - strm->total_in);
|
||||||
|
memcpy(zwd->headerBuf+strm->total_in, strm->next_in, srcSize);
|
||||||
|
strm->total_in += srcSize;
|
||||||
|
strm->next_in += srcSize;
|
||||||
|
strm->avail_in -= srcSize;
|
||||||
|
if (strm->total_in < ZSTD_HEADERSIZE) return Z_OK;
|
||||||
|
|
||||||
|
if (zwd->decompState == ZWRAP_useInit) {
|
||||||
|
errorCode = ZSTD_initDStream(zwd->zbd);
|
||||||
|
if (ZSTD_isError(errorCode)) { LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); goto error; }
|
||||||
|
} else {
|
||||||
|
errorCode = ZSTD_resetDStream(zwd->zbd);
|
||||||
|
if (ZSTD_isError(errorCode)) goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
zwd->inBuffer.src = zwd->headerBuf;
|
||||||
|
zwd->inBuffer.size = ZSTD_HEADERSIZE;
|
||||||
|
zwd->inBuffer.pos = 0;
|
||||||
|
zwd->outBuffer.dst = strm->next_out;
|
||||||
|
zwd->outBuffer.size = 0;
|
||||||
|
zwd->outBuffer.pos = 0;
|
||||||
|
errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer);
|
||||||
|
LOG_WRAPPERD("inflate ZSTD_decompressStream1 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size);
|
||||||
|
if (ZSTD_isError(errorCode)) {
|
||||||
|
LOG_WRAPPERD("ERROR: ZSTD_decompressStream1 %s\n", ZSTD_getErrorName(errorCode));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (zwd->inBuffer.pos != zwd->inBuffer.size) goto error; /* not consumed */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zwd->inBuffer.src = strm->next_in;
|
||||||
|
zwd->inBuffer.size = strm->avail_in;
|
||||||
|
zwd->inBuffer.pos = 0;
|
||||||
|
zwd->outBuffer.dst = strm->next_out;
|
||||||
|
zwd->outBuffer.size = strm->avail_out;
|
||||||
|
zwd->outBuffer.pos = 0;
|
||||||
|
errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer);
|
||||||
|
LOG_WRAPPERD("inflate ZSTD_decompressStream2 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)strm->avail_in, (int)strm->avail_out);
|
||||||
if (ZSTD_isError(errorCode)) {
|
if (ZSTD_isError(errorCode)) {
|
||||||
LOG_WRAPPER("ERROR: ZBUFF_decompressContinue %s\n", ZSTD_getErrorName(errorCode));
|
|
||||||
zwd->errorCount++;
|
zwd->errorCount++;
|
||||||
|
LOG_WRAPPERD("ERROR: ZSTD_decompressStream2 %s zwd->errorCount=%d\n", ZSTD_getErrorName(errorCode), zwd->errorCount);
|
||||||
if (zwd->errorCount<=1) return Z_NEED_DICT; else goto error;
|
if (zwd->errorCount<=1) return Z_NEED_DICT; else goto error;
|
||||||
}
|
}
|
||||||
strm->next_out += dstCapacity;
|
LOG_WRAPPERD("inflate inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d outBuffer.size=%d o\n", (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos, (int)zwd->outBuffer.size);
|
||||||
strm->total_out += dstCapacity;
|
strm->next_out += zwd->outBuffer.pos;
|
||||||
strm->avail_out -= dstCapacity;
|
strm->total_out += zwd->outBuffer.pos;
|
||||||
strm->total_in += srcSize;
|
strm->avail_out -= zwd->outBuffer.pos;
|
||||||
strm->next_in += srcSize;
|
strm->total_in += zwd->inBuffer.pos;
|
||||||
strm->avail_in -= srcSize;
|
strm->next_in += zwd->inBuffer.pos;
|
||||||
if (errorCode == 0) return Z_STREAM_END;
|
strm->avail_in -= zwd->inBuffer.pos;
|
||||||
return Z_OK;
|
if (errorCode == 0) {
|
||||||
error:
|
LOG_WRAPPERD("inflate Z_STREAM_END1 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);
|
||||||
ZWRAP_freeDCtx(zwd);
|
zwd->decompState = ZWRAP_streamEnd;
|
||||||
strm->state = NULL;
|
return Z_STREAM_END;
|
||||||
return Z_MEM_ERROR;
|
}
|
||||||
}
|
}
|
||||||
|
LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, Z_OK);
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
|
|
||||||
|
error:
|
||||||
|
return ZWRAPD_finishWithError(zwd, strm, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_inflateEnd OF((z_streamp strm))
|
ZEXTERN int ZEXPORT z_inflateEnd OF((z_streamp strm))
|
||||||
{
|
{
|
||||||
int ret = Z_OK;
|
if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
|
||||||
if (!strm->reserved)
|
|
||||||
return inflateEnd(strm);
|
return inflateEnd(strm);
|
||||||
|
|
||||||
LOG_WRAPPER("- inflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out));
|
LOG_WRAPPERD("- inflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out));
|
||||||
{ ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
|
{ size_t errorCode;
|
||||||
size_t const errorCode = ZWRAP_freeDCtx(zwd);
|
ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
|
||||||
|
if (zwd == NULL) return Z_OK; /* structures are already freed */
|
||||||
strm->state = NULL;
|
strm->state = NULL;
|
||||||
if (ZSTD_isError(errorCode)) return Z_MEM_ERROR;
|
errorCode = ZWRAP_freeDCtx(zwd);
|
||||||
|
if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR;
|
||||||
}
|
}
|
||||||
return ret;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_inflateSync OF((z_streamp strm))
|
ZEXTERN int ZEXPORT z_inflateSync OF((z_streamp strm))
|
||||||
{
|
{
|
||||||
|
if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) {
|
||||||
|
return inflateSync(strm);
|
||||||
|
}
|
||||||
|
|
||||||
return z_inflate(strm, Z_INFLATE_SYNC);
|
return z_inflate(strm, Z_INFLATE_SYNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Advanced compression functions */
|
/* Advanced compression functions */
|
||||||
ZEXTERN int ZEXPORT z_deflateCopy OF((z_streamp dest,
|
ZEXTERN int ZEXPORT z_deflateCopy OF((z_streamp dest,
|
||||||
z_streamp source))
|
z_streamp source))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return deflateCopy(dest, source);
|
return deflateCopy(dest, source);
|
||||||
FINISH_WITH_ERR(source, "deflateCopy is not supported!");
|
return ZWRAPC_finishWithErrorMsg(source, "deflateCopy is not supported!");
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm))
|
|
||||||
{
|
|
||||||
if (!g_useZSTD)
|
|
||||||
return deflateReset(strm);
|
|
||||||
FINISH_WITH_ERR(strm, "deflateReset is not supported!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -562,9 +829,9 @@ ZEXTERN int ZEXPORT z_deflateTune OF((z_streamp strm,
|
|||||||
int nice_length,
|
int nice_length,
|
||||||
int max_chain))
|
int max_chain))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
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(strm, "deflateTune is not supported!");
|
return ZWRAPC_finishWithErrorMsg(strm, "deflateTune is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -573,9 +840,9 @@ ZEXTERN int ZEXPORT z_deflatePending OF((z_streamp strm,
|
|||||||
unsigned *pending,
|
unsigned *pending,
|
||||||
int *bits))
|
int *bits))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return deflatePending(strm, pending, bits);
|
return deflatePending(strm, pending, bits);
|
||||||
FINISH_WITH_ERR(strm, "deflatePending is not supported!");
|
return ZWRAPC_finishWithErrorMsg(strm, "deflatePending is not supported!");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -584,32 +851,32 @@ ZEXTERN int ZEXPORT z_deflatePrime OF((z_streamp strm,
|
|||||||
int bits,
|
int bits,
|
||||||
int value))
|
int value))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return deflatePrime(strm, bits, value);
|
return deflatePrime(strm, bits, value);
|
||||||
FINISH_WITH_ERR(strm, "deflatePrime is not supported!");
|
return ZWRAPC_finishWithErrorMsg(strm, "deflatePrime is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_deflateSetHeader OF((z_streamp strm,
|
ZEXTERN int ZEXPORT z_deflateSetHeader OF((z_streamp strm,
|
||||||
gz_headerp head))
|
gz_headerp head))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return deflateSetHeader(strm, head);
|
return deflateSetHeader(strm, head);
|
||||||
FINISH_WITH_ERR(strm, "deflateSetHeader is not supported!");
|
return ZWRAPC_finishWithErrorMsg(strm, "deflateSetHeader is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Advanced compression functions */
|
/* Advanced decompression functions */
|
||||||
#if ZLIB_VERNUM >= 0x1280
|
#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 (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
|
||||||
return inflateGetDictionary(strm, dictionary, dictLength);
|
return inflateGetDictionary(strm, dictionary, dictLength);
|
||||||
FINISH_WITH_ERR(strm, "inflateGetDictionary is not supported!");
|
return ZWRAPD_finishWithErrorMsg(strm, "inflateGetDictionary is not supported!");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -617,37 +884,18 @@ ZEXTERN int ZEXPORT z_inflateGetDictionary OF((z_streamp strm,
|
|||||||
ZEXTERN int ZEXPORT z_inflateCopy OF((z_streamp dest,
|
ZEXTERN int ZEXPORT z_inflateCopy OF((z_streamp dest,
|
||||||
z_streamp source))
|
z_streamp source))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !source->reserved)
|
||||||
return inflateCopy(dest, source);
|
return inflateCopy(dest, source);
|
||||||
FINISH_WITH_ERR(source, "inflateCopy is not supported!");
|
return ZWRAPD_finishWithErrorMsg(source, "inflateCopy is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm))
|
|
||||||
{
|
|
||||||
if (!strm->reserved)
|
|
||||||
return inflateReset(strm);
|
|
||||||
FINISH_WITH_ERR(strm, "inflateReset is not supported!");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if ZLIB_VERNUM >= 0x1240
|
|
||||||
ZEXTERN int ZEXPORT z_inflateReset2 OF((z_streamp strm,
|
|
||||||
int windowBits))
|
|
||||||
{
|
|
||||||
if (!strm->reserved)
|
|
||||||
return inflateReset2(strm, windowBits);
|
|
||||||
FINISH_WITH_ERR(strm, "inflateReset2 is not supported!");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if ZLIB_VERNUM >= 0x1240
|
#if ZLIB_VERNUM >= 0x1240
|
||||||
ZEXTERN long ZEXPORT z_inflateMark OF((z_streamp strm))
|
ZEXTERN long ZEXPORT z_inflateMark OF((z_streamp strm))
|
||||||
{
|
{
|
||||||
if (!strm->reserved)
|
if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
|
||||||
return inflateMark(strm);
|
return inflateMark(strm);
|
||||||
FINISH_WITH_ERR(strm, "inflateMark is not supported!");
|
return ZWRAPD_finishWithErrorMsg(strm, "inflateMark is not supported!");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -656,18 +904,18 @@ ZEXTERN int ZEXPORT z_inflatePrime OF((z_streamp strm,
|
|||||||
int bits,
|
int bits,
|
||||||
int value))
|
int value))
|
||||||
{
|
{
|
||||||
if (!strm->reserved)
|
if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
|
||||||
return inflatePrime(strm, bits, value);
|
return inflatePrime(strm, bits, value);
|
||||||
FINISH_WITH_ERR(strm, "inflatePrime is not supported!");
|
return ZWRAPD_finishWithErrorMsg(strm, "inflatePrime is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_inflateGetHeader OF((z_streamp strm,
|
ZEXTERN int ZEXPORT z_inflateGetHeader OF((z_streamp strm,
|
||||||
gz_headerp head))
|
gz_headerp head))
|
||||||
{
|
{
|
||||||
if (!strm->reserved)
|
if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
|
||||||
return inflateGetHeader(strm, head);
|
return inflateGetHeader(strm, head);
|
||||||
FINISH_WITH_ERR(strm, "inflateGetHeader is not supported!");
|
return ZWRAPD_finishWithErrorMsg(strm, "inflateGetHeader is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -676,9 +924,9 @@ ZEXTERN int ZEXPORT z_inflateBackInit_ OF((z_streamp strm, int windowBits,
|
|||||||
const char *version,
|
const char *version,
|
||||||
int stream_size))
|
int stream_size))
|
||||||
{
|
{
|
||||||
if (!strm->reserved)
|
if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
|
||||||
return inflateBackInit_(strm, windowBits, window, version, stream_size);
|
return inflateBackInit_(strm, windowBits, window, version, stream_size);
|
||||||
FINISH_WITH_ERR(strm, "inflateBackInit is not supported!");
|
return ZWRAPD_finishWithErrorMsg(strm, "inflateBackInit is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -686,17 +934,17 @@ ZEXTERN int ZEXPORT z_inflateBack OF((z_streamp strm,
|
|||||||
in_func in, void FAR *in_desc,
|
in_func in, void FAR *in_desc,
|
||||||
out_func out, void FAR *out_desc))
|
out_func out, void FAR *out_desc))
|
||||||
{
|
{
|
||||||
if (!strm->reserved)
|
if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
|
||||||
return inflateBack(strm, in, in_desc, out, out_desc);
|
return inflateBack(strm, in, in_desc, out, out_desc);
|
||||||
FINISH_WITH_ERR(strm, "inflateBack is not supported!");
|
return ZWRAPD_finishWithErrorMsg(strm, "inflateBack is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT z_inflateBackEnd OF((z_streamp strm))
|
ZEXTERN int ZEXPORT z_inflateBackEnd OF((z_streamp strm))
|
||||||
{
|
{
|
||||||
if (!strm->reserved)
|
if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
|
||||||
return inflateBackEnd(strm);
|
return inflateBackEnd(strm);
|
||||||
FINISH_WITH_ERR(strm, "inflateBackEnd is not supported!");
|
return ZWRAPD_finishWithErrorMsg(strm, "inflateBackEnd is not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -710,13 +958,13 @@ ZEXTERN uLong ZEXPORT z_zlibCompileFlags OF((void)) { return zlibCompileFlags();
|
|||||||
ZEXTERN int ZEXPORT z_compress OF((Bytef *dest, uLongf *destLen,
|
ZEXTERN int ZEXPORT z_compress OF((Bytef *dest, uLongf *destLen,
|
||||||
const Bytef *source, uLong sourceLen))
|
const Bytef *source, uLong sourceLen))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return compress(dest, destLen, source, sourceLen);
|
return compress(dest, destLen, source, sourceLen);
|
||||||
|
|
||||||
{ size_t dstCapacity = *destLen;
|
{ size_t dstCapacity = *destLen;
|
||||||
size_t const errorCode = ZSTD_compress(dest, dstCapacity, source, sourceLen, ZWRAP_DEFAULT_CLEVEL);
|
size_t const errorCode = ZSTD_compress(dest, dstCapacity, source, sourceLen, ZWRAP_DEFAULT_CLEVEL);
|
||||||
LOG_WRAPPER("z_compress sourceLen=%d dstCapacity=%d\n", (int)sourceLen, (int)dstCapacity);
|
LOG_WRAPPERD("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_STREAM_ERROR;
|
||||||
*destLen = errorCode;
|
*destLen = errorCode;
|
||||||
}
|
}
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
@@ -727,12 +975,12 @@ ZEXTERN int ZEXPORT z_compress2 OF((Bytef *dest, uLongf *destLen,
|
|||||||
const Bytef *source, uLong sourceLen,
|
const Bytef *source, uLong sourceLen,
|
||||||
int level))
|
int level))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
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_STREAM_ERROR;
|
||||||
*destLen = errorCode;
|
*destLen = errorCode;
|
||||||
}
|
}
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
@@ -741,7 +989,7 @@ ZEXTERN int ZEXPORT z_compress2 OF((Bytef *dest, uLongf *destLen,
|
|||||||
|
|
||||||
ZEXTERN uLong ZEXPORT z_compressBound OF((uLong sourceLen))
|
ZEXTERN uLong ZEXPORT z_compressBound OF((uLong sourceLen))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return compressBound(sourceLen);
|
return compressBound(sourceLen);
|
||||||
|
|
||||||
return ZSTD_compressBound(sourceLen);
|
return ZSTD_compressBound(sourceLen);
|
||||||
@@ -752,12 +1000,11 @@ ZEXTERN int ZEXPORT z_uncompress OF((Bytef *dest, uLongf *destLen,
|
|||||||
const Bytef *source, uLong sourceLen))
|
const Bytef *source, uLong sourceLen))
|
||||||
{
|
{
|
||||||
if (sourceLen < 4 || MEM_readLE32(source) != ZSTD_MAGICNUMBER)
|
if (sourceLen < 4 || MEM_readLE32(source) != ZSTD_MAGICNUMBER)
|
||||||
// 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_STREAM_ERROR;
|
||||||
*destLen = errorCode;
|
*destLen = errorCode;
|
||||||
}
|
}
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
@@ -768,7 +1015,7 @@ ZEXTERN int ZEXPORT z_uncompress OF((Bytef *dest, uLongf *destLen,
|
|||||||
/* gzip file access functions */
|
/* gzip file access functions */
|
||||||
ZEXTERN gzFile ZEXPORT z_gzopen OF((const char *path, const char *mode))
|
ZEXTERN gzFile ZEXPORT z_gzopen OF((const char *path, const char *mode))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzopen(path, mode);
|
return gzopen(path, mode);
|
||||||
FINISH_WITH_NULL_ERR("gzopen is not supported!");
|
FINISH_WITH_NULL_ERR("gzopen is not supported!");
|
||||||
}
|
}
|
||||||
@@ -776,7 +1023,7 @@ ZEXTERN gzFile ZEXPORT z_gzopen OF((const char *path, const char *mode))
|
|||||||
|
|
||||||
ZEXTERN gzFile ZEXPORT z_gzdopen OF((int fd, const char *mode))
|
ZEXTERN gzFile ZEXPORT z_gzdopen OF((int fd, const char *mode))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzdopen(fd, mode);
|
return gzdopen(fd, mode);
|
||||||
FINISH_WITH_NULL_ERR("gzdopen is not supported!");
|
FINISH_WITH_NULL_ERR("gzdopen is not supported!");
|
||||||
}
|
}
|
||||||
@@ -785,7 +1032,7 @@ ZEXTERN gzFile ZEXPORT z_gzdopen OF((int fd, const char *mode))
|
|||||||
#if ZLIB_VERNUM >= 0x1240
|
#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_ZWRAP_useZSTDcompression)
|
||||||
return gzbuffer(file, size);
|
return gzbuffer(file, size);
|
||||||
FINISH_WITH_GZ_ERR("gzbuffer is not supported!");
|
FINISH_WITH_GZ_ERR("gzbuffer is not supported!");
|
||||||
}
|
}
|
||||||
@@ -793,7 +1040,7 @@ ZEXTERN int ZEXPORT z_gzbuffer OF((gzFile file, unsigned size))
|
|||||||
|
|
||||||
ZEXTERN z_off_t ZEXPORT z_gzoffset OF((gzFile file))
|
ZEXTERN z_off_t ZEXPORT z_gzoffset OF((gzFile file))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzoffset(file);
|
return gzoffset(file);
|
||||||
FINISH_WITH_GZ_ERR("gzoffset is not supported!");
|
FINISH_WITH_GZ_ERR("gzoffset is not supported!");
|
||||||
}
|
}
|
||||||
@@ -801,7 +1048,7 @@ ZEXTERN z_off_t ZEXPORT z_gzoffset OF((gzFile file))
|
|||||||
|
|
||||||
ZEXTERN int ZEXPORT z_gzclose_r OF((gzFile file))
|
ZEXTERN int ZEXPORT z_gzclose_r OF((gzFile file))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzclose_r(file);
|
return gzclose_r(file);
|
||||||
FINISH_WITH_GZ_ERR("gzclose_r is not supported!");
|
FINISH_WITH_GZ_ERR("gzclose_r is not supported!");
|
||||||
}
|
}
|
||||||
@@ -809,7 +1056,7 @@ ZEXTERN int ZEXPORT z_gzclose_r OF((gzFile file))
|
|||||||
|
|
||||||
ZEXTERN int ZEXPORT z_gzclose_w OF((gzFile file))
|
ZEXTERN int ZEXPORT z_gzclose_w OF((gzFile file))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzclose_w(file);
|
return gzclose_w(file);
|
||||||
FINISH_WITH_GZ_ERR("gzclose_w is not supported!");
|
FINISH_WITH_GZ_ERR("gzclose_w is not supported!");
|
||||||
}
|
}
|
||||||
@@ -818,7 +1065,7 @@ ZEXTERN int ZEXPORT z_gzclose_w OF((gzFile file))
|
|||||||
|
|
||||||
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_ZWRAP_useZSTDcompression)
|
||||||
return gzsetparams(file, level, strategy);
|
return gzsetparams(file, level, strategy);
|
||||||
FINISH_WITH_GZ_ERR("gzsetparams is not supported!");
|
FINISH_WITH_GZ_ERR("gzsetparams is not supported!");
|
||||||
}
|
}
|
||||||
@@ -826,7 +1073,7 @@ ZEXTERN int ZEXPORT z_gzsetparams OF((gzFile file, int level, int strategy))
|
|||||||
|
|
||||||
ZEXTERN int ZEXPORT z_gzread OF((gzFile file, voidp buf, unsigned len))
|
ZEXTERN int ZEXPORT z_gzread OF((gzFile file, voidp buf, unsigned len))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzread(file, buf, len);
|
return gzread(file, buf, len);
|
||||||
FINISH_WITH_GZ_ERR("gzread is not supported!");
|
FINISH_WITH_GZ_ERR("gzread is not supported!");
|
||||||
}
|
}
|
||||||
@@ -835,7 +1082,7 @@ ZEXTERN int ZEXPORT z_gzread OF((gzFile file, voidp buf, unsigned len))
|
|||||||
ZEXTERN int ZEXPORT z_gzwrite OF((gzFile file,
|
ZEXTERN int ZEXPORT z_gzwrite OF((gzFile file,
|
||||||
voidpc buf, unsigned len))
|
voidpc buf, unsigned len))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzwrite(file, buf, len);
|
return gzwrite(file, buf, len);
|
||||||
FINISH_WITH_GZ_ERR("gzwrite is not supported!");
|
FINISH_WITH_GZ_ERR("gzwrite is not supported!");
|
||||||
}
|
}
|
||||||
@@ -847,7 +1094,7 @@ ZEXTERN int ZEXPORTVA z_gzprintf Z_ARG((gzFile file, const char *format, ...))
|
|||||||
ZEXTERN int ZEXPORTVA z_gzprintf OF((gzFile file, const char *format, ...))
|
ZEXTERN int ZEXPORTVA z_gzprintf OF((gzFile file, const char *format, ...))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (!g_useZSTD) {
|
if (!g_ZWRAP_useZSTDcompression) {
|
||||||
int ret;
|
int ret;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
va_list args;
|
va_list args;
|
||||||
@@ -856,7 +1103,6 @@ ZEXTERN int ZEXPORTVA z_gzprintf OF((gzFile file, const char *format, ...))
|
|||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
ret = gzprintf(file, buf);
|
ret = gzprintf(file, buf);
|
||||||
// printf("gzprintf ret=%d\n", ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
FINISH_WITH_GZ_ERR("gzprintf is not supported!");
|
FINISH_WITH_GZ_ERR("gzprintf is not supported!");
|
||||||
@@ -865,7 +1111,7 @@ ZEXTERN int ZEXPORTVA z_gzprintf OF((gzFile file, const char *format, ...))
|
|||||||
|
|
||||||
ZEXTERN int ZEXPORT z_gzputs OF((gzFile file, const char *s))
|
ZEXTERN int ZEXPORT z_gzputs OF((gzFile file, const char *s))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzputs(file, s);
|
return gzputs(file, s);
|
||||||
FINISH_WITH_GZ_ERR("gzputs is not supported!");
|
FINISH_WITH_GZ_ERR("gzputs is not supported!");
|
||||||
}
|
}
|
||||||
@@ -873,7 +1119,7 @@ ZEXTERN int ZEXPORT z_gzputs OF((gzFile file, const char *s))
|
|||||||
|
|
||||||
ZEXTERN char * ZEXPORT z_gzgets OF((gzFile file, char *buf, int len))
|
ZEXTERN char * ZEXPORT z_gzgets OF((gzFile file, char *buf, int len))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzgets(file, buf, len);
|
return gzgets(file, buf, len);
|
||||||
FINISH_WITH_NULL_ERR("gzgets is not supported!");
|
FINISH_WITH_NULL_ERR("gzgets is not supported!");
|
||||||
}
|
}
|
||||||
@@ -881,7 +1127,7 @@ ZEXTERN char * ZEXPORT z_gzgets OF((gzFile file, char *buf, int len))
|
|||||||
|
|
||||||
ZEXTERN int ZEXPORT z_gzputc OF((gzFile file, int c))
|
ZEXTERN int ZEXPORT z_gzputc OF((gzFile file, int c))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzputc(file, c);
|
return gzputc(file, c);
|
||||||
FINISH_WITH_GZ_ERR("gzputc is not supported!");
|
FINISH_WITH_GZ_ERR("gzputc is not supported!");
|
||||||
}
|
}
|
||||||
@@ -893,7 +1139,7 @@ ZEXTERN int ZEXPORT z_gzgetc_ OF((gzFile file))
|
|||||||
ZEXTERN int ZEXPORT z_gzgetc OF((gzFile file))
|
ZEXTERN int ZEXPORT z_gzgetc OF((gzFile file))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzgetc(file);
|
return gzgetc(file);
|
||||||
FINISH_WITH_GZ_ERR("gzgetc is not supported!");
|
FINISH_WITH_GZ_ERR("gzgetc is not supported!");
|
||||||
}
|
}
|
||||||
@@ -901,7 +1147,7 @@ ZEXTERN int ZEXPORT z_gzgetc OF((gzFile file))
|
|||||||
|
|
||||||
ZEXTERN int ZEXPORT z_gzungetc OF((int c, gzFile file))
|
ZEXTERN int ZEXPORT z_gzungetc OF((int c, gzFile file))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzungetc(c, file);
|
return gzungetc(c, file);
|
||||||
FINISH_WITH_GZ_ERR("gzungetc is not supported!");
|
FINISH_WITH_GZ_ERR("gzungetc is not supported!");
|
||||||
}
|
}
|
||||||
@@ -909,7 +1155,7 @@ ZEXTERN int ZEXPORT z_gzungetc OF((int c, gzFile file))
|
|||||||
|
|
||||||
ZEXTERN int ZEXPORT z_gzflush OF((gzFile file, int flush))
|
ZEXTERN int ZEXPORT z_gzflush OF((gzFile file, int flush))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzflush(file, flush);
|
return gzflush(file, flush);
|
||||||
FINISH_WITH_GZ_ERR("gzflush is not supported!");
|
FINISH_WITH_GZ_ERR("gzflush is not supported!");
|
||||||
}
|
}
|
||||||
@@ -917,7 +1163,7 @@ ZEXTERN int ZEXPORT z_gzflush OF((gzFile file, int flush))
|
|||||||
|
|
||||||
ZEXTERN z_off_t ZEXPORT z_gzseek OF((gzFile file, z_off_t offset, int whence))
|
ZEXTERN z_off_t ZEXPORT z_gzseek OF((gzFile file, z_off_t offset, int whence))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzseek(file, offset, whence);
|
return gzseek(file, offset, whence);
|
||||||
FINISH_WITH_GZ_ERR("gzseek is not supported!");
|
FINISH_WITH_GZ_ERR("gzseek is not supported!");
|
||||||
}
|
}
|
||||||
@@ -925,7 +1171,7 @@ ZEXTERN z_off_t ZEXPORT z_gzseek OF((gzFile file, z_off_t offset, int whence))
|
|||||||
|
|
||||||
ZEXTERN int ZEXPORT z_gzrewind OF((gzFile file))
|
ZEXTERN int ZEXPORT z_gzrewind OF((gzFile file))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzrewind(file);
|
return gzrewind(file);
|
||||||
FINISH_WITH_GZ_ERR("gzrewind is not supported!");
|
FINISH_WITH_GZ_ERR("gzrewind is not supported!");
|
||||||
}
|
}
|
||||||
@@ -933,7 +1179,7 @@ ZEXTERN int ZEXPORT z_gzrewind OF((gzFile file))
|
|||||||
|
|
||||||
ZEXTERN z_off_t ZEXPORT z_gztell OF((gzFile file))
|
ZEXTERN z_off_t ZEXPORT z_gztell OF((gzFile file))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gztell(file);
|
return gztell(file);
|
||||||
FINISH_WITH_GZ_ERR("gztell is not supported!");
|
FINISH_WITH_GZ_ERR("gztell is not supported!");
|
||||||
}
|
}
|
||||||
@@ -941,7 +1187,7 @@ ZEXTERN z_off_t ZEXPORT z_gztell OF((gzFile file))
|
|||||||
|
|
||||||
ZEXTERN int ZEXPORT z_gzeof OF((gzFile file))
|
ZEXTERN int ZEXPORT z_gzeof OF((gzFile file))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzeof(file);
|
return gzeof(file);
|
||||||
FINISH_WITH_GZ_ERR("gzeof is not supported!");
|
FINISH_WITH_GZ_ERR("gzeof is not supported!");
|
||||||
}
|
}
|
||||||
@@ -949,7 +1195,7 @@ ZEXTERN int ZEXPORT z_gzeof OF((gzFile file))
|
|||||||
|
|
||||||
ZEXTERN int ZEXPORT z_gzdirect OF((gzFile file))
|
ZEXTERN int ZEXPORT z_gzdirect OF((gzFile file))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzdirect(file);
|
return gzdirect(file);
|
||||||
FINISH_WITH_GZ_ERR("gzdirect is not supported!");
|
FINISH_WITH_GZ_ERR("gzdirect is not supported!");
|
||||||
}
|
}
|
||||||
@@ -957,7 +1203,7 @@ ZEXTERN int ZEXPORT z_gzdirect OF((gzFile file))
|
|||||||
|
|
||||||
ZEXTERN int ZEXPORT z_gzclose OF((gzFile file))
|
ZEXTERN int ZEXPORT z_gzclose OF((gzFile file))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzclose(file);
|
return gzclose(file);
|
||||||
FINISH_WITH_GZ_ERR("gzclose is not supported!");
|
FINISH_WITH_GZ_ERR("gzclose is not supported!");
|
||||||
}
|
}
|
||||||
@@ -965,7 +1211,7 @@ ZEXTERN int ZEXPORT z_gzclose OF((gzFile file))
|
|||||||
|
|
||||||
ZEXTERN const char * ZEXPORT z_gzerror OF((gzFile file, int *errnum))
|
ZEXTERN const char * ZEXPORT z_gzerror OF((gzFile file, int *errnum))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
return gzerror(file, errnum);
|
return gzerror(file, errnum);
|
||||||
FINISH_WITH_NULL_ERR("gzerror is not supported!");
|
FINISH_WITH_NULL_ERR("gzerror is not supported!");
|
||||||
}
|
}
|
||||||
@@ -973,7 +1219,7 @@ ZEXTERN const char * ZEXPORT z_gzerror OF((gzFile file, int *errnum))
|
|||||||
|
|
||||||
ZEXTERN void ZEXPORT z_gzclearerr OF((gzFile file))
|
ZEXTERN void ZEXPORT z_gzclearerr OF((gzFile file))
|
||||||
{
|
{
|
||||||
if (!g_useZSTD)
|
if (!g_ZWRAP_useZSTDcompression)
|
||||||
gzclearerr(file);
|
gzclearerr(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,33 +1,11 @@
|
|||||||
/*
|
/**
|
||||||
zstd_zlibwrapper.h - zstd wrapper for zlib
|
* Copyright (c) 2016-present, Przemyslaw Skibinski, Facebook, Inc.
|
||||||
Copyright (C) 2016, Przemyslaw Skibinski.
|
* All rights reserved.
|
||||||
|
*
|
||||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
Redistribution and use in source and binary forms, with or without
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
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 ZSTD_ZLIBWRAPPER_H
|
#ifndef ZSTD_ZLIBWRAPPER_H
|
||||||
#define ZSTD_ZLIBWRAPPER_H
|
#define ZSTD_ZLIBWRAPPER_H
|
||||||
@@ -42,17 +20,57 @@ extern "C" {
|
|||||||
|
|
||||||
#if !defined(z_const)
|
#if !defined(z_const)
|
||||||
#if ZLIB_VERNUM >= 0x1260
|
#if ZLIB_VERNUM >= 0x1260
|
||||||
#define z_const const
|
#define z_const const
|
||||||
#else
|
#else
|
||||||
#define z_const
|
#define z_const
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void useZSTD(int turn_on);
|
/* returns a string with version of zstd library */
|
||||||
int isUsingZSTD(void);
|
|
||||||
const char * zstdVersion(void);
|
const char * zstdVersion(void);
|
||||||
|
|
||||||
|
|
||||||
|
/*** COMPRESSION ***/
|
||||||
|
/* enables/disables zstd compression during runtime */
|
||||||
|
void ZWRAP_useZSTDcompression(int turn_on);
|
||||||
|
|
||||||
|
/* checks if zstd compression is turned on */
|
||||||
|
int ZWRAP_isUsingZSTDcompression(void);
|
||||||
|
|
||||||
|
/* Changes a pledged source size for a given compression stream.
|
||||||
|
It will change ZSTD compression parameters what may improve compression speed and/or ratio.
|
||||||
|
The function should be called just after deflateInit() or deflateReset() and before deflate() or deflateSetDictionary().
|
||||||
|
It's only helpful when data is compressed in blocks.
|
||||||
|
There will be no change in case of deflateInit() or deflateReset() immediately followed by deflate(strm, Z_FINISH)
|
||||||
|
as this case is automatically detected. */
|
||||||
|
int ZWRAP_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize);
|
||||||
|
|
||||||
|
/* Similar to deflateReset but preserves dictionary set using deflateSetDictionary.
|
||||||
|
It should improve compression speed because there will be less calls to deflateSetDictionary
|
||||||
|
When using zlib compression this method redirects to deflateReset. */
|
||||||
|
int ZWRAP_deflateReset_keepDict(z_streamp strm);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*** DECOMPRESSION ***/
|
||||||
|
typedef enum { ZWRAP_FORCE_ZLIB, ZWRAP_AUTO } ZWRAP_decompress_type;
|
||||||
|
|
||||||
|
/* enables/disables automatic recognition of zstd/zlib compressed data during runtime */
|
||||||
|
void ZWRAP_setDecompressionType(ZWRAP_decompress_type type);
|
||||||
|
|
||||||
|
/* checks zstd decompression type */
|
||||||
|
ZWRAP_decompress_type ZWRAP_getDecompressionType(void);
|
||||||
|
|
||||||
|
/* Checks if zstd decompression is used for a given stream.
|
||||||
|
If will return 1 only when inflate() was called and zstd header was detected. */
|
||||||
|
int ZWRAP_isUsingZSTDdecompression(z_streamp strm);
|
||||||
|
|
||||||
|
/* Similar to inflateReset but preserves dictionary set using inflateSetDictionary.
|
||||||
|
inflate() will return Z_NEED_DICT only for the first time what will improve decompression speed.
|
||||||
|
For zlib streams this method redirects to inflateReset. */
|
||||||
|
int ZWRAP_inflateReset_keepDict(z_streamp strm);
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
class Zstd < Formula
|
|
||||||
desc "Zstandard - Fast real-time compression algorithm"
|
|
||||||
homepage "http://www.zstd.net/"
|
|
||||||
url "https://github.com/Cyan4973/zstd/archive/v0.7.5.tar.gz"
|
|
||||||
sha256 "6800defac9a93ddb1d9673d62c78526800df71cf9f353456f8e488ba4de51061"
|
|
||||||
|
|
||||||
def install
|
|
||||||
system "make", "install", "PREFIX=#{prefix}"
|
|
||||||
end
|
|
||||||
|
|
||||||
test do
|
|
||||||
(testpath/"input.txt").write("Hello, world." * 10)
|
|
||||||
system "#{bin}/zstd", "input.txt", "-o", "compressed.zst"
|
|
||||||
system "#{bin}/zstd", "--test", "compressed.zst"
|
|
||||||
system "#{bin}/zstd", "-d", "compressed.zst", "-o", "decompressed.txt"
|
|
||||||
system "cmp", "input.txt", "decompressed.txt"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
+357
-144
@@ -16,7 +16,7 @@ Distribution of this document is unlimited.
|
|||||||
|
|
||||||
### Version
|
### Version
|
||||||
|
|
||||||
0.2.0 (22/07/16)
|
0.2.2 (14/09/16)
|
||||||
|
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
@@ -97,6 +97,42 @@ to decode all concatenated frames in their sequential order,
|
|||||||
delivering the final decompressed result as if it was a single content.
|
delivering the final decompressed result as if it was a single content.
|
||||||
|
|
||||||
|
|
||||||
|
Skippable Frames
|
||||||
|
----------------
|
||||||
|
|
||||||
|
| `Magic_Number` | `Frame_Size` | `User_Data` |
|
||||||
|
|:--------------:|:------------:|:-----------:|
|
||||||
|
| 4 bytes | 4 bytes | n bytes |
|
||||||
|
|
||||||
|
Skippable frames allow the insertion of user-defined data
|
||||||
|
into a flow of concatenated frames.
|
||||||
|
Its design is pretty straightforward,
|
||||||
|
with the sole objective to allow the decoder to quickly skip
|
||||||
|
over user-defined data and continue decoding.
|
||||||
|
|
||||||
|
Skippable frames defined in this specification are compatible with [LZ4] ones.
|
||||||
|
|
||||||
|
[LZ4]:http://www.lz4.org
|
||||||
|
|
||||||
|
__`Magic_Number`__
|
||||||
|
|
||||||
|
4 Bytes, little-endian format.
|
||||||
|
Value : 0x184D2A5X, which means any value from 0x184D2A50 to 0x184D2A5F.
|
||||||
|
All 16 values are valid to identify a skippable frame.
|
||||||
|
|
||||||
|
__`Frame_Size`__
|
||||||
|
|
||||||
|
This is the size, in bytes, of the following `User_Data`
|
||||||
|
(without including the magic number nor the size field itself).
|
||||||
|
This field is represented using 4 Bytes, little-endian format, unsigned 32-bits.
|
||||||
|
This means `User_Data` can’t be bigger than (2^32-1) bytes.
|
||||||
|
|
||||||
|
__`User_Data`__
|
||||||
|
|
||||||
|
The `User_Data` can be anything. Data will just be skipped by the decoder.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
General Structure of Zstandard Frame format
|
General Structure of Zstandard Frame format
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
The structure of a single Zstandard frame is following:
|
The structure of a single Zstandard frame is following:
|
||||||
@@ -108,7 +144,7 @@ The structure of a single Zstandard frame is following:
|
|||||||
__`Magic_Number`__
|
__`Magic_Number`__
|
||||||
|
|
||||||
4 Bytes, little-endian format.
|
4 Bytes, little-endian format.
|
||||||
Value : 0xFD2FB527
|
Value : 0xFD2FB528
|
||||||
|
|
||||||
__`Frame_Header`__
|
__`Frame_Header`__
|
||||||
|
|
||||||
@@ -163,9 +199,9 @@ The `Flag_Value` can be converted into `Field_Size`,
|
|||||||
which is the number of bytes used by `Frame_Content_Size`
|
which is the number of bytes used by `Frame_Content_Size`
|
||||||
according to the following table:
|
according to the following table:
|
||||||
|
|
||||||
|`Flag_Value`| 0 | 1 | 2 | 3 |
|
|`Flag_Value`| 0 | 1 | 2 | 3 |
|
||||||
| ---------- | --- | --- | --- | --- |
|
| ---------- | ------ | --- | --- | --- |
|
||||||
|`Field_Size`| 0-1 | 2 | 4 | 8 |
|
|`Field_Size`| 0 or 1 | 2 | 4 | 8 |
|
||||||
|
|
||||||
When `Flag_Value` is `0`, `Field_Size` depends on `Single_Segment_flag` :
|
When `Flag_Value` is `0`, `Field_Size` depends on `Single_Segment_flag` :
|
||||||
if `Single_Segment_flag` is set, `Field_Size` is 1.
|
if `Single_Segment_flag` is set, `Field_Size` is 1.
|
||||||
@@ -235,7 +271,7 @@ which can be any value from 1 to 2^64-1 bytes (16 EB).
|
|||||||
| ----------- | ---------- | ---------- |
|
| ----------- | ---------- | ---------- |
|
||||||
| Field name | `Exponent` | `Mantissa` |
|
| Field name | `Exponent` | `Mantissa` |
|
||||||
|
|
||||||
Maximum distance is given by the following formulae :
|
Maximum distance is given by the following formulas :
|
||||||
```
|
```
|
||||||
windowLog = 10 + Exponent;
|
windowLog = 10 + Exponent;
|
||||||
windowBase = 1 << windowLog;
|
windowBase = 1 << windowLog;
|
||||||
@@ -265,6 +301,7 @@ This is a variable size field, which contains
|
|||||||
the ID of the dictionary required to properly decode the frame.
|
the ID of the dictionary required to properly decode the frame.
|
||||||
Note that this field is optional. When it's not present,
|
Note that this field is optional. When it's not present,
|
||||||
it's up to the caller to make sure it uses the correct dictionary.
|
it's up to the caller to make sure it uses the correct dictionary.
|
||||||
|
Format is little-endian.
|
||||||
|
|
||||||
Field size depends on `Dictionary_ID_flag`.
|
Field size depends on `Dictionary_ID_flag`.
|
||||||
1 byte can represent an ID 0-255.
|
1 byte can represent an ID 0-255.
|
||||||
@@ -361,40 +398,6 @@ up to `Block_Maximum_Decompressed_Size`, which is the smallest of :
|
|||||||
- 128 KB
|
- 128 KB
|
||||||
|
|
||||||
|
|
||||||
Skippable Frames
|
|
||||||
----------------
|
|
||||||
|
|
||||||
| `Magic_Number` | `Frame_Size` | `User_Data` |
|
|
||||||
|:--------------:|:------------:|:-----------:|
|
|
||||||
| 4 bytes | 4 bytes | n bytes |
|
|
||||||
|
|
||||||
Skippable frames allow the insertion of user-defined data
|
|
||||||
into a flow of concatenated frames.
|
|
||||||
Its design is pretty straightforward,
|
|
||||||
with the sole objective to allow the decoder to quickly skip
|
|
||||||
over user-defined data and continue decoding.
|
|
||||||
|
|
||||||
Skippable frames defined in this specification are compatible with [LZ4] ones.
|
|
||||||
|
|
||||||
[LZ4]:http://www.lz4.org
|
|
||||||
|
|
||||||
__`Magic_Number`__
|
|
||||||
|
|
||||||
4 Bytes, little-endian format.
|
|
||||||
Value : 0x184D2A5X, which means any value from 0x184D2A50 to 0x184D2A5F.
|
|
||||||
All 16 values are valid to identify a skippable frame.
|
|
||||||
|
|
||||||
__`Frame_Size`__
|
|
||||||
|
|
||||||
This is the size, in bytes, of the following `User_Data`
|
|
||||||
(without including the magic number nor the size field itself).
|
|
||||||
This field is represented using 4 Bytes, little-endian format, unsigned 32-bits.
|
|
||||||
This means `User_Data` can’t be bigger than (2^32-1) bytes.
|
|
||||||
|
|
||||||
__`User_Data`__
|
|
||||||
|
|
||||||
The `User_Data` can be anything. Data will just be skipped by the decoder.
|
|
||||||
|
|
||||||
|
|
||||||
The format of `Compressed_Block`
|
The format of `Compressed_Block`
|
||||||
--------------------------------
|
--------------------------------
|
||||||
@@ -413,7 +416,7 @@ To decode a compressed block, the following elements are necessary :
|
|||||||
or all previous blocks when `Single_Segment_flag` is set.
|
or all previous blocks when `Single_Segment_flag` is set.
|
||||||
- List of "recent offsets" from previous compressed block.
|
- List of "recent offsets" from previous compressed block.
|
||||||
- Decoding tables of previous compressed block for each symbol type
|
- Decoding tables of previous compressed block for each symbol type
|
||||||
(literals, litLength, matchLength, offset).
|
(literals, literals lengths, match lengths, offsets).
|
||||||
|
|
||||||
|
|
||||||
### `Literals_Section`
|
### `Literals_Section`
|
||||||
@@ -443,13 +446,16 @@ using little-endian convention.
|
|||||||
|
|
||||||
In this representation, bits on the left are smallest bits.
|
In this representation, bits on the left are smallest bits.
|
||||||
|
|
||||||
__`Literals_Block_Type`__
|
__`Literals_Block_Type`__
|
||||||
|
|
||||||
This field uses 2 lowest bits of first byte, describing 4 different block types :
|
This field uses 2 lowest bits of first byte, describing 4 different block types :
|
||||||
|
|
||||||
| Value | 0 | 1 | 2 | 3 |
|
| `Literals_Block_Type` | Value |
|
||||||
| --------------------- | -------------------- | -------------------- | --------------------------- | ----------------------------- |
|
| ----------------------------- | ----- |
|
||||||
| `Literals_Block_Type` | `Raw_Literals_Block` | `RLE_Literals_Block` | `Compressed_Literals_Block` | `Repeat_Stats_Literals_Block` |
|
| `Raw_Literals_Block` | 0 |
|
||||||
|
| `RLE_Literals_Block` | 1 |
|
||||||
|
| `Compressed_Literals_Block` | 2 |
|
||||||
|
| `Repeat_Stats_Literals_Block` | 3 |
|
||||||
|
|
||||||
- `Raw_Literals_Block` - Literals are stored uncompressed.
|
- `Raw_Literals_Block` - Literals are stored uncompressed.
|
||||||
- `RLE_Literals_Block` - Literals consist of a single byte value repeated N times.
|
- `RLE_Literals_Block` - Literals consist of a single byte value repeated N times.
|
||||||
@@ -460,43 +466,43 @@ This field uses 2 lowest bits of first byte, describing 4 different block types
|
|||||||
using Huffman tree _from previous Huffman-compressed literals block_.
|
using Huffman tree _from previous Huffman-compressed literals block_.
|
||||||
Huffman tree description will be skipped.
|
Huffman tree description will be skipped.
|
||||||
|
|
||||||
__`Size_Format`__
|
__`Size_Format`__
|
||||||
|
|
||||||
`Size_Format` is divided into 2 families :
|
`Size_Format` is divided into 2 families :
|
||||||
|
|
||||||
- For `Compressed_Block`, it requires to decode both `Compressed_Size`
|
- For `Compressed_Block`, it requires to decode both `Compressed_Size`
|
||||||
and `Regenerated_Size` (the decompressed size). It will also decode the number of streams.
|
and `Regenerated_Size` (the decompressed size). It will also decode the number of streams.
|
||||||
- For `Raw_Block` and `RLE_Block` it's enough to decode `Regenerated_Size`.
|
- For `Raw_Literals_Block` and `RLE_Literals_Block` it's enough to decode `Regenerated_Size`.
|
||||||
|
|
||||||
For values spanning several bytes, convention is little-endian.
|
For values spanning several bytes, convention is little-endian.
|
||||||
|
|
||||||
__`Size_Format` for `Raw_Literals_Block` and `RLE_Literals_Block`__ :
|
__`Size_Format` for `Raw_Literals_Block` and `RLE_Literals_Block`__ :
|
||||||
|
|
||||||
- Value : x0 : `Regenerated_Size` uses 5 bits (0-31).
|
- Value x0 : `Regenerated_Size` uses 5 bits (0-31).
|
||||||
`Literals_Section_Header` has 1 byte.
|
`Literals_Section_Header` has 1 byte.
|
||||||
`Regenerated_Size = Header[0]>>3`
|
`Regenerated_Size = Header[0]>>3`
|
||||||
- Value : 01 : `Regenerated_Size` uses 12 bits (0-4095).
|
- Value 01 : `Regenerated_Size` uses 12 bits (0-4095).
|
||||||
`Literals_Section_Header` has 2 bytes.
|
`Literals_Section_Header` has 2 bytes.
|
||||||
`Regenerated_Size = (Header[0]>>4) + (Header[1]<<4)`
|
`Regenerated_Size = (Header[0]>>4) + (Header[1]<<4)`
|
||||||
- Value : 11 : `Regenerated_Size` uses 20 bits (0-1048575).
|
- Value 11 : `Regenerated_Size` uses 20 bits (0-1048575).
|
||||||
`Literals_Section_Header` has 3 bytes.
|
`Literals_Section_Header` has 3 bytes.
|
||||||
`Regenerated_Size = (Header[0]>>4) + (Header[1]<<4) + (Header[2]<<12)`
|
`Regenerated_Size = (Header[0]>>4) + (Header[1]<<4) + (Header[2]<<12)`
|
||||||
|
|
||||||
Note : it's allowed to represent a short value (ex : `13`)
|
Note : it's allowed to represent a short value (for example `13`)
|
||||||
using a long format, accepting the reduced compacity.
|
using a long format, accepting the increased compressed data size.
|
||||||
|
|
||||||
__`Size_Format` for `Compressed_Literals_Block` and `Repeat_Stats_Literals_Block`__ :
|
__`Size_Format` for `Compressed_Literals_Block` and `Repeat_Stats_Literals_Block`__ :
|
||||||
|
|
||||||
- Value : 00 : _Single stream_.
|
- Value 00 : _A single stream_.
|
||||||
Both `Compressed_Size` and `Regenerated_Size` use 10 bits (0-1023).
|
Both `Compressed_Size` and `Regenerated_Size` use 10 bits (0-1023).
|
||||||
`Literals_Section_Header` has 3 bytes.
|
`Literals_Section_Header` has 3 bytes.
|
||||||
- Value : 01 : 4 streams.
|
- Value 01 : 4 streams.
|
||||||
Both `Compressed_Size` and `Regenerated_Size` use 10 bits (0-1023).
|
Both `Compressed_Size` and `Regenerated_Size` use 10 bits (0-1023).
|
||||||
`Literals_Section_Header` has 3 bytes.
|
`Literals_Section_Header` has 3 bytes.
|
||||||
- Value : 10 : 4 streams.
|
- Value 10 : 4 streams.
|
||||||
Both `Compressed_Size` and `Regenerated_Size` use 14 bits (0-16383).
|
Both `Compressed_Size` and `Regenerated_Size` use 14 bits (0-16383).
|
||||||
`Literals_Section_Header` has 4 bytes.
|
`Literals_Section_Header` has 4 bytes.
|
||||||
- Value : 11 : 4 streams.
|
- Value 11 : 4 streams.
|
||||||
Both `Compressed_Size` and `Regenerated_Size` use 18 bits (0-262143).
|
Both `Compressed_Size` and `Regenerated_Size` use 18 bits (0-262143).
|
||||||
`Literals_Section_Header` has 5 bytes.
|
`Literals_Section_Header` has 5 bytes.
|
||||||
|
|
||||||
@@ -505,7 +511,7 @@ Both `Compressed_Size` and `Regenerated_Size` fields follow little-endian conven
|
|||||||
|
|
||||||
#### `Huffman_Tree_Description`
|
#### `Huffman_Tree_Description`
|
||||||
|
|
||||||
This section is only present when `Literals_Block_Type` type is `Compressed_Block` (`2`).
|
This section is only present when `Literals_Block_Type` type is `Compressed_Literals_Block` (`2`).
|
||||||
|
|
||||||
Prefix coding represents symbols from an a priori known alphabet
|
Prefix coding represents symbols from an a priori known alphabet
|
||||||
by bit sequences (codewords), one codeword for each symbol,
|
by bit sequences (codewords), one codeword for each symbol,
|
||||||
@@ -527,9 +533,11 @@ This specification limits maximum code length to 11 bits.
|
|||||||
##### Representation
|
##### Representation
|
||||||
|
|
||||||
All literal values from zero (included) to last present one (excluded)
|
All literal values from zero (included) to last present one (excluded)
|
||||||
are represented by `Weight` values, from 0 to `Max_Number_of_Bits`.
|
are represented by `Weight` with values from `0` to `Max_Number_of_Bits`.
|
||||||
Transformation from `Weight` to `Number_of_Bits` follows this formulae :
|
Transformation from `Weight` to `Number_of_Bits` follows this formula :
|
||||||
`Number_of_Bits = Weight ? Max_Number_of_Bits + 1 - Weight : 0` .
|
```
|
||||||
|
Number_of_Bits = Weight ? (Max_Number_of_Bits + 1 - Weight) : 0
|
||||||
|
```
|
||||||
The last symbol's `Weight` is deduced from previously decoded ones,
|
The last symbol's `Weight` is deduced from previously decoded ones,
|
||||||
by completing to the nearest power of 2.
|
by completing to the nearest power of 2.
|
||||||
This power of 2 gives `Max_Number_of_Bits`, the depth of the current tree.
|
This power of 2 gives `Max_Number_of_Bits`, the depth of the current tree.
|
||||||
@@ -544,7 +552,10 @@ Let's presume the following Huffman tree must be described :
|
|||||||
The tree depth is 4, since its smallest element uses 4 bits.
|
The tree depth is 4, since its smallest element uses 4 bits.
|
||||||
Value `5` will not be listed, nor will values above `5`.
|
Value `5` will not be listed, nor will values above `5`.
|
||||||
Values from `0` to `4` will be listed using `Weight` instead of `Number_of_Bits`.
|
Values from `0` to `4` will be listed using `Weight` instead of `Number_of_Bits`.
|
||||||
Weight formula is : `Weight = Number_of_Bits ? Max_Number_of_Bits + 1 - Number_of_Bits : 0`.
|
Weight formula is :
|
||||||
|
```
|
||||||
|
Weight = Number_of_Bits ? (Max_Number_of_Bits + 1 - Number_of_Bits) : 0
|
||||||
|
```
|
||||||
It gives the following serie of weights :
|
It gives the following serie of weights :
|
||||||
|
|
||||||
| `Weight` | 4 | 3 | 2 | 0 | 1 |
|
| `Weight` | 4 | 3 | 2 | 0 | 1 |
|
||||||
@@ -575,9 +586,9 @@ which tells how to decode the list of weights.
|
|||||||
|
|
||||||
- if `headerByte` < 128 :
|
- if `headerByte` < 128 :
|
||||||
the serie of weights is compressed by FSE.
|
the serie of weights is compressed by FSE.
|
||||||
The length of the FSE-compressed serie is `headerByte` (0-127).
|
The length of the FSE-compressed serie is equal to `headerByte` (0-127).
|
||||||
|
|
||||||
##### FSE (Finite State Entropy) compression of Huffman weights
|
##### Finite State Entropy (FSE) compression of Huffman weights
|
||||||
|
|
||||||
The serie of weights is compressed using FSE compression.
|
The serie of weights is compressed using FSE compression.
|
||||||
It's a single bitstream with 2 interleaved states,
|
It's a single bitstream with 2 interleaved states,
|
||||||
@@ -607,9 +618,10 @@ When both states have overflowed the bitstream, end is reached.
|
|||||||
##### Conversion from weights to Huffman prefix codes
|
##### Conversion from weights to Huffman prefix codes
|
||||||
|
|
||||||
All present symbols shall now have a `Weight` value.
|
All present symbols shall now have a `Weight` value.
|
||||||
It is possible to transform weights into Number_of_Bits, using this formula :
|
It is possible to transform weights into Number_of_Bits, using this formula:
|
||||||
`Number_of_Bits = Number_of_Bits ? Max_Number_of_Bits + 1 - Weight : 0` .
|
```
|
||||||
|
Number_of_Bits = Number_of_Bits ? Max_Number_of_Bits + 1 - Weight : 0
|
||||||
|
```
|
||||||
Symbols are sorted by `Weight`. Within same `Weight`, symbols keep natural order.
|
Symbols are sorted by `Weight`. Within same `Weight`, symbols keep natural order.
|
||||||
Symbols with a `Weight` of zero are removed.
|
Symbols with a `Weight` of zero are removed.
|
||||||
Then, starting from lowest weight, prefix codes are distributed in order.
|
Then, starting from lowest weight, prefix codes are distributed in order.
|
||||||
@@ -631,21 +643,21 @@ it gives the following distribution :
|
|||||||
| prefix codes | N/A | 0000| 0001| 001 | 01 | 1 |
|
| prefix codes | N/A | 0000| 0001| 001 | 01 | 1 |
|
||||||
|
|
||||||
|
|
||||||
#### Literals bitstreams
|
#### The content of Huffman-compressed literal stream
|
||||||
|
|
||||||
##### Bitstreams sizes
|
##### Bitstreams sizes
|
||||||
|
|
||||||
As seen in a previous paragraph,
|
As seen in a previous paragraph,
|
||||||
there are 2 flavors of Huffman-compressed literals :
|
there are 2 types of Huffman-compressed literals :
|
||||||
single stream, and 4-streams.
|
a single stream and 4 streams.
|
||||||
|
|
||||||
4-streams is useful for CPU with multiple execution units and out-of-order operations.
|
Encoding using 4 streams is useful for CPU with multiple execution units and out-of-order operations.
|
||||||
Since each stream can be decoded independently,
|
Since each stream can be decoded independently,
|
||||||
it's possible to decode them up to 4x faster than a single stream,
|
it's possible to decode them up to 4x faster than a single stream,
|
||||||
presuming the CPU has enough parallelism available.
|
presuming the CPU has enough parallelism available.
|
||||||
|
|
||||||
For single stream, header provides both the compressed and regenerated size.
|
For single stream, header provides both the compressed and regenerated size.
|
||||||
For 4-streams though,
|
For 4 streams though,
|
||||||
header only provides compressed and regenerated size of all 4 streams combined.
|
header only provides compressed and regenerated size of all 4 streams combined.
|
||||||
In order to properly decode the 4 streams,
|
In order to properly decode the 4 streams,
|
||||||
it's necessary to know the compressed and regenerated size of each stream.
|
it's necessary to know the compressed and regenerated size of each stream.
|
||||||
@@ -658,8 +670,10 @@ bitstreams are preceded by 3 unsigned little-endian 16-bits values.
|
|||||||
Each value represents the compressed size of one stream, in order.
|
Each value represents the compressed size of one stream, in order.
|
||||||
The last stream size is deducted from total compressed size
|
The last stream size is deducted from total compressed size
|
||||||
and from previously decoded stream sizes :
|
and from previously decoded stream sizes :
|
||||||
|
|
||||||
`stream4CSize = totalCSize - 6 - stream1CSize - stream2CSize - stream3CSize`.
|
`stream4CSize = totalCSize - 6 - stream1CSize - stream2CSize - stream3CSize`.
|
||||||
|
|
||||||
|
|
||||||
##### Bitstreams read and decode
|
##### Bitstreams read and decode
|
||||||
|
|
||||||
Each bitstream must be read _backward_,
|
Each bitstream must be read _backward_,
|
||||||
@@ -697,28 +711,28 @@ A match copy command specifies an offset and a length.
|
|||||||
The offset gives the position to copy from,
|
The offset gives the position to copy from,
|
||||||
which can be within a previous block.
|
which can be within a previous block.
|
||||||
|
|
||||||
There are 3 symbol types, literals lengths, offsets and match lengths,
|
When all _sequences_ are decoded,
|
||||||
which are encoded together, interleaved in a single _bitstream_.
|
if there is any literal left in the _literal section_,
|
||||||
|
these bytes are added at the end of the block.
|
||||||
|
|
||||||
Each symbol is a _code_ in its own context,
|
The `Sequences_Section` regroup all symbols required to decode commands.
|
||||||
which specifies a baseline and a number of bits to add.
|
There are 3 symbol types : literals lengths, offsets and match lengths.
|
||||||
_Codes_ are FSE compressed,
|
They are encoded together, interleaved, in a single _bitstream_.
|
||||||
and interleaved with raw additional bits in the same bitstream.
|
|
||||||
|
|
||||||
The Sequences section starts by a header,
|
The `Sequences_Section` starts by a header,
|
||||||
followed by optional Probability tables for each symbol type,
|
followed by optional probability tables for each symbol type,
|
||||||
followed by the bitstream.
|
followed by the bitstream.
|
||||||
|
|
||||||
| `Sequences_Section_Header` | [`Literals_Length_Table`] | [`Offset_Table`] | [`Match_Length_Table`] | bitStream |
|
| `Sequences_Section_Header` | [`Literals_Length_Table`] | [`Offset_Table`] | [`Match_Length_Table`] | bitStream |
|
||||||
| -------------------------- | ------------------------- | ---------------- | ---------------------- | --------- |
|
| -------------------------- | ------------------------- | ---------------- | ---------------------- | --------- |
|
||||||
|
|
||||||
To decode the Sequence section, it's required to know its size.
|
To decode the `Sequences_Section`, it's required to know its size.
|
||||||
This size is deducted from `blockSize - literalSectionSize`.
|
This size is deducted from `blockSize - literalSectionSize`.
|
||||||
|
|
||||||
|
|
||||||
#### `Sequences_Section_Header`
|
#### `Sequences_Section_Header`
|
||||||
|
|
||||||
Consists in 2 items :
|
Consists of 2 items:
|
||||||
- `Number_of_Sequences`
|
- `Number_of_Sequences`
|
||||||
- Symbol compression modes
|
- Symbol compression modes
|
||||||
|
|
||||||
@@ -743,8 +757,8 @@ This is a single byte, defining the compression mode of each symbol type.
|
|||||||
|
|
||||||
The last field, `Reserved`, must be all-zeroes.
|
The last field, `Reserved`, must be all-zeroes.
|
||||||
|
|
||||||
`Literals_Lengths_Mode`, `Offsets_Mode` and `Match_Lengths_Mode` define the compression mode of
|
`Literals_Lengths_Mode`, `Offsets_Mode` and `Match_Lengths_Mode` define the `Compression_Mode` of
|
||||||
literals lengths, offsets and match lengths respectively.
|
literals lengths, offsets, and match lengths respectively.
|
||||||
|
|
||||||
They follow the same enumeration :
|
They follow the same enumeration :
|
||||||
|
|
||||||
@@ -759,9 +773,14 @@ They follow the same enumeration :
|
|||||||
A distribution table will be present.
|
A distribution table will be present.
|
||||||
It will be described in [next part](#distribution-tables).
|
It will be described in [next part](#distribution-tables).
|
||||||
|
|
||||||
#### Symbols decoding
|
#### The codes for literals lengths, match lengths, and offsets.
|
||||||
|
|
||||||
##### Literals Length codes
|
Each symbol is a _code_ in its own context,
|
||||||
|
which specifies `Baseline` and `Number_of_Bits` to add.
|
||||||
|
_Codes_ are FSE compressed,
|
||||||
|
and interleaved with raw additional bits in the same bitstream.
|
||||||
|
|
||||||
|
##### Literals length codes
|
||||||
|
|
||||||
Literals length codes are values ranging from `0` to `35` included.
|
Literals length codes are values ranging from `0` to `35` included.
|
||||||
They define lengths from 0 to 131071 bytes.
|
They define lengths from 0 to 131071 bytes.
|
||||||
@@ -773,20 +792,20 @@ They define lengths from 0 to 131071 bytes.
|
|||||||
|
|
||||||
| `Literals_Length_Code` | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
|
| `Literals_Length_Code` | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
|
||||||
| ---------------------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
|
| ---------------------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
|
||||||
| Baseline | 16 | 18 | 20 | 22 | 24 | 28 | 32 | 40 |
|
| `Baseline` | 16 | 18 | 20 | 22 | 24 | 28 | 32 | 40 |
|
||||||
| `Number_of_Bits` | 1 | 1 | 1 | 1 | 2 | 2 | 3 | 3 |
|
| `Number_of_Bits` | 1 | 1 | 1 | 1 | 2 | 2 | 3 | 3 |
|
||||||
|
|
||||||
| `Literals_Length_Code` | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
|
| `Literals_Length_Code` | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
|
||||||
| ---------------------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
|
| ---------------------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
|
||||||
| Baseline | 48 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 |
|
| `Baseline` | 48 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 |
|
||||||
| `Number_of_Bits` | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|
| `Number_of_Bits` | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|
||||||
|
|
||||||
| `Literals_Length_Code` | 32 | 33 | 34 | 35 |
|
| `Literals_Length_Code` | 32 | 33 | 34 | 35 |
|
||||||
| ---------------------- | ---- | ---- | ---- | ---- |
|
| ---------------------- | ---- | ---- | ---- | ---- |
|
||||||
| Baseline | 8192 |16384 |32768 |65536 |
|
| `Baseline` | 8192 |16384 |32768 |65536 |
|
||||||
| `Number_of_Bits` | 13 | 14 | 15 | 16 |
|
| `Number_of_Bits` | 13 | 14 | 15 | 16 |
|
||||||
|
|
||||||
__Default distribution__
|
##### Default distribution for literals length codes
|
||||||
|
|
||||||
When `Compression_Mode` is `Predefined_Mode`,
|
When `Compression_Mode` is `Predefined_Mode`,
|
||||||
a predefined distribution is used for FSE compression.
|
a predefined distribution is used for FSE compression.
|
||||||
@@ -799,7 +818,7 @@ short literalsLength_defaultDistribution[36] =
|
|||||||
-1,-1,-1,-1 };
|
-1,-1,-1,-1 };
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Match Length codes
|
##### Match length codes
|
||||||
|
|
||||||
Match length codes are values ranging from `0` to `52` included.
|
Match length codes are values ranging from `0` to `52` included.
|
||||||
They define lengths from 3 to 131074 bytes.
|
They define lengths from 3 to 131074 bytes.
|
||||||
@@ -811,25 +830,25 @@ They define lengths from 3 to 131074 bytes.
|
|||||||
|
|
||||||
| `Match_Length_Code` | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
|
| `Match_Length_Code` | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
|
||||||
| ------------------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
|
| ------------------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
|
||||||
| Baseline | 35 | 37 | 39 | 41 | 43 | 47 | 51 | 59 |
|
| `Baseline` | 35 | 37 | 39 | 41 | 43 | 47 | 51 | 59 |
|
||||||
| `Number_of_Bits` | 1 | 1 | 1 | 1 | 2 | 2 | 3 | 3 |
|
| `Number_of_Bits` | 1 | 1 | 1 | 1 | 2 | 2 | 3 | 3 |
|
||||||
|
|
||||||
| `Match_Length_Code` | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
|
| `Match_Length_Code` | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
|
||||||
| ------------------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
|
| ------------------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
|
||||||
| Baseline | 67 | 83 | 99 | 131 | 258 | 514 | 1026 | 2050 |
|
| `Baseline` | 67 | 83 | 99 | 131 | 258 | 514 | 1026 | 2050 |
|
||||||
| `Number_of_Bits` | 4 | 4 | 5 | 7 | 8 | 9 | 10 | 11 |
|
| `Number_of_Bits` | 4 | 4 | 5 | 7 | 8 | 9 | 10 | 11 |
|
||||||
|
|
||||||
| `Match_Length_Code` | 48 | 49 | 50 | 51 | 52 |
|
| `Match_Length_Code` | 48 | 49 | 50 | 51 | 52 |
|
||||||
| ------------------- | ---- | ---- | ---- | ---- | ---- |
|
| ------------------- | ---- | ---- | ---- | ---- | ---- |
|
||||||
| Baseline | 4098 | 8194 |16486 |32770 |65538 |
|
| `Baseline` | 4098 | 8194 |16486 |32770 |65538 |
|
||||||
| `Number_of_Bits` | 12 | 13 | 14 | 15 | 16 |
|
| `Number_of_Bits` | 12 | 13 | 14 | 15 | 16 |
|
||||||
|
|
||||||
__Default distribution__
|
##### Default distribution for match length codes
|
||||||
|
|
||||||
When `Compression_Mode` is defined as `Predefined_Mode`,
|
When `Compression_Mode` is defined as `Predefined_Mode`,
|
||||||
a predefined distribution is used for FSE compression.
|
a predefined distribution is used for FSE compression.
|
||||||
|
|
||||||
Here is its definition. It uses an accuracy of 6 bits (64 states).
|
Below is its definition. It uses an accuracy of 6 bits (64 states).
|
||||||
```
|
```
|
||||||
short matchLengths_defaultDistribution[53] =
|
short matchLengths_defaultDistribution[53] =
|
||||||
{ 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
|
{ 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
|
||||||
@@ -848,33 +867,34 @@ For information, at the time of this writing.
|
|||||||
the reference decoder supports a maximum `N` value of `28` in 64-bits mode.
|
the reference decoder supports a maximum `N` value of `28` in 64-bits mode.
|
||||||
|
|
||||||
An offset code is also the number of additional bits to read,
|
An offset code is also the number of additional bits to read,
|
||||||
and can be translated into an `Offset_Value` using the following formulae :
|
and can be translated into an `Offset_Value` using the following formulas :
|
||||||
|
|
||||||
```
|
```
|
||||||
Offset_Value = (1 << offsetCode) + readNBits(offsetCode);
|
Offset_Value = (1 << offsetCode) + readNBits(offsetCode);
|
||||||
if (Offset_Value > 3) offset = Offset_Value - 3;
|
if (Offset_Value > 3) offset = Offset_Value - 3;
|
||||||
```
|
```
|
||||||
It means that maximum `Offset_Value` is `2^(N+1))-1` and it supports back-reference distance up to 2^(N+1))-4
|
It means that maximum `Offset_Value` is `(2^(N+1))-1` and it supports back-reference distance up to `(2^(N+1))-4`
|
||||||
but is limited by [maximum back-reference distance](#window_descriptor).
|
but is limited by [maximum back-reference distance](#window_descriptor).
|
||||||
|
|
||||||
Offset_Value from 1 to 3 are special : they define "repeat codes",
|
`Offset_Value` from 1 to 3 are special : they define "repeat codes",
|
||||||
which means one of the previous offsets will be repeated.
|
which means one of the previous offsets will be repeated.
|
||||||
They are sorted in recency order, with 1 meaning the most recent one.
|
They are sorted in recency order, with 1 meaning the most recent one.
|
||||||
See [Repeat offsets](#repeat-offsets) paragraph.
|
See [Repeat offsets](#repeat-offsets) paragraph.
|
||||||
|
|
||||||
__Default distribution__
|
|
||||||
|
##### Default distribution for offset codes
|
||||||
|
|
||||||
When `Compression_Mode` is defined as `Predefined_Mode`,
|
When `Compression_Mode` is defined as `Predefined_Mode`,
|
||||||
a predefined distribution is used for FSE compression.
|
a predefined distribution is used for FSE compression.
|
||||||
|
|
||||||
Here is its definition. It uses an accuracy of 5 bits (32 states),
|
Below is its definition. It uses an accuracy of 5 bits (32 states),
|
||||||
and supports a maximum `N` of 28, allowing offset values up to 536,870,908 .
|
and supports a maximum `N` of 28, allowing offset values up to 536,870,908 .
|
||||||
|
|
||||||
If any sequence in the compressed block requires an offset larger than this,
|
If any sequence in the compressed block requires an offset larger than this,
|
||||||
it's not possible to use the default distribution to represent it.
|
it's not possible to use the default distribution to represent it.
|
||||||
|
|
||||||
```
|
```
|
||||||
short offsetCodes_defaultDistribution[53] =
|
short offsetCodes_defaultDistribution[29] =
|
||||||
{ 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 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 };
|
1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1 };
|
||||||
```
|
```
|
||||||
@@ -905,10 +925,10 @@ since it will be discovered and reported by the decoding process.
|
|||||||
|
|
||||||
The bitstream starts by reporting on which scale it operates.
|
The bitstream starts by reporting on which scale it operates.
|
||||||
`Accuracy_Log = low4bits + 5`.
|
`Accuracy_Log = low4bits + 5`.
|
||||||
Note that maximum `Accuracy_Log` for literal and match length is `9`,
|
Note that maximum `Accuracy_Log` for literal and match lengths is `9`,
|
||||||
and for offsets it is `8`. Higher values are considered errors.
|
and for offsets is `8`. Higher values are considered errors.
|
||||||
|
|
||||||
Then follow each symbol value, from `0` to last present one.
|
Then follows each symbol value, from `0` to last present one.
|
||||||
The number of bits used by each field is variable.
|
The number of bits used by each field is variable.
|
||||||
It depends on :
|
It depends on :
|
||||||
|
|
||||||
@@ -937,11 +957,11 @@ It depends on :
|
|||||||
|
|
||||||
Symbols probabilities are read one by one, in order.
|
Symbols probabilities are read one by one, in order.
|
||||||
|
|
||||||
Probability is obtained from Value decoded by following formulae :
|
Probability is obtained from Value decoded by following formula :
|
||||||
`Proba = value - 1`
|
`Proba = value - 1`
|
||||||
|
|
||||||
It means value `0` becomes negative probability `-1`.
|
It means value `0` becomes negative probability `-1`.
|
||||||
`-1` is a special probability, which means `less than 1`.
|
`-1` is a special probability, which means "less than 1".
|
||||||
Its effect on distribution table is described in [next paragraph].
|
Its effect on distribution table is described in [next paragraph].
|
||||||
For the purpose of calculating cumulated distribution, it counts as one.
|
For the purpose of calculating cumulated distribution, it counts as one.
|
||||||
|
|
||||||
@@ -974,7 +994,7 @@ The table has a size of `tableSize = 1 << Accuracy_Log`.
|
|||||||
Each cell describes the symbol decoded,
|
Each cell describes the symbol decoded,
|
||||||
and instructions to get the next state.
|
and instructions to get the next state.
|
||||||
|
|
||||||
Symbols are scanned in their natural order for `less than 1` probabilities.
|
Symbols are scanned in their natural order for "less than 1" probabilities.
|
||||||
Symbols with this probability are being attributed a single cell,
|
Symbols with this probability are being attributed a single cell,
|
||||||
starting from the end of the table.
|
starting from the end of the table.
|
||||||
These symbols define a full state reset, reading `Accuracy_Log` bits.
|
These symbols define a full state reset, reading `Accuracy_Log` bits.
|
||||||
@@ -996,7 +1016,7 @@ typically by a "less than 1" probability symbol.
|
|||||||
The result is a list of state values.
|
The result is a list of state values.
|
||||||
Each state will decode the current symbol.
|
Each state will decode the current symbol.
|
||||||
|
|
||||||
To get the Number of bits and baseline required for next state,
|
To get the `Number_of_Bits` and `Baseline` required for next state,
|
||||||
it's first necessary to sort all states in their natural order.
|
it's first necessary to sort all states in their natural order.
|
||||||
The lower states will need 1 more bit than higher ones.
|
The lower states will need 1 more bit than higher ones.
|
||||||
|
|
||||||
@@ -1020,24 +1040,32 @@ Numbering starts from higher states using less bits.
|
|||||||
| width | 32 | 32 | 32 | 16 | 16 |
|
| width | 32 | 32 | 32 | 16 | 16 |
|
||||||
| `Number_of_Bits` | 5 | 5 | 5 | 4 | 4 |
|
| `Number_of_Bits` | 5 | 5 | 5 | 4 | 4 |
|
||||||
| range number | 2 | 4 | 6 | 0 | 1 |
|
| range number | 2 | 4 | 6 | 0 | 1 |
|
||||||
| baseline | 32 | 64 | 96 | 0 | 16 |
|
| `Baseline` | 32 | 64 | 96 | 0 | 16 |
|
||||||
| range | 32-63 | 64-95 | 96-127 | 0-15 | 16-31 |
|
| range | 32-63 | 64-95 | 96-127 | 0-15 | 16-31 |
|
||||||
|
|
||||||
Next state is determined from current state
|
Next state is determined from current state
|
||||||
by reading the required number of bits, and adding the specified baseline.
|
by reading the required `Number_of_Bits`, and adding the specified `Baseline`.
|
||||||
|
|
||||||
|
|
||||||
#### Bitstream
|
#### Bitstream
|
||||||
|
|
||||||
All sequences are stored in a single bitstream, read _backward_.
|
FSE bitstreams are read in reverse direction than written. In zstd,
|
||||||
It is therefore necessary to know the bitstream size,
|
the compressor writes bits forward into a block and the decompressor
|
||||||
which is deducted from compressed block size.
|
must read the bitstream _backwards_.
|
||||||
|
|
||||||
The last useful bit of the stream is followed by an end-bit-flag.
|
To find the start of the bitstream it is therefore necessary to
|
||||||
Highest bit of last byte is this flag.
|
know the offset of the last byte of the block which can be found
|
||||||
It does not belong to the useful part of the bitstream.
|
by counting `Block_Size` bytes after the block header.
|
||||||
Therefore, last byte has 0-7 useful bits.
|
|
||||||
Note that it also means that last byte cannot be `0`.
|
After writing the last bit containing information, the compressor
|
||||||
|
writes a single `1`-bit and then fills the byte with 0-7 `0` bits of
|
||||||
|
padding. The last byte of the compressed bitstream cannot be `0` for
|
||||||
|
that reason.
|
||||||
|
|
||||||
|
When decompressing, the last byte containing the padding is the first
|
||||||
|
byte to read. The decompressor needs to skip 0-7 initial `0`-bits and
|
||||||
|
the first `1`-bit it occurs. Afterwards, the useful part of the bitstream
|
||||||
|
begins.
|
||||||
|
|
||||||
##### Starting states
|
##### Starting states
|
||||||
|
|
||||||
@@ -1054,16 +1082,16 @@ Reminder : always keep in mind that all values are read _backward_.
|
|||||||
##### Decoding a sequence
|
##### Decoding a sequence
|
||||||
|
|
||||||
A state gives a code.
|
A state gives a code.
|
||||||
A code provides a baseline and number of bits to add.
|
A code provides `Baseline` and `Number_of_Bits` to add.
|
||||||
See [Symbol Decoding] section for details on each symbol.
|
See [Symbol Decoding] section for details on each symbol.
|
||||||
|
|
||||||
Decoding starts by reading the number of bits required to decode offset.
|
Decoding starts by reading the `Number_of_Bits` required to decode `Offset`.
|
||||||
It then does the same for match length,
|
It then does the same for `Match_Length`,
|
||||||
and then for literals length.
|
and then for `Literals_Length`.
|
||||||
|
|
||||||
Offset / matchLength / litLength define a sequence.
|
`Offset`, `Match_Length`, and `Literals_Length` define a sequence.
|
||||||
It starts by inserting the number of literals defined by `litLength`,
|
It starts by inserting the number of literals defined by `Literals_Length`,
|
||||||
then continue by copying `matchLength` bytes from `currentPos - offset`.
|
then continue by copying `Match_Length` bytes from `currentPos - Offset`.
|
||||||
|
|
||||||
The next operation is to update states.
|
The next operation is to update states.
|
||||||
Using rules pre-calculated in the decoding tables,
|
Using rules pre-calculated in the decoding tables,
|
||||||
@@ -1075,17 +1103,17 @@ This operation will be repeated `Number_of_Sequences` times.
|
|||||||
At the end, the bitstream shall be entirely consumed,
|
At the end, the bitstream shall be entirely consumed,
|
||||||
otherwise bitstream is considered corrupted.
|
otherwise bitstream is considered corrupted.
|
||||||
|
|
||||||
[Symbol Decoding]:#symbols-decoding
|
[Symbol Decoding]:#the-codes-for-literals-lengths-match-lengths-and-offsets
|
||||||
|
|
||||||
##### Repeat offsets
|
##### Repeat offsets
|
||||||
|
|
||||||
As seen in [Offset Codes], the first 3 values define a repeated offset.
|
As seen in [Offset Codes], the first 3 values define a repeated offset and we will call them `Repeated_Offset1`, `Repeated_Offset2`, and `Repeated_Offset3`.
|
||||||
They are sorted in recency order, with 1 meaning "most recent one".
|
They are sorted in recency order, with `Repeated_Offset1` meaning "most recent one".
|
||||||
|
|
||||||
There is an exception though, when current sequence's literals length is `0`.
|
There is an exception though, when current sequence's literals length is `0`.
|
||||||
In which case, repcodes are "pushed by one",
|
In which case, repeated offsets are "pushed by one",
|
||||||
so 1 becomes 2, 2 becomes 3,
|
so `Repeated_Offset1` becomes `Repeated_Offset2`, `Repeated_Offset2` becomes `Repeated_Offset3`,
|
||||||
and 3 becomes "offset_1 - 1_byte".
|
and `Repeated_Offset3` becomes `Repeated_Offset1 - 1_byte`.
|
||||||
|
|
||||||
On first block, offset history is populated by the following values : 1, 4 and 8 (in order).
|
On first block, offset history is populated by the following values : 1, 4 and 8 (in order).
|
||||||
|
|
||||||
@@ -1100,17 +1128,17 @@ they do not contribute to offset history.
|
|||||||
New offset take the lead in offset history,
|
New offset take the lead in offset history,
|
||||||
up to its previous place if it was already present.
|
up to its previous place if it was already present.
|
||||||
|
|
||||||
It means that when repeat offset 1 (most recent) is used, history is unmodified.
|
It means that when `Repeated_Offset1` (most recent) is used, history is unmodified.
|
||||||
When repeat offset 2 is used, it's swapped with offset 1.
|
When `Repeated_Offset2` is used, it's swapped with `Repeated_Offset1`.
|
||||||
|
|
||||||
|
|
||||||
Dictionary format
|
Dictionary format
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
`zstd` is compatible with "pure content" dictionaries, free of any format restriction.
|
`zstd` is compatible with "raw content" dictionaries, free of any format restriction.
|
||||||
But dictionaries created by `zstd --train` follow a format, described here.
|
But dictionaries created by `zstd --train` follow a format, described here.
|
||||||
|
|
||||||
__Pre-requisites__ : a dictionary has a known length,
|
__Pre-requisites__ : a dictionary has a size,
|
||||||
defined either by a buffer limit, or a file size.
|
defined either by a buffer limit, or a file size.
|
||||||
|
|
||||||
| `Magic_Number` | `Dictionary_ID` | `Entropy_Tables` | `Content` |
|
| `Magic_Number` | `Dictionary_ID` | `Entropy_Tables` | `Content` |
|
||||||
@@ -1128,24 +1156,209 @@ _Reserved ranges :_
|
|||||||
However, for public distribution of compressed frames,
|
However, for public distribution of compressed frames,
|
||||||
the following ranges are reserved for future use and should not be used :
|
the following ranges are reserved for future use and should not be used :
|
||||||
|
|
||||||
- low range : 1 - 32767
|
- low range : 1 - 32767
|
||||||
- high range : >= (2^31)
|
- high range : >= (2^31)
|
||||||
|
|
||||||
__`Entropy_Tables`__ : following the same format as a [compressed blocks].
|
__`Entropy_Tables`__ : following the same format as a [compressed blocks].
|
||||||
They are stored in following order :
|
They are stored in following order :
|
||||||
Huffman tables for literals, FSE table for offset,
|
Huffman tables for literals, FSE table for offsets,
|
||||||
FSE table for matchLenth, and FSE table for litLength.
|
FSE table for match lengths, and FSE table for literals lengths.
|
||||||
It's finally followed by 3 offset values, populating recent offsets,
|
It's finally followed by 3 offset values, populating recent offsets,
|
||||||
stored in order, 4-bytes little-endian each, for a total of 12 bytes.
|
stored in order, 4-bytes little-endian each, for a total of 12 bytes.
|
||||||
|
Each recent offset must have a value < dictionary size.
|
||||||
|
|
||||||
__`Content`__ : Where the actual dictionary content is.
|
__`Content`__ : The rest of the dictionary is its content.
|
||||||
Content size depends on Dictionary size.
|
The content act as a "past" in front of data to compress or decompress.
|
||||||
|
|
||||||
[compressed blocks]: #the-format-of-compressed_block
|
[compressed blocks]: #the-format-of-compressed_block
|
||||||
|
|
||||||
|
Appendix A - Decoding tables for predefined codes
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
This appendix contains FSE decoding tables for the predefined literal length, match length, and offset
|
||||||
|
codes. The tables have been constructed using the algorithm as given above in the
|
||||||
|
"from normalized distribution to decoding tables" chapter. The tables here can be used as examples
|
||||||
|
to crosscheck that an implementation implements the decoding table generation algorithm correctly.
|
||||||
|
|
||||||
|
#### Literal Length Code:
|
||||||
|
|
||||||
|
| State | Symbol | Number_Of_Bits | Base |
|
||||||
|
| ----- | ------ | -------------- | ---- |
|
||||||
|
| 0 | 0 | 4 | 0 |
|
||||||
|
| 1 | 0 | 4 | 16 |
|
||||||
|
| 2 | 1 | 5 | 32 |
|
||||||
|
| 3 | 3 | 5 | 0 |
|
||||||
|
| 4 | 4 | 5 | 0 |
|
||||||
|
| 5 | 6 | 5 | 0 |
|
||||||
|
| 6 | 7 | 5 | 0 |
|
||||||
|
| 7 | 9 | 5 | 0 |
|
||||||
|
| 8 | 10 | 5 | 0 |
|
||||||
|
| 9 | 12 | 5 | 0 |
|
||||||
|
| 10 | 14 | 6 | 0 |
|
||||||
|
| 11 | 16 | 5 | 0 |
|
||||||
|
| 12 | 18 | 5 | 0 |
|
||||||
|
| 13 | 19 | 5 | 0 |
|
||||||
|
| 14 | 21 | 5 | 0 |
|
||||||
|
| 15 | 22 | 5 | 0 |
|
||||||
|
| 16 | 24 | 5 | 0 |
|
||||||
|
| 17 | 25 | 5 | 32 |
|
||||||
|
| 18 | 26 | 5 | 0 |
|
||||||
|
| 19 | 27 | 6 | 0 |
|
||||||
|
| 20 | 29 | 6 | 0 |
|
||||||
|
| 21 | 31 | 6 | 0 |
|
||||||
|
| 22 | 0 | 4 | 32 |
|
||||||
|
| 23 | 1 | 4 | 0 |
|
||||||
|
| 24 | 2 | 5 | 0 |
|
||||||
|
| 25 | 4 | 5 | 32 |
|
||||||
|
| 26 | 5 | 5 | 0 |
|
||||||
|
| 27 | 7 | 5 | 32 |
|
||||||
|
| 28 | 8 | 5 | 0 |
|
||||||
|
| 29 | 10 | 5 | 32 |
|
||||||
|
| 30 | 11 | 5 | 0 |
|
||||||
|
| 31 | 13 | 6 | 0 |
|
||||||
|
| 32 | 16 | 5 | 32 |
|
||||||
|
| 33 | 17 | 5 | 0 |
|
||||||
|
| 34 | 19 | 5 | 32 |
|
||||||
|
| 35 | 20 | 5 | 0 |
|
||||||
|
| 36 | 22 | 5 | 32 |
|
||||||
|
| 37 | 23 | 5 | 0 |
|
||||||
|
| 38 | 25 | 4 | 0 |
|
||||||
|
| 39 | 25 | 4 | 16 |
|
||||||
|
| 40 | 26 | 5 | 32 |
|
||||||
|
| 41 | 28 | 6 | 0 |
|
||||||
|
| 42 | 30 | 6 | 0 |
|
||||||
|
| 43 | 0 | 4 | 48 |
|
||||||
|
| 44 | 1 | 4 | 16 |
|
||||||
|
| 45 | 2 | 5 | 32 |
|
||||||
|
| 46 | 3 | 5 | 32 |
|
||||||
|
| 47 | 5 | 5 | 32 |
|
||||||
|
| 48 | 6 | 5 | 32 |
|
||||||
|
| 49 | 8 | 5 | 32 |
|
||||||
|
| 50 | 9 | 5 | 32 |
|
||||||
|
| 51 | 11 | 5 | 32 |
|
||||||
|
| 52 | 12 | 5 | 32 |
|
||||||
|
| 53 | 15 | 6 | 0 |
|
||||||
|
| 54 | 17 | 5 | 32 |
|
||||||
|
| 55 | 18 | 5 | 32 |
|
||||||
|
| 56 | 20 | 5 | 32 |
|
||||||
|
| 57 | 21 | 5 | 32 |
|
||||||
|
| 58 | 23 | 5 | 32 |
|
||||||
|
| 59 | 24 | 5 | 32 |
|
||||||
|
| 60 | 35 | 6 | 0 |
|
||||||
|
| 61 | 34 | 6 | 0 |
|
||||||
|
| 62 | 33 | 6 | 0 |
|
||||||
|
| 63 | 32 | 6 | 0 |
|
||||||
|
|
||||||
|
#### Match Length Code:
|
||||||
|
|
||||||
|
| State | Symbol | Number_Of_Bits | Base |
|
||||||
|
| ----- | ------ | -------------- | ---- |
|
||||||
|
| 0 | 0 | 6 | 0 |
|
||||||
|
| 1 | 1 | 4 | 0 |
|
||||||
|
| 2 | 2 | 5 | 32 |
|
||||||
|
| 3 | 3 | 5 | 0 |
|
||||||
|
| 4 | 5 | 5 | 0 |
|
||||||
|
| 5 | 6 | 5 | 0 |
|
||||||
|
| 6 | 8 | 5 | 0 |
|
||||||
|
| 7 | 10 | 6 | 0 |
|
||||||
|
| 8 | 13 | 6 | 0 |
|
||||||
|
| 9 | 16 | 6 | 0 |
|
||||||
|
| 10 | 19 | 6 | 0 |
|
||||||
|
| 11 | 22 | 6 | 0 |
|
||||||
|
| 12 | 25 | 6 | 0 |
|
||||||
|
| 13 | 28 | 6 | 0 |
|
||||||
|
| 14 | 31 | 6 | 0 |
|
||||||
|
| 15 | 33 | 6 | 0 |
|
||||||
|
| 16 | 35 | 6 | 0 |
|
||||||
|
| 17 | 37 | 6 | 0 |
|
||||||
|
| 18 | 39 | 6 | 0 |
|
||||||
|
| 19 | 41 | 6 | 0 |
|
||||||
|
| 20 | 43 | 6 | 0 |
|
||||||
|
| 21 | 45 | 6 | 0 |
|
||||||
|
| 22 | 1 | 4 | 16 |
|
||||||
|
| 23 | 2 | 4 | 0 |
|
||||||
|
| 24 | 3 | 5 | 32 |
|
||||||
|
| 25 | 4 | 5 | 0 |
|
||||||
|
| 26 | 6 | 5 | 32 |
|
||||||
|
| 27 | 7 | 5 | 0 |
|
||||||
|
| 28 | 9 | 6 | 0 |
|
||||||
|
| 29 | 12 | 6 | 0 |
|
||||||
|
| 30 | 15 | 6 | 0 |
|
||||||
|
| 31 | 18 | 6 | 0 |
|
||||||
|
| 32 | 21 | 6 | 0 |
|
||||||
|
| 33 | 24 | 6 | 0 |
|
||||||
|
| 34 | 27 | 6 | 0 |
|
||||||
|
| 35 | 30 | 6 | 0 |
|
||||||
|
| 36 | 32 | 6 | 0 |
|
||||||
|
| 37 | 34 | 6 | 0 |
|
||||||
|
| 38 | 36 | 6 | 0 |
|
||||||
|
| 39 | 38 | 6 | 0 |
|
||||||
|
| 40 | 40 | 6 | 0 |
|
||||||
|
| 41 | 42 | 6 | 0 |
|
||||||
|
| 42 | 44 | 6 | 0 |
|
||||||
|
| 43 | 1 | 4 | 32 |
|
||||||
|
| 44 | 1 | 4 | 48 |
|
||||||
|
| 45 | 2 | 4 | 16 |
|
||||||
|
| 46 | 4 | 5 | 32 |
|
||||||
|
| 47 | 5 | 5 | 32 |
|
||||||
|
| 48 | 7 | 5 | 32 |
|
||||||
|
| 49 | 8 | 5 | 32 |
|
||||||
|
| 50 | 11 | 6 | 0 |
|
||||||
|
| 51 | 14 | 6 | 0 |
|
||||||
|
| 52 | 17 | 6 | 0 |
|
||||||
|
| 53 | 20 | 6 | 0 |
|
||||||
|
| 54 | 23 | 6 | 0 |
|
||||||
|
| 55 | 26 | 6 | 0 |
|
||||||
|
| 56 | 29 | 6 | 0 |
|
||||||
|
| 57 | 52 | 6 | 0 |
|
||||||
|
| 58 | 51 | 6 | 0 |
|
||||||
|
| 59 | 50 | 6 | 0 |
|
||||||
|
| 60 | 49 | 6 | 0 |
|
||||||
|
| 61 | 48 | 6 | 0 |
|
||||||
|
| 62 | 47 | 6 | 0 |
|
||||||
|
| 63 | 46 | 6 | 0 |
|
||||||
|
|
||||||
|
#### Offset Code:
|
||||||
|
|
||||||
|
| State | Symbol | Number_Of_Bits | Base |
|
||||||
|
| ----- | ------ | -------------- | ---- |
|
||||||
|
| 0 | 0 | 5 | 0 |
|
||||||
|
| 1 | 6 | 4 | 0 |
|
||||||
|
| 2 | 9 | 5 | 0 |
|
||||||
|
| 3 | 15 | 5 | 0 |
|
||||||
|
| 4 | 21 | 5 | 0 |
|
||||||
|
| 5 | 3 | 5 | 0 |
|
||||||
|
| 6 | 7 | 4 | 0 |
|
||||||
|
| 7 | 12 | 5 | 0 |
|
||||||
|
| 8 | 18 | 5 | 0 |
|
||||||
|
| 9 | 23 | 5 | 0 |
|
||||||
|
| 10 | 5 | 5 | 0 |
|
||||||
|
| 11 | 8 | 4 | 0 |
|
||||||
|
| 12 | 14 | 5 | 0 |
|
||||||
|
| 13 | 20 | 5 | 0 |
|
||||||
|
| 14 | 2 | 5 | 0 |
|
||||||
|
| 15 | 7 | 4 | 16 |
|
||||||
|
| 16 | 11 | 5 | 0 |
|
||||||
|
| 17 | 17 | 5 | 0 |
|
||||||
|
| 18 | 22 | 5 | 0 |
|
||||||
|
| 19 | 4 | 5 | 0 |
|
||||||
|
| 20 | 8 | 4 | 16 |
|
||||||
|
| 21 | 13 | 5 | 0 |
|
||||||
|
| 22 | 19 | 5 | 0 |
|
||||||
|
| 23 | 1 | 5 | 0 |
|
||||||
|
| 24 | 6 | 4 | 16 |
|
||||||
|
| 25 | 10 | 5 | 0 |
|
||||||
|
| 26 | 16 | 5 | 0 |
|
||||||
|
| 27 | 28 | 5 | 0 |
|
||||||
|
| 28 | 27 | 5 | 0 |
|
||||||
|
| 29 | 26 | 5 | 0 |
|
||||||
|
| 30 | 25 | 5 | 0 |
|
||||||
|
| 31 | 24 | 5 | 0 |
|
||||||
|
|
||||||
Version changes
|
Version changes
|
||||||
---------------
|
---------------
|
||||||
|
- 0.2.2 : added predefined codes, by Johannes Rudolph
|
||||||
|
- 0.2.1 : clarify field names, by Przemyslaw Skibinski
|
||||||
- 0.2.0 : numerous format adjustments for zstd v0.8
|
- 0.2.0 : numerous format adjustments for zstd v0.8
|
||||||
- 0.1.2 : limit Huffman tree depth to 11 bits
|
- 0.1.2 : limit Huffman tree depth to 11 bits
|
||||||
- 0.1.1 : reserved dictID ranges
|
- 0.1.1 : reserved dictID ranges
|
||||||
|
|||||||
Reference in New Issue
Block a user