diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 357985a..770cefa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -201,8 +201,8 @@ if (WIN32) # Bundled zstd set(ZSTD_BUILD_PROGRAMS OFF) set(ZSTD_BUILD_SHARED OFF) - add_subdirectory(dependencies/zstd-1.5.4/build/cmake) - set(ZSTD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zstd-1.5.4/lib CACHE PATH "zstd include dir") + add_subdirectory(dependencies/zstd-1.5.6/build/cmake) + set(ZSTD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zstd-1.5.6/lib CACHE PATH "zstd include dir") set(ZSTD_LIBRARY libzstd_static) # Bundled libarchive @@ -295,8 +295,8 @@ elseif(APPLE) # Bundled zstd set(ZSTD_BUILD_PROGRAMS OFF) set(ZSTD_BUILD_SHARED OFF) - add_subdirectory(dependencies/zstd-1.5.4/build/cmake) - set(ZSTD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zstd-1.5.4/lib) + add_subdirectory(dependencies/zstd-1.5.6/build/cmake) + set(ZSTD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zstd-1.5.6/lib) set(ZSTD_LIBRARY libzstd_static) # Bundled libarchive diff --git a/src/dependencies/zstd-1.5.4/.travis.yml b/src/dependencies/zstd-1.5.4/.travis.yml deleted file mode 100644 index b96bf8b..0000000 --- a/src/dependencies/zstd-1.5.4/.travis.yml +++ /dev/null @@ -1,128 +0,0 @@ -# Travis CI is used to test platforms that github-actions currently doesn't support -# without either self-hosting or some finnicky work-around. Also, some tests -# are troublesome to migrate since GH Actions runs tests not in a tty. -language: c - -git: - depth: 1 - -branches: - only: - - dev - - release - - master - - travisTest - -addons: - apt: - update: true - -env: - global: - - FUZZERTEST=-T1mn - ZSTREAM_TESTTIME=-T1mn - DECODECORPUS_TESTTIME=-T1mn - -matrix: - fast_finish: true - include: - - name: S390X (big endian) + Fuzz test - dist: trusty - arch: s390x - script: - - FUZZER_FLAGS=--no-big-tests make -C tests fuzztest - - - name: S390X (big endian) + Fuzz test + no intrinsics - dist: trusty - arch: s390x - script: - - MOREFLAGS="-DZSTD_NO_INTRINSICS" FUZZER_FLAGS=--no-big-tests make -C tests fuzztest - - - name: arm64 # ~2.5 mn - os: linux - arch: arm64 - script: - - make check - - - name: arm64fuzz - os: linux - arch: arm64 - script: - - make -C tests fuzztest - - # TODO: migrate to GH Actions once newest clang staticanalyze warnings are fixed - - name: static analyzer scanbuild # ~8mn - dist: trusty # note : it's important to pin down a version of static analyzer, since different versions report different false positives - script: - - make staticAnalyze - - # GH actions can't run this command on OS-X, non-tty issues - - name: OS-X make all lib - os: osx - script: - - make -C lib all - - # Introduced to check compat with old toolchains, to prevent e.g. #1872 - - name: ARM Build Test (on Trusty) - dist: trusty - script: - - make arminstall - - make armbuild - - # check release number (release/new tag only) - - name: Tag-Specific Test - if: tag =~ ^v[0-9]\.[0-9] - script: - - make -C tests checkTag - - tests/checkTag "$TRAVIS_BRANCH" - - - name: PPC64LE + Fuzz test # ~13mn - arch: ppc64le - env: - - FUZZER_FLAGS=--no-big-tests - - MOREFLAGS="-static" - script: - - cat /proc/cpuinfo - - make -C tests fuzztest - - # This test currently fails on GA specifically, for no obvious reason - # (it works fine on travisCI, and on local test platforms). - - name: Versions Compatibility Test # ~6mn - script: - - make -C tests versionsTest - - # meson dedicated test - - name: Focal (Meson + clang) # ~15mn - dist: focal - language: cpp - compiler: clang - install: - - sudo apt-get install -qq liblz4-dev valgrind tree - - | - travis_retry curl -o ~/ninja.zip -L 'https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-linux.zip' && - unzip ~/ninja.zip -d ~/.local/bin - - | - travis_retry curl -o ~/get-pip.py -L 'https://bootstrap.pypa.io/pip/3.6/get-pip.py' && - python3 ~/get-pip.py --user && - pip3 install --user meson - script: - - | - meson setup \ - --buildtype=debugoptimized \ - -Db_lundef=false \ - -Dauto_features=enabled \ - -Dbin_programs=true \ - -Dbin_tests=true \ - -Dbin_contrib=true \ - -Ddefault_library=both \ - build/meson builddir - - pushd builddir - - ninja - - meson test --verbose --no-rebuild - - DESTDIR=./staging ninja install - - tree ./staging - after_failure: - - cat "$TRAVIS_BUILD_DIR"/builddir/meson-logs/testlog.txt - - allow_failures: - - env: ALLOW_FAILURES=true diff --git a/src/dependencies/zstd-1.5.4/appveyor.yml b/src/dependencies/zstd-1.5.4/appveyor.yml deleted file mode 100644 index c58ef91..0000000 --- a/src/dependencies/zstd-1.5.4/appveyor.yml +++ /dev/null @@ -1,205 +0,0 @@ -# Following tests are run _only_ on `release` branch -# and on selected feature branch named `appveyorTest` or `visual*` - -- - version: 1.0.{build} - branches: - only: - - release - - master - - /appveyor*/ - - /visual*/ - environment: - matrix: - - COMPILER: "gcc" - HOST: "mingw" - PLATFORM: "x64" - SCRIPT: "make allzstd MOREFLAGS=-static" - ARTIFACT: "true" - BUILD: "true" - - COMPILER: "gcc" - HOST: "mingw" - PLATFORM: "x86" - SCRIPT: "make allzstd MOREFLAGS=-static" - ARTIFACT: "true" - BUILD: "true" - - - COMPILER: "clang-cl" - HOST: "cmake-visual" - PLATFORM: "x64" - CONFIGURATION: "Release" - CMAKE_GENERATOR: "Visual Studio 15 2017" - CMAKE_GENERATOR_PLATFORM: "x64" - CMAKE_GENERATOR_TOOLSET: "LLVM" - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017" - - install: - - ECHO Installing %COMPILER% %PLATFORM% %CONFIGURATION% - - SET PATH_ORIGINAL=%PATH% - - if [%HOST%]==[mingw] ( - SET "PATH_MINGW32=C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin" && - SET "PATH_MINGW64=C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin" && - COPY C:\msys64\usr\bin\make.exe C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin\make.exe && - COPY C:\msys64\usr\bin\make.exe C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin\make.exe - ) - - IF [%HOST%]==[visual] IF [%PLATFORM%]==[x64] ( - SET ADDITIONALPARAM=/p:LibraryPath="C:\Program Files\Microsoft SDKs\Windows\v7.1\lib\x64;c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64;C:\Program Files (x86)\Microsoft Visual Studio 10.0\;C:\Program Files (x86)\Microsoft Visual Studio 10.0\lib\amd64;" - ) - - build_script: - - if [%HOST%]==[mingw] ( - ( if [%PLATFORM%]==[x64] ( - SET "PATH=%PATH_MINGW64%;%PATH_ORIGINAL%" - ) else if [%PLATFORM%]==[x86] ( - SET "PATH=%PATH_MINGW32%;%PATH_ORIGINAL%" - ) ) - ) - - if [%HOST%]==[mingw] if [%BUILD%]==[true] ( - make -v && - sh -c "%COMPILER% -v" && - ECHO Building zlib to static link && - SET "CC=%COMPILER%" && - sh -c "cd .. && git clone --depth 1 --branch v1.2.11 https://github.com/madler/zlib" && - sh -c "cd ../zlib && make -f win32/Makefile.gcc libz.a" - ECHO Building zstd && - SET "CPPFLAGS=-I../../zlib" && - SET "LDFLAGS=../../zlib/libz.a" && - sh -c "%SCRIPT%" && - ( if [%COMPILER%]==[gcc] if [%ARTIFACT%]==[true] - ECHO Creating artifacts && - ECHO %cd% && - lib\dll\example\build_package.bat && - make -C programs DEBUGFLAGS= clean zstd && - cd programs\ && 7z a -tzip -mx9 zstd-win-binary-%PLATFORM%.zip zstd.exe && - appveyor PushArtifact zstd-win-binary-%PLATFORM%.zip && - cp zstd.exe ..\bin\zstd.exe && - git clone --depth 1 --branch release https://github.com/facebook/zstd && - cd zstd && - git archive --format=tar release -o zstd-src.tar && - ..\zstd -19 zstd-src.tar && - appveyor PushArtifact zstd-src.tar.zst && - certUtil -hashfile zstd-src.tar.zst SHA256 > zstd-src.tar.zst.sha256.sig && - appveyor PushArtifact zstd-src.tar.zst.sha256.sig && - cd ..\..\bin\ && - 7z a -tzip -mx9 zstd-win-release-%PLATFORM%.zip * && - appveyor PushArtifact zstd-win-release-%PLATFORM%.zip - ) - ) - - if [%HOST%]==[cmake-visual] ( - ECHO *** && - ECHO *** Building %CMAKE_GENERATOR% ^(%CMAKE_GENERATOR_TOOLSET%^) %PLATFORM%\%CONFIGURATION% && - PUSHD build\cmake && - cmake -DBUILD_TESTING=ON . && - cmake --build . --config %CONFIGURATION% -j4 && - POPD && - ECHO *** - ) - - test_script: - - ECHO Testing %COMPILER% %PLATFORM% %CONFIGURATION% - - SET "CC=gcc" - - SET "CXX=g++" - - if [%TEST%]==[cmake] ( - mkdir build\cmake\build && - cd build\cmake\build && - SET FUZZERTEST=-T2mn && - SET ZSTREAM_TESTTIME=-T2mn && - cmake -G "Visual Studio 14 2015 Win64" .. && - cd ..\..\.. && - make clean - ) - - -# The following tests are for regular pushes -# into `dev` or some feature branch -# There run less tests, for shorter feedback loop - -- - version: 1.0.{build} - environment: - matrix: - - COMPILER: "visual" - HOST: "visual" - PLATFORM: "x64" - CONFIGURATION: "Debug" - - COMPILER: "visual" - HOST: "visual" - PLATFORM: "Win32" - CONFIGURATION: "Debug" - - COMPILER: "visual" - HOST: "visual" - PLATFORM: "x64" - CONFIGURATION: "Release" - - COMPILER: "visual" - HOST: "visual" - PLATFORM: "Win32" - CONFIGURATION: "Release" - - - COMPILER: "gcc" - HOST: "cygwin" - PLATFORM: "x64" - - - COMPILER: "clang-cl" - HOST: "cmake-visual" - PLATFORM: "x64" - CONFIGURATION: "Release" - CMAKE_GENERATOR: "Visual Studio 15 2017" - CMAKE_GENERATOR_PLATFORM: "x64" - CMAKE_GENERATOR_TOOLSET: "LLVM" - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017" - - install: - - ECHO Installing %COMPILER% %PLATFORM% %CONFIGURATION% - - SET PATH_ORIGINAL=%PATH% - - if [%HOST%]==[cygwin] ( - ECHO Installing Cygwin Packages && - C:\cygwin64\setup-x86_64.exe -qnNdO -R "C:\cygwin64" -g -P ^ - gcc,^ - cmake,^ - make - ) - - IF [%HOST%]==[visual] IF [%PLATFORM%]==[x64] ( - SET ADDITIONALPARAM=/p:LibraryPath="C:\Program Files\Microsoft SDKs\Windows\v7.1\lib\x64;c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64;C:\Program Files (x86)\Microsoft Visual Studio 10.0\;C:\Program Files (x86)\Microsoft Visual Studio 10.0\lib\amd64;" - ) - - build_script: - - ECHO Building %COMPILER% %PLATFORM% %CONFIGURATION% - - if [%HOST%]==[cygwin] ( - set CHERE_INVOKING=yes && - set CC=%COMPILER% && - C:\cygwin64\bin\bash --login -c " - set -e; - cd build/cmake; - CFLAGS='-Werror' cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=Debug -DZSTD_BUILD_TESTS:BOOL=ON -DZSTD_FUZZER_FLAGS=-T20s -DZSTD_ZSTREAM_FLAGS=-T20s -DZSTD_FULLBENCH_FLAGS=-i0 .; - make VERBOSE=1 -j; - ctest -V -L Medium; - " - ) - - if [%HOST%]==[cmake-visual] ( - ECHO *** && - ECHO *** Building %CMAKE_GENERATOR% ^(%CMAKE_GENERATOR_TOOLSET%^) %PLATFORM%\%CONFIGURATION% && - PUSHD build\cmake && - cmake -DBUILD_TESTING=ON . && - cmake --build . --config %CONFIGURATION% -j4 && - POPD && - ECHO *** - ) - - if [%HOST%]==[visual] ( - ECHO *** && - ECHO *** Building Visual Studio 2012 %PLATFORM%\%CONFIGURATION% && - ECHO *** && - msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && - msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe - ) - - - test_script: - - ECHO Testing %COMPILER% %PLATFORM% %CONFIGURATION% - - SET "FUZZERTEST=-T10s" - - if [%HOST%]==[mingw] ( - set "CC=%COMPILER%" && - make clean && - make check - ) \ No newline at end of file diff --git a/src/dependencies/zstd-1.5.4/build/.gitignore b/src/dependencies/zstd-1.5.4/build/.gitignore deleted file mode 100644 index 5a18b30..0000000 --- a/src/dependencies/zstd-1.5.4/build/.gitignore +++ /dev/null @@ -1,33 +0,0 @@ -# Visual C++ -.vs/ -*Copy -*.db -*.opensdf -*.sdf -*.suo -*.user -*.opendb - -VS2008/bin/ -VS2010/bin/ -VS2010/zwrapbench/ -VS2012/ -VS2013/ -VS2015/ -Studio* - -# CMake -cmake/build/ -CMakeCache.txt -CMakeFiles -CMakeScripts -Testing -Makefile -cmake_install.cmake -install_manifest.txt -compile_commands.json -CTestTestfile.cmake -build -lib -!cmake/lib -!meson/lib diff --git a/src/dependencies/zstd-1.5.4/build/README.md b/src/dependencies/zstd-1.5.4/build/README.md deleted file mode 100644 index 23f92ce..0000000 --- a/src/dependencies/zstd-1.5.4/build/README.md +++ /dev/null @@ -1,56 +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 -- `VS2005` - Visual Studio 2005 Project (this project has been moved to the contrib directory and will no longer be supported) -- `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` - - -#### Projects available within zstd.sln - -The Visual Studio solution file `visual\VS2010\zstd.sln` contains many projects that will be compiled to the -`visual\VS2010\bin\$(Platform)_$(Configuration)` directory. For example `zstd` set to `x64` and -`Release` will be compiled to `visual\VS2010\bin\x64_Release\zstd.exe`. The solution file contains the -following projects: - -- `zstd` : Command Line Utility, supporting gzip-like arguments -- `datagen` : Synthetic and parametrable data generator, for tests -- `fullbench` : Precisely measure speed for each zstd inner functions -- `fuzzer` : Test tool, to check zstd integrity on target platform -- `libzstd` : A static ZSTD library compiled to `libzstd_static.lib` -- `libzstd-dll` : A dynamic ZSTD library (DLL) compiled to `libzstd.dll` with the import library `libzstd.lib` -- `fullbench-dll` : The fullbench program compiled with the import library; the executable requires ZSTD DLL - - -#### Using ZSTD DLL with Microsoft Visual C++ project - -The header file `lib\zstd.h` and the import library -`visual\VS2010\bin\$(Platform)_$(Configuration)\libzstd.lib` are required to compile -a project using Visual C++. - -1. The path to header files should be added to `Additional Include Directories` that can - be found in Project Properties of Visual Studio IDE in the `C/C++` Property Pages on the `General` page. -2. The import library has to be added to `Additional Dependencies` that can - be found in Project Properties in the `Linker` Property Pages on the `Input` page. - If one will provide only the name `libzstd.lib` without a full path to the library - then the directory has to be added to `Linker\General\Additional Library Directories`. - -The compiled executable will require ZSTD DLL which is available at -`visual\VS2010\bin\$(Platform)_$(Configuration)\libzstd.dll`. diff --git a/src/dependencies/zstd-1.5.4/build/VS2008/fullbench/fullbench.vcproj b/src/dependencies/zstd-1.5.4/build/VS2008/fullbench/fullbench.vcproj deleted file mode 100644 index 5e349dc..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS2008/fullbench/fullbench.vcproj +++ /dev/null @@ -1,549 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/dependencies/zstd-1.5.4/build/VS2008/fuzzer/fuzzer.vcproj b/src/dependencies/zstd-1.5.4/build/VS2008/fuzzer/fuzzer.vcproj deleted file mode 100644 index 32f2846..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS2008/fuzzer/fuzzer.vcproj +++ /dev/null @@ -1,585 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/dependencies/zstd-1.5.4/build/VS2008/zstd.sln b/src/dependencies/zstd-1.5.4/build/VS2008/zstd.sln deleted file mode 100644 index 97b88c8..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS2008/zstd.sln +++ /dev/null @@ -1,56 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zstd", "zstd\zstd.vcproj", "{1A2AB08E-5CE7-4C5B-BE55-458157C14051}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fuzzer", "fuzzer\fuzzer.vcproj", "{A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench", "fullbench\fullbench.vcproj", "{CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zstdlib", "zstdlib\zstdlib.vcproj", "{99DE2A79-7298-4004-A0ED-030D7A3796CA}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Debug|Win32.ActiveCfg = Debug|Win32 - {1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Debug|Win32.Build.0 = Debug|Win32 - {1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Debug|x64.ActiveCfg = Debug|x64 - {1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Debug|x64.Build.0 = Debug|x64 - {1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Release|Win32.ActiveCfg = Release|Win32 - {1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Release|Win32.Build.0 = Release|Win32 - {1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Release|x64.ActiveCfg = Release|x64 - {1A2AB08E-5CE7-4C5B-BE55-458157C14051}.Release|x64.Build.0 = Release|x64 - {A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Debug|Win32.ActiveCfg = Debug|Win32 - {A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Debug|Win32.Build.0 = Debug|Win32 - {A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Debug|x64.ActiveCfg = Debug|x64 - {A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Debug|x64.Build.0 = Debug|x64 - {A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Release|Win32.ActiveCfg = Release|Win32 - {A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Release|Win32.Build.0 = Release|Win32 - {A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Release|x64.ActiveCfg = Release|x64 - {A62E89D2-9DDE-42BA-8F9B-9DA74889A6B0}.Release|x64.Build.0 = Release|x64 - {CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Debug|Win32.ActiveCfg = Debug|Win32 - {CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Debug|Win32.Build.0 = Debug|Win32 - {CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Debug|x64.ActiveCfg = Debug|x64 - {CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Debug|x64.Build.0 = Debug|x64 - {CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Release|Win32.ActiveCfg = Release|Win32 - {CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Release|Win32.Build.0 = Release|Win32 - {CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Release|x64.ActiveCfg = Release|x64 - {CC8F1D1B-BA2F-43E3-A71F-FA415D81AAD3}.Release|x64.Build.0 = Release|x64 - {99DE2A79-7298-4004-A0ED-030D7A3796CA}.Debug|Win32.ActiveCfg = Debug|Win32 - {99DE2A79-7298-4004-A0ED-030D7A3796CA}.Debug|Win32.Build.0 = Debug|Win32 - {99DE2A79-7298-4004-A0ED-030D7A3796CA}.Debug|x64.ActiveCfg = Debug|x64 - {99DE2A79-7298-4004-A0ED-030D7A3796CA}.Debug|x64.Build.0 = Debug|x64 - {99DE2A79-7298-4004-A0ED-030D7A3796CA}.Release|Win32.ActiveCfg = Release|Win32 - {99DE2A79-7298-4004-A0ED-030D7A3796CA}.Release|Win32.Build.0 = Release|Win32 - {99DE2A79-7298-4004-A0ED-030D7A3796CA}.Release|x64.ActiveCfg = Release|x64 - {99DE2A79-7298-4004-A0ED-030D7A3796CA}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/src/dependencies/zstd-1.5.4/build/VS2008/zstd/zstd.vcproj b/src/dependencies/zstd-1.5.4/build/VS2008/zstd/zstd.vcproj deleted file mode 100644 index 91f2bda..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS2008/zstd/zstd.vcproj +++ /dev/null @@ -1,673 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/dependencies/zstd-1.5.4/build/VS2008/zstdlib/zstdlib.vcproj b/src/dependencies/zstd-1.5.4/build/VS2008/zstdlib/zstdlib.vcproj deleted file mode 100644 index 88c1aee..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS2008/zstdlib/zstdlib.vcproj +++ /dev/null @@ -1,635 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/dependencies/zstd-1.5.4/build/VS2010/CompileAsCpp.props b/src/dependencies/zstd-1.5.4/build/VS2010/CompileAsCpp.props deleted file mode 100644 index 372a94b..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS2010/CompileAsCpp.props +++ /dev/null @@ -1,8 +0,0 @@ - - - - - CompileAsCpp - - - diff --git a/src/dependencies/zstd-1.5.4/build/VS2010/datagen/datagen.vcxproj b/src/dependencies/zstd-1.5.4/build/VS2010/datagen/datagen.vcxproj deleted file mode 100644 index a66358a..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS2010/datagen/datagen.vcxproj +++ /dev/null @@ -1,168 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {037E781E-81A6-494B-B1B3-438AB1200523} - Win32Proj - datagen - $(SolutionDir)bin\$(Platform)_$(Configuration)\ - $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ - - - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - true - false - $(IncludePath);$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); - - - true - false - $(IncludePath);$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); - - - false - false - $(IncludePath);$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); - - - false - false - $(IncludePath);$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); - - - - - - Level4 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - false - - - Console - true - - - - - - - Level4 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - false - - - Console - true - - - - - Level4 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - false - false - MultiThreaded - - - Console - true - true - true - - - - - Level4 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - false - false - MultiThreaded - - - Console - true - true - true - - - - - - - - - - - - - - diff --git a/src/dependencies/zstd-1.5.4/build/VS2010/fullbench-dll/fullbench-dll.vcxproj b/src/dependencies/zstd-1.5.4/build/VS2010/fullbench-dll/fullbench-dll.vcxproj deleted file mode 100644 index befdc04..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS2010/fullbench-dll/fullbench-dll.vcxproj +++ /dev/null @@ -1,189 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8} - Win32Proj - fullbench-dll - $(SolutionDir)bin\$(Platform)_$(Configuration)\ - $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ - - - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - true - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); - false - - - true - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); - false - - - false - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); - false - - - false - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); - false - - - - - - Level4 - Disabled - WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions) - true - false - - - Console - true - $(SolutionDir)bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories) - libzstd.lib;%(AdditionalDependencies) - false - - - - - - - Level4 - Disabled - WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions) - true - false - - - Console - true - $(SolutionDir)bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories) - libzstd.lib;%(AdditionalDependencies) - - - - - Level4 - - - MaxSpeed - true - true - WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions) - false - false - MultiThreaded - - - Console - true - true - true - $(SolutionDir)bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories) - libzstd.lib;%(AdditionalDependencies) - false - - - - - Level4 - - - MaxSpeed - true - true - WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions) - false - false - MultiThreaded - - - Console - true - true - true - $(SolutionDir)bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories) - libzstd.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - {00000000-94d5-4bf9-8a50-7bd9929a0850} - - - - - - diff --git a/src/dependencies/zstd-1.5.4/build/VS2010/fullbench/fullbench.vcxproj b/src/dependencies/zstd-1.5.4/build/VS2010/fullbench/fullbench.vcxproj deleted file mode 100644 index 2e0a042..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS2010/fullbench/fullbench.vcxproj +++ /dev/null @@ -1,218 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8} - Win32Proj - fullbench - $(SolutionDir)bin\$(Platform)_$(Configuration)\ - $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ - - - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - true - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); - false - - - true - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); - false - - - false - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); - false - - - false - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath); - false - - - - - - Level4 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - false - - - Console - true - - - - - - - Level4 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - false - - - Console - true - - - - - Level4 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - false - false - MultiThreaded - - - Console - true - true - true - - - - - Level4 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - false - false - MultiThreaded - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/dependencies/zstd-1.5.4/build/VS2010/fuzzer/fuzzer.vcxproj b/src/dependencies/zstd-1.5.4/build/VS2010/fuzzer/fuzzer.vcxproj deleted file mode 100644 index 91974ec..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS2010/fuzzer/fuzzer.vcxproj +++ /dev/null @@ -1,223 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {6FD4352B-346C-4703-96EA-D4A8B9A6976E} - Win32Proj - fuzzer - $(SolutionDir)bin\$(Platform)_$(Configuration)\ - $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ - - - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - true - false - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\compress;$(UniversalCRT_IncludePath); - - - true - false - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\compress;$(UniversalCRT_IncludePath); - - - false - false - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\compress;$(UniversalCRT_IncludePath); - - - false - false - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\compress;$(UniversalCRT_IncludePath); - - - - - - Level4 - Disabled - ZSTD_MULTITHREAD=1;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - false - - - Console - true - - - - - - - Level4 - Disabled - ZSTD_MULTITHREAD=1;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - false - - - Console - true - - - - - Level4 - - - MaxSpeed - true - true - ZSTD_MULTITHREAD=1;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - false - false - MultiThreaded - - - Console - true - true - true - - - - - Level4 - - - MaxSpeed - true - true - ZSTD_MULTITHREAD=1;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - false - false - MultiThreaded - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/dependencies/zstd-1.5.4/build/VS2010/libzstd-dll/libzstd-dll.rc b/src/dependencies/zstd-1.5.4/build/VS2010/libzstd-dll/libzstd-dll.rc deleted file mode 100644 index 13e8746..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS2010/libzstd-dll/libzstd-dll.rc +++ /dev/null @@ -1,51 +0,0 @@ -// 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", "Meta Platforms, Inc." - VALUE "FileDescription", "Zstandard - Fast and efficient compression algorithm" - VALUE "FileVersion", ZSTD_VERSION_STRING - VALUE "InternalName", "libzstd.dll" - VALUE "LegalCopyright", "Copyright (c) Meta Platforms, Inc. and affiliates." - VALUE "OriginalFilename", "libzstd.dll" - VALUE "ProductName", "Zstandard" - VALUE "ProductVersion", ZSTD_VERSION_STRING - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0409, 1200 - END -END - -#endif diff --git a/src/dependencies/zstd-1.5.4/build/VS2010/libzstd-dll/libzstd-dll.vcxproj b/src/dependencies/zstd-1.5.4/build/VS2010/libzstd-dll/libzstd-dll.vcxproj deleted file mode 100644 index a0aa897..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS2010/libzstd-dll/libzstd-dll.vcxproj +++ /dev/null @@ -1,250 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {00000000-94D5-4BF9-8A50-7BD9929A0850} - Win32Proj - libzstd-dll - $(SolutionDir)bin\$(Platform)_$(Configuration)\ - $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ - - - - DynamicLibrary - true - MultiByte - - - DynamicLibrary - true - MultiByte - - - DynamicLibrary - false - true - MultiByte - - - DynamicLibrary - false - true - MultiByte - - - - - - - - - - - - - - - - - - - true - libzstd - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); - false - - - true - libzstd - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); - false - - - false - libzstd - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); - false - - - false - libzstd - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); - false - - - - - - Level4 - Disabled - ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - EditAndContinue - true - false - - - Console - true - MachineX86 - - - - - - - Level4 - Disabled - ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - ProgramDatabase - false - - - Console - true - - - - - Level4 - - - MaxSpeed - true - true - ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - false - MultiThreaded - ProgramDatabase - - - Console - true - true - true - MachineX86 - - - - - Level4 - - - MaxSpeed - true - true - ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - false - false - MultiThreaded - ProgramDatabase - true - true - - - Console - true - true - true - - - - - - diff --git a/src/dependencies/zstd-1.5.4/build/VS2010/libzstd/libzstd.vcxproj b/src/dependencies/zstd-1.5.4/build/VS2010/libzstd/libzstd.vcxproj deleted file mode 100644 index 17c08d7..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS2010/libzstd/libzstd.vcxproj +++ /dev/null @@ -1,243 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850} - Win32Proj - libzstd - libzstd_static - MultiByte - StaticLibrary - $(SolutionDir)bin\$(Platform)_$(Configuration)\ - $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ - - - - true - - - true - - - false - true - - - false - true - - - - - - - - - - - - - - - - - - - true - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); - false - - - true - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); - false - - - false - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); - false - - - false - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); - false - - - - $(OutDir)$(TargetName).pdb - - - - - - - Level4 - Disabled - ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - EditAndContinue - true - false - - - Console - true - MachineX86 - - - - - - - Level4 - Disabled - ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - ProgramDatabase - false - - - Console - true - - - - - Level4 - - - MaxSpeed - true - true - ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - false - MultiThreaded - ProgramDatabase - - - Console - true - true - true - MachineX86 - - - - - Level4 - - - MaxSpeed - true - true - ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - false - false - MultiThreaded - ProgramDatabase - true - true - - - Console - true - true - true - - - - - - diff --git a/src/dependencies/zstd-1.5.4/build/VS2010/zstd.sln b/src/dependencies/zstd-1.5.4/build/VS2010/zstd.sln deleted file mode 100644 index 12032db..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS2010/zstd.sln +++ /dev/null @@ -1,89 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Express 2012 for Windows Desktop -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zstd", "zstd\zstd.vcxproj", "{4E52A41A-F33B-4C7A-8C36-A1A6B4F4277C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fuzzer", "fuzzer\fuzzer.vcxproj", "{6FD4352B-346C-4703-96EA-D4A8B9A6976E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench", "fullbench\fullbench.vcxproj", "{61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench-dll", "fullbench-dll\fullbench-dll.vcxproj", "{00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}" - ProjectSection(ProjectDependencies) = postProject - {00000000-94D5-4BF9-8A50-7BD9929A0850} = {00000000-94D5-4BF9-8A50-7BD9929A0850} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "datagen", "datagen\datagen.vcxproj", "{037E781E-81A6-494B-B1B3-438AB1200523}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzstd", "libzstd\libzstd.vcxproj", "{8BFD8150-94D5-4BF9-8A50-7BD9929A0850}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzstd-dll", "libzstd-dll\libzstd-dll.vcxproj", "{00000000-94D5-4BF9-8A50-7BD9929A0850}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4E52A41A-F33B-4C7A-8C36-A1A6B4F4277C}.Debug|Win32.ActiveCfg = Debug|Win32 - {4E52A41A-F33B-4C7A-8C36-A1A6B4F4277C}.Debug|Win32.Build.0 = Debug|Win32 - {4E52A41A-F33B-4C7A-8C36-A1A6B4F4277C}.Debug|x64.ActiveCfg = Debug|x64 - {4E52A41A-F33B-4C7A-8C36-A1A6B4F4277C}.Debug|x64.Build.0 = Debug|x64 - {4E52A41A-F33B-4C7A-8C36-A1A6B4F4277C}.Release|Win32.ActiveCfg = Release|Win32 - {4E52A41A-F33B-4C7A-8C36-A1A6B4F4277C}.Release|Win32.Build.0 = Release|Win32 - {4E52A41A-F33B-4C7A-8C36-A1A6B4F4277C}.Release|x64.ActiveCfg = Release|x64 - {4E52A41A-F33B-4C7A-8C36-A1A6B4F4277C}.Release|x64.Build.0 = Release|x64 - {6FD4352B-346C-4703-96EA-D4A8B9A6976E}.Debug|Win32.ActiveCfg = Debug|Win32 - {6FD4352B-346C-4703-96EA-D4A8B9A6976E}.Debug|Win32.Build.0 = Debug|Win32 - {6FD4352B-346C-4703-96EA-D4A8B9A6976E}.Debug|x64.ActiveCfg = Debug|x64 - {6FD4352B-346C-4703-96EA-D4A8B9A6976E}.Debug|x64.Build.0 = Debug|x64 - {6FD4352B-346C-4703-96EA-D4A8B9A6976E}.Release|Win32.ActiveCfg = Release|Win32 - {6FD4352B-346C-4703-96EA-D4A8B9A6976E}.Release|Win32.Build.0 = Release|Win32 - {6FD4352B-346C-4703-96EA-D4A8B9A6976E}.Release|x64.ActiveCfg = Release|x64 - {6FD4352B-346C-4703-96EA-D4A8B9A6976E}.Release|x64.Build.0 = Release|x64 - {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}.Debug|Win32.ActiveCfg = Debug|Win32 - {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}.Debug|Win32.Build.0 = Debug|Win32 - {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}.Debug|x64.ActiveCfg = Debug|x64 - {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}.Debug|x64.Build.0 = Debug|x64 - {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|Win32.ActiveCfg = Release|Win32 - {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|Win32.Build.0 = Release|Win32 - {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|x64.ActiveCfg = Release|x64 - {61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|x64.Build.0 = Release|x64 - {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}.Debug|Win32.ActiveCfg = Debug|Win32 - {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}.Debug|Win32.Build.0 = Debug|Win32 - {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}.Debug|x64.ActiveCfg = Debug|x64 - {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}.Debug|x64.Build.0 = Debug|x64 - {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|Win32.ActiveCfg = Release|Win32 - {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|Win32.Build.0 = Release|Win32 - {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|x64.ActiveCfg = Release|x64 - {00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}.Release|x64.Build.0 = Release|x64 - {037E781E-81A6-494B-B1B3-438AB1200523}.Debug|Win32.ActiveCfg = Debug|Win32 - {037E781E-81A6-494B-B1B3-438AB1200523}.Debug|Win32.Build.0 = Debug|Win32 - {037E781E-81A6-494B-B1B3-438AB1200523}.Debug|x64.ActiveCfg = Debug|x64 - {037E781E-81A6-494B-B1B3-438AB1200523}.Debug|x64.Build.0 = Debug|x64 - {037E781E-81A6-494B-B1B3-438AB1200523}.Release|Win32.ActiveCfg = Release|Win32 - {037E781E-81A6-494B-B1B3-438AB1200523}.Release|Win32.Build.0 = Release|Win32 - {037E781E-81A6-494B-B1B3-438AB1200523}.Release|x64.ActiveCfg = Release|x64 - {037E781E-81A6-494B-B1B3-438AB1200523}.Release|x64.Build.0 = Release|x64 - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Debug|Win32.ActiveCfg = Debug|Win32 - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Debug|Win32.Build.0 = Debug|Win32 - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Debug|x64.ActiveCfg = Debug|x64 - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Debug|x64.Build.0 = Debug|x64 - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Release|Win32.ActiveCfg = Release|Win32 - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Release|Win32.Build.0 = Release|Win32 - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Release|x64.ActiveCfg = Release|x64 - {8BFD8150-94D5-4BF9-8A50-7BD9929A0850}.Release|x64.Build.0 = Release|x64 - {00000000-94D5-4BF9-8A50-7BD9929A0850}.Debug|Win32.ActiveCfg = Debug|Win32 - {00000000-94D5-4BF9-8A50-7BD9929A0850}.Debug|Win32.Build.0 = Debug|Win32 - {00000000-94D5-4BF9-8A50-7BD9929A0850}.Debug|x64.ActiveCfg = Debug|x64 - {00000000-94D5-4BF9-8A50-7BD9929A0850}.Debug|x64.Build.0 = Debug|x64 - {00000000-94D5-4BF9-8A50-7BD9929A0850}.Release|Win32.ActiveCfg = Release|Win32 - {00000000-94D5-4BF9-8A50-7BD9929A0850}.Release|Win32.Build.0 = Release|Win32 - {00000000-94D5-4BF9-8A50-7BD9929A0850}.Release|x64.ActiveCfg = Release|x64 - {00000000-94D5-4BF9-8A50-7BD9929A0850}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/src/dependencies/zstd-1.5.4/build/VS2010/zstd/zstd.vcxproj b/src/dependencies/zstd-1.5.4/build/VS2010/zstd/zstd.vcxproj deleted file mode 100644 index 8ab239d..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS2010/zstd/zstd.vcxproj +++ /dev/null @@ -1,259 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {4E52A41A-F33B-4C7A-8C36-A1A6B4F4277C} - Win32Proj - zstd - $(SolutionDir)bin\$(Platform)_$(Configuration)\ - $(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\ - - - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - true - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\compress;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); - false - $(LibraryPath) - - - true - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\compress;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); - false - $(LibraryPath); - - - false - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\compress;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); - false - $(LibraryPath) - - - false - $(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\compress;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\dictBuilder;$(UniversalCRT_IncludePath); - false - $(LibraryPath); - - - - - - Level4 - Disabled - ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - false - - - Console - true - setargv.obj;%(AdditionalDependencies) - - - - - - - Level4 - Disabled - ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - false - - - Console - true - setargv.obj;%(AdditionalDependencies) - - - - - Level4 - - - MaxSpeed - true - true - ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - false - false - MultiThreaded - - - Console - true - true - true - setargv.obj;%(AdditionalDependencies) - - - - - Level4 - - - MaxSpeed - true - true - ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - false - false - MultiThreaded - /DZSTD_MULTITHREAD %(AdditionalOptions) - - - Console - true - true - true - setargv.obj;%(AdditionalDependencies) - - - - - - diff --git a/src/dependencies/zstd-1.5.4/build/VS_scripts/README.md b/src/dependencies/zstd-1.5.4/build/VS_scripts/README.md deleted file mode 100644 index 6ccaca7..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS_scripts/README.md +++ /dev/null @@ -1,64 +0,0 @@ -Command line scripts for Visual Studio compilation without IDE -============================================================== - -Here are a few command lines for reference : - -### Build with Visual Studio 2013 for msvcr120.dll - -Running the following command will build both the `Release Win32` and `Release x64` versions: -```batch -build.VS2013.cmd -``` -The result of each build will be in the corresponding `bin\Release\{ARCH}\` folder. - -If you want to only need one architecture: -- Win32: `build.generic.cmd VS2013 Win32 Release v120` -- x64: `build.generic.cmd VS2013 x64 Release v120` - -If you want a Debug build: -- Win32: `build.generic.cmd VS2013 Win32 Debug v120` -- x64: `build.generic.cmd VS2013 x64 Debug v120` - -### Build with Visual Studio 2015 for msvcr140.dll - -Running the following command will build both the `Release Win32` and `Release x64` versions: -```batch -build.VS2015.cmd -``` -The result of each build will be in the corresponding `bin\Release\{ARCH}\` folder. - -If you want to only need one architecture: -- Win32: `build.generic.cmd VS2015 Win32 Release v140` -- x64: `build.generic.cmd VS2015 x64 Release v140` - -If you want a Debug build: -- Win32: `build.generic.cmd VS2015 Win32 Debug v140` -- x64: `build.generic.cmd VS2015 x64 Debug v140` - -### Build with Visual Studio 2015 for msvcr120.dll - -This capability is offered through `build.generic.cmd` using proper arguments: - -**For Win32** -```batch -build.generic.cmd VS2015 Win32 Release v120 -``` -The result of the build will be in the `bin\Release\Win32\` folder. - -**For x64** -```batch -build.generic.cmd VS2015 x64 Release v120 -``` -The result of the build will be in the `bin\Release\x64\` folder. - -If you want Debug builds, replace `Release` with `Debug`. - -### Build with Visual Studio 2017 - -`build.VS2017.cmd`, contributed by [@HaydnTrigg](https://github.com/HaydnTrigg), -will build both the `Release Win32` and `Release x64` versions -of the first VS2017 variant it finds, in this priority order : -Enterprise > Professional > Community - -Alternatively, it's possible to target a specific version, -using appropriate script, such as `build.VS2017Enterprise.cmd` for example. diff --git a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2010.cmd b/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2010.cmd deleted file mode 100644 index c3bc176..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2010.cmd +++ /dev/null @@ -1,7 +0,0 @@ -@echo off - -rem build 32-bit -call "%~p0%build.generic.cmd" VS2010 Win32 Release v100 - -rem build 64-bit -call "%~p0%build.generic.cmd" VS2010 x64 Release v100 \ No newline at end of file diff --git a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2012.cmd b/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2012.cmd deleted file mode 100644 index d7399a9..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2012.cmd +++ /dev/null @@ -1,6 +0,0 @@ -@echo off - -rem build 32-bit -call "%~p0%build.generic.cmd" VS2012 Win32 Release v110 -rem build 64-bit -call "%~p0%build.generic.cmd" VS2012 x64 Release v110 \ No newline at end of file diff --git a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2013.cmd b/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2013.cmd deleted file mode 100644 index 486ba6c..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2013.cmd +++ /dev/null @@ -1,7 +0,0 @@ -@echo off - -rem build 32-bit -call "%~p0%build.generic.cmd" VS2013 Win32 Release v120 - -rem build 64-bit -call "%~p0%build.generic.cmd" VS2013 x64 Release v120 \ No newline at end of file diff --git a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2015.cmd b/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2015.cmd deleted file mode 100644 index abc41c9..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2015.cmd +++ /dev/null @@ -1,7 +0,0 @@ -@echo off - -rem build 32-bit -call "%~p0%build.generic.cmd" VS2015 Win32 Release v140 - -rem build 64-bit -call "%~p0%build.generic.cmd" VS2015 x64 Release v140 \ No newline at end of file diff --git a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2017.cmd b/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2017.cmd deleted file mode 100644 index a810faa..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2017.cmd +++ /dev/null @@ -1,7 +0,0 @@ -@echo off - -rem build 32-bit -call "%~p0%build.generic.cmd" VS2017 Win32 Release v141 - -rem build 64-bit -call "%~p0%build.generic.cmd" VS2017 x64 Release v141 \ No newline at end of file diff --git a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2017Community.cmd b/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2017Community.cmd deleted file mode 100644 index 133e1b4..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2017Community.cmd +++ /dev/null @@ -1,7 +0,0 @@ -@echo off - -rem build 32-bit -call "%~p0%build.generic.cmd" VS2017Community Win32 Release v141 - -rem build 64-bit -call "%~p0%build.generic.cmd" VS2017Community x64 Release v141 \ No newline at end of file diff --git a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2017Enterprise.cmd b/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2017Enterprise.cmd deleted file mode 100644 index 6a70932..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2017Enterprise.cmd +++ /dev/null @@ -1,7 +0,0 @@ -@echo off - -rem build 32-bit -call "%~p0%build.generic.cmd" VS2017Enterprise Win32 Release v141 - -rem build 64-bit -call "%~p0%build.generic.cmd" VS2017Enterprise x64 Release v141 \ No newline at end of file diff --git a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2017Professional.cmd b/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2017Professional.cmd deleted file mode 100644 index d183519..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.VS2017Professional.cmd +++ /dev/null @@ -1,7 +0,0 @@ -@echo off - -rem build 32-bit -call "%~p0%build.generic.cmd" VS2017Professional Win32 Release v141 - -rem build 64-bit -call "%~p0%build.generic.cmd" VS2017Professional x64 Release v141 \ No newline at end of file diff --git a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.generic.cmd b/src/dependencies/zstd-1.5.4/build/VS_scripts/build.generic.cmd deleted file mode 100644 index b24e6ed..0000000 --- a/src/dependencies/zstd-1.5.4/build/VS_scripts/build.generic.cmd +++ /dev/null @@ -1,72 +0,0 @@ -@echo off - -IF "%1%" == "" GOTO display_help - -SETLOCAL - -SET msbuild_version=%1 - -SET msbuild_platform=%2 -IF "%msbuild_platform%" == "" SET msbuild_platform=x64 - -SET msbuild_configuration=%3 -IF "%msbuild_configuration%" == "" SET msbuild_configuration=Release - -SET msbuild_toolset=%4 - -GOTO build - -:display_help - -echo Syntax: build.generic.cmd msbuild_version msbuild_platform msbuild_configuration msbuild_toolset -echo msbuild_version: VS installed version (VS2012, VS2013, VS2015, VS2017, VS2019, ...) -echo msbuild_platform: Platform (x64 or Win32) -echo msbuild_configuration: VS configuration (Release or Debug) -echo msbuild_toolset: Platform Toolset (v100, v110, v120, v140, v141, v142, ...) - -EXIT /B 1 - -:build - -SET msbuild="%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" -SET msbuild_vs2017community="%programfiles(x86)%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe" -SET msbuild_vs2017professional="%programfiles(x86)%\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\MSBuild.exe" -SET msbuild_vs2017enterprise="%programfiles(x86)%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\MSBuild.exe" -IF %msbuild_version% == VS2013 SET msbuild="%programfiles(x86)%\MSBuild\12.0\Bin\MSBuild.exe" -IF %msbuild_version% == VS2015 SET msbuild="%programfiles(x86)%\MSBuild\14.0\Bin\MSBuild.exe" -IF %msbuild_version% == VS2017Community SET msbuild=%msbuild_vs2017community% -IF %msbuild_version% == VS2017Professional SET msbuild=%msbuild_vs2017professional% -IF %msbuild_version% == VS2017Enterprise SET msbuild=%msbuild_vs2017enterprise% -IF %msbuild_version% == VS2017 ( - IF EXIST %msbuild_vs2017community% SET msbuild=%msbuild_vs2017community% - IF EXIST %msbuild_vs2017professional% SET msbuild=%msbuild_vs2017professional% - IF EXIST %msbuild_vs2017enterprise% SET msbuild=%msbuild_vs2017enterprise% -) - -:: VS2019 -SET msbuild_vs2019community="%programfiles(x86)%\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe" -SET msbuild_vs2019professional="%programfiles(x86)%\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\MSBuild.exe" -SET msbuild_vs2019enterprise="%programfiles(x86)%\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe" -IF %msbuild_version% == VS2019 ( - IF EXIST %msbuild_vs2019community% SET msbuild=%msbuild_vs2019community% - IF EXIST %msbuild_vs2019professional% SET msbuild=%msbuild_vs2019professional% - IF EXIST %msbuild_vs2019enterprise% SET msbuild=%msbuild_vs2019enterprise% -) - -SET project="%~p0\..\VS2010\zstd.sln" - -SET msbuild_params=/verbosity:minimal /nologo /t:Clean,Build /p:Platform=%msbuild_platform% /p:Configuration=%msbuild_configuration% -IF NOT "%msbuild_toolset%" == "" SET msbuild_params=%msbuild_params% /p:PlatformToolset=%msbuild_toolset% - -SET output=%~p0%bin -SET output="%output%/%msbuild_configuration%/%msbuild_platform%/" -SET msbuild_params=%msbuild_params% /p:OutDir=%output% - -echo ### Building %msbuild_version% project for %msbuild_configuration% %msbuild_platform% (%msbuild_toolset%)... -echo ### Build Params: %msbuild_params% - -%msbuild% %project% %msbuild_params% -IF ERRORLEVEL 1 EXIT /B 1 -echo # Success -echo # OutDir: %output% -echo # diff --git a/src/dependencies/zstd-1.5.4/build/cmake/.gitignore b/src/dependencies/zstd-1.5.4/build/cmake/.gitignore deleted file mode 100644 index 2e51e89..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -# cmake working directory -cmakeBuild - -# cmake artefacts -CMakeCache.txt -CMakeFiles -Makefile -cmake_install.cmake -cmake_uninstall.cmake -*.1 diff --git a/src/dependencies/zstd-1.5.4/build/cmake/CMakeLists.txt b/src/dependencies/zstd-1.5.4/build/cmake/CMakeLists.txt deleted file mode 100644 index 0bffc87..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/CMakeLists.txt +++ /dev/null @@ -1,212 +0,0 @@ -# ################################################################ -# Copyright (c) Meta Platforms, Inc. and affiliates. -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ################################################################ - -cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) - -# As of 2018-12-26 ZSTD has been validated to build with cmake version 3.13.2 new policies. -# Set and use the newest cmake policies that are validated to work -set(ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION "3") -set(ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION "13") #Policies never changed at PATCH level -if("${CMAKE_MAJOR_VERSION}" LESS 3) - set(ZSTD_CMAKE_POLICY_VERSION "${CMAKE_VERSION}") -elseif( "${ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION}" EQUAL "${CMAKE_MAJOR_VERSION}" AND - "${ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION}" GREATER "${CMAKE_MINOR_VERSION}") - set(ZSTD_CMAKE_POLICY_VERSION "${CMAKE_VERSION}") -else() - set(ZSTD_CMAKE_POLICY_VERSION "${ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION}.${ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION}.0") -endif() -cmake_policy(VERSION ${ZSTD_CMAKE_POLICY_VERSION}) - -set(CMAKE_BUILD_WITH_INSTALL_RPATH on) - -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") -set(ZSTD_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../..") -set(LIBRARY_DIR ${ZSTD_SOURCE_DIR}/lib) -# Parse version -include(GetZstdLibraryVersion) -GetZstdLibraryVersion(${LIBRARY_DIR}/zstd.h zstd_VERSION_MAJOR zstd_VERSION_MINOR zstd_VERSION_PATCH) - -if( CMAKE_MAJOR_VERSION LESS 3 ) - ## Provide cmake 3+ behavior for older versions of cmake - project(zstd) - set(PROJECT_VERSION_MAJOR ${zstd_VERSION_MAJOR}) - set(PROJECT_VERSION_MINOR ${zstd_VERSION_MINOR}) - set(PROJECT_VERSION_PATCH ${zstd_VERSION_PATCH}) - set(PROJECT_VERSION "${zstd_VERSION_MAJOR}.${zstd_VERSION_MINOR}.${zstd_VERSION_PATCH}") - enable_language(C) # Main library is in C - enable_language(ASM) # And ASM - enable_language(CXX) # Testing contributed code also utilizes CXX -else() - project(zstd - VERSION "${zstd_VERSION_MAJOR}.${zstd_VERSION_MINOR}.${zstd_VERSION_PATCH}" - LANGUAGES C # Main library is in C - ASM # And ASM - CXX # Testing contributed code also utilizes CXX - ) -endif() -message(STATUS "ZSTD VERSION: ${zstd_VERSION}") -set(zstd_HOMEPAGE_URL "https://facebook.github.io/zstd") -set(zstd_DESCRIPTION "Zstandard is a real-time compression algorithm, providing high compression ratios.") - -# Set a default build type if none was specified -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - message(STATUS "Setting build type to 'Release' as none was specified.") - set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) - # Set the possible values of build type for cmake-gui - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") -endif() - -include(GNUInstallDirs) - -#----------------------------------------------------------------------------- -# Add extra compilation flags -#----------------------------------------------------------------------------- -include(AddZstdCompilationFlags) -ADD_ZSTD_COMPILATION_FLAGS() - -# Always hide XXHash symbols -add_definitions(-DXXH_NAMESPACE=ZSTD_) - -#----------------------------------------------------------------------------- -# Installation variables -#----------------------------------------------------------------------------- -message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") -message(STATUS "CMAKE_INSTALL_LIBDIR: ${CMAKE_INSTALL_LIBDIR}") - -#----------------------------------------------------------------------------- -# Options -#----------------------------------------------------------------------------- - -# Legacy support -option(ZSTD_LEGACY_SUPPORT "LEGACY SUPPORT" ON) - -if (ZSTD_LEGACY_SUPPORT) - message(STATUS "ZSTD_LEGACY_SUPPORT defined!") - set(ZSTD_LEGACY_LEVEL 5 CACHE STRING "") - add_definitions(-DZSTD_LEGACY_SUPPORT=${ZSTD_LEGACY_LEVEL}) -else () - message(STATUS "ZSTD_LEGACY_SUPPORT not defined!") - add_definitions(-DZSTD_LEGACY_SUPPORT=0) -endif () - -if (ANDROID) - set(ZSTD_MULTITHREAD_SUPPORT_DEFAULT OFF) -else() - set(ZSTD_MULTITHREAD_SUPPORT_DEFAULT ON) -endif() - -# Multi-threading support -option(ZSTD_MULTITHREAD_SUPPORT "MULTITHREADING SUPPORT" ${ZSTD_MULTITHREAD_SUPPORT_DEFAULT}) - -if (ZSTD_MULTITHREAD_SUPPORT) - message(STATUS "ZSTD_MULTITHREAD_SUPPORT is enabled") -else () - message(STATUS "ZSTD_MULTITHREAD_SUPPORT is disabled") -endif () - -option(ZSTD_BUILD_PROGRAMS "BUILD PROGRAMS" ON) -option(ZSTD_BUILD_CONTRIB "BUILD CONTRIB" OFF) - -# Respect the conventional CMake option for enabling tests if it was specified on the first configure -if (BUILD_TESTING) - set(ZSTD_BUILD_TESTS_default ON) -else() - set(ZSTD_BUILD_TESTS_default OFF) -endif() -option(ZSTD_BUILD_TESTS "BUILD TESTS" ${ZSTD_BUILD_TESTS_default}) -if (MSVC) - option(ZSTD_USE_STATIC_RUNTIME "LINK TO STATIC RUN-TIME LIBRARIES" OFF) -endif () - -#----------------------------------------------------------------------------- -# External dependencies -#----------------------------------------------------------------------------- -if (ZSTD_MULTITHREAD_SUPPORT AND UNIX) - set(THREADS_PREFER_PTHREAD_FLAG ON) - find_package(Threads REQUIRED) - if(CMAKE_USE_PTHREADS_INIT) - set(THREADS_LIBS "${CMAKE_THREAD_LIBS_INIT}") - else() - message(SEND_ERROR "ZSTD currently does not support thread libraries other than pthreads") - endif() -endif () - -#----------------------------------------------------------------------------- -# Add source directories -#----------------------------------------------------------------------------- -add_subdirectory(lib) - -option(ZSTD_PROGRAMS_LINK_SHARED "PROGRAMS LINK SHARED" OFF) - -if (ZSTD_BUILD_PROGRAMS) - if (NOT ZSTD_BUILD_STATIC AND NOT ZSTD_PROGRAMS_LINK_SHARED) - message(SEND_ERROR "You need to build static library to build zstd CLI") - elseif(NOT ZSTD_BUILD_SHARED AND ZSTD_PROGRAMS_LINK_SHARED) - message(SEND_ERROR "You need to build shared library to build zstd CLI") - endif () - - add_subdirectory(programs) -endif () - -if (ZSTD_BUILD_TESTS) - enable_testing() - if (NOT ZSTD_BUILD_STATIC) - message(SEND_ERROR "You need to build static library to build tests") - endif () - - add_subdirectory(tests) -endif () - -if (ZSTD_BUILD_CONTRIB) - add_subdirectory(contrib) -endif () - -#----------------------------------------------------------------------------- -# Add clean-all target -#----------------------------------------------------------------------------- -add_custom_target(clean-all - COMMAND ${CMAKE_BUILD_TOOL} clean - COMMAND rm -rf ${CMAKE_BINARY_DIR}/ -) - -#----------------------------------------------------------------------------- -# Generate Package Config files -# -# This section is based on the boiler plate code from: -# https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#creating-packages -#----------------------------------------------------------------------------- -include(CMakePackageConfigHelpers) -write_basic_package_version_file( - "${CMAKE_CURRENT_BINARY_DIR}/zstdConfigVersion.cmake" - VERSION ${zstd_VERSION} - COMPATIBILITY SameMajorVersion - ) - -# A Package Config file that works from the build directory -export(EXPORT zstdExports - FILE "${CMAKE_CURRENT_BINARY_DIR}/zstdTargets.cmake" - NAMESPACE zstd:: - ) -configure_file(zstdConfig.cmake - "${CMAKE_CURRENT_BINARY_DIR}/zstdConfig.cmake" - COPYONLY - ) - -# A Package Config file that works from the installation directory -set(ConfigPackageLocation ${CMAKE_INSTALL_LIBDIR}/cmake/zstd) -install(EXPORT zstdExports - FILE zstdTargets.cmake - NAMESPACE zstd:: - DESTINATION ${ConfigPackageLocation} - ) -install(FILES - zstdConfig.cmake - "${CMAKE_CURRENT_BINARY_DIR}/zstdConfigVersion.cmake" - DESTINATION ${ConfigPackageLocation} - ) diff --git a/src/dependencies/zstd-1.5.4/build/cmake/CMakeModules/AddZstdCompilationFlags.cmake b/src/dependencies/zstd-1.5.4/build/cmake/CMakeModules/AddZstdCompilationFlags.cmake deleted file mode 100644 index 0265349..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/CMakeModules/AddZstdCompilationFlags.cmake +++ /dev/null @@ -1,99 +0,0 @@ -include(CheckCXXCompilerFlag) -include(CheckCCompilerFlag) -include(CheckLinkerFlag) - -function(EnableCompilerFlag _flag _C _CXX _LD) - string(REGEX REPLACE "\\+" "PLUS" varname "${_flag}") - string(REGEX REPLACE "[^A-Za-z0-9]+" "_" varname "${varname}") - string(REGEX REPLACE "^_+" "" varname "${varname}") - string(TOUPPER "${varname}" varname) - if (_C) - CHECK_C_COMPILER_FLAG(${_flag} C_FLAG_${varname}) - if (C_FLAG_${varname}) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_flag}" PARENT_SCOPE) - endif () - endif () - if (_CXX) - CHECK_CXX_COMPILER_FLAG(${_flag} CXX_FLAG_${varname}) - if (CXX_FLAG_${varname}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flag}" PARENT_SCOPE) - endif () - endif () - if (_LD) - CHECK_LINKER_FLAG(C ${_flag} LD_FLAG_${varname}) - if (LD_FLAG_${varname}) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${_flag}" PARENT_SCOPE) - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${_flag}" PARENT_SCOPE) - endif () - endif () -endfunction() - -macro(ADD_ZSTD_COMPILATION_FLAGS) - if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang" OR MINGW) #Not only UNIX but also WIN32 for MinGW - # It's possible to select the exact standard used for compilation. - # It's not necessary, but can be employed for specific purposes. - # Note that zstd source code is compatible with both C++98 and above - # and C-gnu90 (c90 + long long + variadic macros ) and above - # EnableCompilerFlag("-std=c++11" false true) # Set C++ compilation to c++11 standard - # EnableCompilerFlag("-std=c99" true false) # Set C compiation to c99 standard - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND MSVC) - # clang-cl normally maps -Wall to -Weverything. - EnableCompilerFlag("/clang:-Wall" true true false) - else () - EnableCompilerFlag("-Wall" true true false) - endif () - EnableCompilerFlag("-Wextra" true true false) - EnableCompilerFlag("-Wundef" true true false) - EnableCompilerFlag("-Wshadow" true true false) - EnableCompilerFlag("-Wcast-align" true true false) - EnableCompilerFlag("-Wcast-qual" true true false) - EnableCompilerFlag("-Wstrict-prototypes" true false false) - # Enable asserts in Debug mode - if (CMAKE_BUILD_TYPE MATCHES "Debug") - EnableCompilerFlag("-DDEBUGLEVEL=1" true true false) - endif () - # Add noexecstack flags - # LDFLAGS - EnableCompilerFlag("-z noexecstack" false false true) - # CFLAGS & CXXFLAGS - EnableCompilerFlag("-Qunused-arguments" true true false) - EnableCompilerFlag("-Wa,--noexecstack" true true false) - elseif (MSVC) # Add specific compilation flags for Windows Visual - - set(ACTIVATE_MULTITHREADED_COMPILATION "ON" CACHE BOOL "activate multi-threaded compilation (/MP flag)") - if (CMAKE_GENERATOR MATCHES "Visual Studio" AND ACTIVATE_MULTITHREADED_COMPILATION) - EnableCompilerFlag("/MP" true true false) - endif () - - # UNICODE SUPPORT - EnableCompilerFlag("/D_UNICODE" true true false) - EnableCompilerFlag("/DUNICODE" true true false) - # Enable asserts in Debug mode - if (CMAKE_BUILD_TYPE MATCHES "Debug") - EnableCompilerFlag("/DDEBUGLEVEL=1" true true false) - endif () - endif () - - # Remove duplicates compilation flags - foreach (flag_var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE - CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO - CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE - CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) - if( ${flag_var} ) - separate_arguments(${flag_var}) - string(REPLACE ";" " " ${flag_var} "${${flag_var}}") - endif() - endforeach () - - if (MSVC AND ZSTD_USE_STATIC_RUNTIME) - foreach (flag_var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE - CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO - CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE - CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) - if ( ${flag_var} ) - string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") - endif() - endforeach () - endif () - -endmacro() diff --git a/src/dependencies/zstd-1.5.4/build/cmake/CMakeModules/FindLibLZ4.cmake b/src/dependencies/zstd-1.5.4/build/cmake/CMakeModules/FindLibLZ4.cmake deleted file mode 100644 index d0fac06..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/CMakeModules/FindLibLZ4.cmake +++ /dev/null @@ -1,49 +0,0 @@ -# Find LibLZ4 -# -# Find LibLZ4 headers and library -# -# Result Variables -# -# LIBLZ4_FOUND - True if lz4 is found -# LIBLZ4_INCLUDE_DIRS - lz4 headers directories -# LIBLZ4_LIBRARIES - lz4 libraries -# LIBLZ4_VERSION_MAJOR - The major version of lz4 -# LIBLZ4_VERSION_MINOR - The minor version of lz4 -# LIBLZ4_VERSION_RELEASE - The release version of lz4 -# LIBLZ4_VERSION_STRING - version number string (e.g. 1.8.3) -# -# Hints -# -# Set ``LZ4_ROOT_DIR`` to the directory of lz4.h and lz4 library - -set(_LIBLZ4_ROOT_HINTS - ENV LZ4_ROOT_DIR) - -find_path( LIBLZ4_INCLUDE_DIR lz4.h - HINTS ${_LIBLZ4_ROOT_HINTS}) -find_library( LIBLZ4_LIBRARY NAMES lz4 liblz4 liblz4_static - HINTS ${_LIBLZ4_ROOT_HINTS}) - -if(LIBLZ4_INCLUDE_DIR) - file(STRINGS "${LIBLZ4_INCLUDE_DIR}/lz4.h" LIBLZ4_HEADER_CONTENT REGEX "#define LZ4_VERSION_[A-Z]+ +[0-9]+") - - string(REGEX REPLACE ".*#define LZ4_VERSION_MAJOR +([0-9]+).*" "\\1" LIBLZ4_VERSION_MAJOR "${LIBLZ4_HEADER_CONTENT}") - string(REGEX REPLACE ".*#define LZ4_VERSION_MINOR +([0-9]+).*" "\\1" LIBLZ4_VERSION_MINOR "${LIBLZ4_HEADER_CONTENT}") - string(REGEX REPLACE ".*#define LZ4_VERSION_RELEASE +([0-9]+).*" "\\1" LIBLZ4_VERSION_RELEASE "${LIBLZ4_HEADER_CONTENT}") - - set(LIBLZ4_VERSION_STRING "${LIBLZ4_VERSION_MAJOR}.${LIBLZ4_VERSION_MINOR}.${LIBLZ4_VERSION_RELEASE}") - unset(LIBLZ4_HEADER_CONTENT) -endif() - -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibLZ4 REQUIRED_VARS LIBLZ4_INCLUDE_DIR - LIBLZ4_LIBRARY - VERSION_VAR LIBLZ4_VERSION_STRING - FAIL_MESSAGE "Could NOT find LZ4, try to set the paths to lz4.h and lz4 library in environment variable LZ4_ROOT_DIR") - -if (LIBLZ4_FOUND) - set(LIBLZ4_LIBRARIES ${LIBLZ4_LIBRARY}) - set(LIBLZ4_INCLUDE_DIRS ${LIBLZ4_INCLUDE_DIR}) -endif () - -mark_as_advanced( LIBLZ4_INCLUDE_DIR LIBLZ4_LIBRARY ) diff --git a/src/dependencies/zstd-1.5.4/build/cmake/CMakeModules/GetZstdLibraryVersion.cmake b/src/dependencies/zstd-1.5.4/build/cmake/CMakeModules/GetZstdLibraryVersion.cmake deleted file mode 100644 index e8ed606..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/CMakeModules/GetZstdLibraryVersion.cmake +++ /dev/null @@ -1,10 +0,0 @@ -function(GetZstdLibraryVersion _header _major _minor _patch) - # Read file content - file(READ ${_header} CONTENT) - - string(REGEX MATCH ".*define ZSTD_VERSION_MAJOR *([0-9]+).*define ZSTD_VERSION_MINOR *([0-9]+).*define ZSTD_VERSION_RELEASE *([0-9]+)" VERSION_REGEX "${CONTENT}") - set(${_major} ${CMAKE_MATCH_1} PARENT_SCOPE) - set(${_minor} ${CMAKE_MATCH_2} PARENT_SCOPE) - set(${_patch} ${CMAKE_MATCH_3} PARENT_SCOPE) -endfunction() - diff --git a/src/dependencies/zstd-1.5.4/build/cmake/CMakeModules/JoinPaths.cmake b/src/dependencies/zstd-1.5.4/build/cmake/CMakeModules/JoinPaths.cmake deleted file mode 100644 index c68d91b..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/CMakeModules/JoinPaths.cmake +++ /dev/null @@ -1,23 +0,0 @@ -# This module provides function for joining paths -# known from most languages -# -# SPDX-License-Identifier: (MIT OR CC0-1.0) -# Copyright 2020 Jan Tojnar -# https://github.com/jtojnar/cmake-snips -# -# Modelled after Python’s os.path.join -# https://docs.python.org/3.7/library/os.path.html#os.path.join -# Windows not supported -function(join_paths joined_path first_path_segment) - set(temp_path "${first_path_segment}") - foreach(current_segment IN LISTS ARGN) - if(NOT ("${current_segment}" STREQUAL "")) - if(IS_ABSOLUTE "${current_segment}") - set(temp_path "${current_segment}") - else() - set(temp_path "${temp_path}/${current_segment}") - endif() - endif() - endforeach() - set(${joined_path} "${temp_path}" PARENT_SCOPE) -endfunction() diff --git a/src/dependencies/zstd-1.5.4/build/cmake/README.md b/src/dependencies/zstd-1.5.4/build/cmake/README.md deleted file mode 100644 index a460dd1..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/README.md +++ /dev/null @@ -1,104 +0,0 @@ -# Cmake contributions - -Contributions to the cmake build configurations are welcome. Please -use case sensitivity that matches modern (i.e. cmake version 2.6 and above) -conventions of using lower-case for commands, and upper-case for -variables. - -## How to build - -As cmake doesn't support command like `cmake clean`, it's recommended to perform an "out of source build". -To do this, you can create a new directory and build in it: -```sh -cd build/cmake -mkdir builddir -cd builddir -cmake .. -make -``` -Then you can clean all cmake caches by simply delete the new directory: -```sh -rm -rf build/cmake/builddir -``` - -And of course, you can directly build in build/cmake: -```sh -cd build/cmake -cmake -make -``` - -To show cmake build options, you can: -```sh -cd build/cmake/builddir -cmake -LH .. -``` - -Bool options can be set to `ON/OFF` with `-D[option]=[ON/OFF]`. You can configure cmake options like this: -```sh -cd build/cmake/builddir -cmake -DZSTD_BUILD_TESTS=ON -DZSTD_LEGACY_SUPPORT=OFF .. -make -``` - -### referring -[Looking for a 'cmake clean' command to clear up CMake output](https://stackoverflow.com/questions/9680420/looking-for-a-cmake-clean-command-to-clear-up-cmake-output) - -## CMake Style Recommendations - -### Indent all code correctly, i.e. the body of - - * if/else/endif - * foreach/endforeach - * while/endwhile - * macro/endmacro - * function/endfunction - -Use spaces for indenting, 2, 3 or 4 spaces preferably. Use the same amount of -spaces for indenting as is used in the rest of the file. Do not use tabs. - -### Upper/lower casing - -Most important: use consistent upper- or lowercasing within one file ! - -In general, the all-lowercase style is preferred. - -So, this is recommended: - -``` -add_executable(foo foo.c) -``` - -These forms are discouraged - -``` -ADD_EXECUTABLE(bar bar.c) -Add_Executable(hello hello.c) -aDd_ExEcUtAbLe(blub blub.c) -``` - -### End commands -To make the code easier to read, use empty commands for endforeach(), endif(), -endfunction(), endmacro() and endwhile(). Also, use empty else() commands. - -For example, do this: - -``` -if(FOOVAR) - some_command(...) -else() - another_command(...) -endif() -``` - -and not this: - -``` -if(BARVAR) - some_other_command(...) -endif(BARVAR) -``` - -### Other resources for best practices - -https://cmake.org/cmake/help/latest/manual/cmake-developer.7.html#modules diff --git a/src/dependencies/zstd-1.5.4/build/cmake/contrib/CMakeLists.txt b/src/dependencies/zstd-1.5.4/build/cmake/contrib/CMakeLists.txt deleted file mode 100644 index 8df2a17..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/contrib/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -# ################################################################ -# Copyright (c) Meta Platforms, Inc. and affiliates. -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ################################################################ - -project(contrib) - -add_subdirectory(pzstd) -add_subdirectory(gen_html) diff --git a/src/dependencies/zstd-1.5.4/build/cmake/contrib/gen_html/CMakeLists.txt b/src/dependencies/zstd-1.5.4/build/cmake/contrib/gen_html/CMakeLists.txt deleted file mode 100644 index d1ff6c6..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/contrib/gen_html/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -# ################################################################ -# Copyright (c) Meta Platforms, Inc. and affiliates. -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ################################################################ - -project(gen_html) -include(GetZstdLibraryVersion) - -set(CMAKE_INCLUDE_CURRENT_DIR TRUE) - -# Define programs directory, where sources and header files are located -set(LIBRARY_DIR ${ZSTD_SOURCE_DIR}/lib) -set(PROGRAMS_DIR ${ZSTD_SOURCE_DIR}/programs) -set(GENHTML_DIR ${ZSTD_SOURCE_DIR}/contrib/gen_html) -set(GENHTML_BINARY ${PROJECT_BINARY_DIR}/gen_html${CMAKE_EXECUTABLE_SUFFIX}) -include_directories(${PROGRAMS_DIR} ${LIBRARY_DIR} ${LIBRARY_DIR}/common ${GENHTML_DIR}) - -add_executable(gen_html ${GENHTML_DIR}/gen_html.cpp) - -GetZstdLibraryVersion(${LIBRARY_DIR}/zstd.h VMAJOR VMINOR VRELEASE) -set(LIBVERSION "${VMAJOR}.${VMINOR}.${VRELEASE}") -add_custom_target(zstd_manual.html ALL - ${GENHTML_BINARY} "${LIBVERSION}" "${LIBRARY_DIR}/zstd.h" "${PROJECT_BINARY_DIR}/zstd_manual.html" - DEPENDS gen_html COMMENT "Update zstd manual") - -install(FILES "${PROJECT_BINARY_DIR}/zstd_manual.html" DESTINATION "${CMAKE_INSTALL_DOCDIR}") diff --git a/src/dependencies/zstd-1.5.4/build/cmake/contrib/pzstd/CMakeLists.txt b/src/dependencies/zstd-1.5.4/build/cmake/contrib/pzstd/CMakeLists.txt deleted file mode 100644 index f7098fa..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/contrib/pzstd/CMakeLists.txt +++ /dev/null @@ -1,38 +0,0 @@ -# ################################################################ -# Copyright (c) Meta Platforms, Inc. and affiliates. -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ################################################################ - -project(pzstd) - -set(CMAKE_INCLUDE_CURRENT_DIR TRUE) - -# Define programs directory, where sources and header files are located -set(LIBRARY_DIR ${ZSTD_SOURCE_DIR}/lib) -set(PROGRAMS_DIR ${ZSTD_SOURCE_DIR}/programs) -set(PZSTD_DIR ${ZSTD_SOURCE_DIR}/contrib/pzstd) -include_directories(${PROGRAMS_DIR} ${LIBRARY_DIR} ${LIBRARY_DIR}/common ${PZSTD_DIR}) - -add_executable(pzstd ${PROGRAMS_DIR}/util.c ${PZSTD_DIR}/main.cpp ${PZSTD_DIR}/Options.cpp ${PZSTD_DIR}/Pzstd.cpp ${PZSTD_DIR}/SkippableFrame.cpp) -set_property(TARGET pzstd APPEND PROPERTY COMPILE_DEFINITIONS "NDEBUG") -set_property(TARGET pzstd APPEND PROPERTY COMPILE_OPTIONS "-Wno-shadow") - -if (ZSTD_BUILD_SHARED) - set(ZSTD_LIB libzstd_shared) -else() - set(ZSTD_LIB libzstd_static) -endif() - -set(THREADS_PREFER_PTHREAD_FLAG ON) -find_package(Threads REQUIRED) -if (CMAKE_USE_PTHREADS_INIT) - target_link_libraries(pzstd ${ZSTD_LIB} ${CMAKE_THREAD_LIBS_INIT}) -else() - message(SEND_ERROR "ZSTD currently does not support thread libraries other than pthreads") -endif() - -install(TARGETS pzstd RUNTIME DESTINATION "bin") diff --git a/src/dependencies/zstd-1.5.4/build/cmake/lib/.gitignore b/src/dependencies/zstd-1.5.4/build/cmake/lib/.gitignore deleted file mode 100644 index a4444c8..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/lib/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# cmake build artefact -libzstd.pc diff --git a/src/dependencies/zstd-1.5.4/build/cmake/lib/CMakeLists.txt b/src/dependencies/zstd-1.5.4/build/cmake/lib/CMakeLists.txt deleted file mode 100644 index 3034958..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/lib/CMakeLists.txt +++ /dev/null @@ -1,181 +0,0 @@ -# ################################################################ -# Copyright (c) Meta Platforms, Inc. and affiliates. -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ################################################################ - -project(libzstd C ASM) - -set(CMAKE_INCLUDE_CURRENT_DIR TRUE) -option(ZSTD_BUILD_STATIC "BUILD STATIC LIBRARIES" ON) -option(ZSTD_BUILD_SHARED "BUILD SHARED LIBRARIES" ON) - -if(NOT ZSTD_BUILD_SHARED AND NOT ZSTD_BUILD_STATIC) - message(SEND_ERROR "You need to build at least one flavor of libzstd") -endif() - -# Define library directory, where sources and header files are located -include_directories(${LIBRARY_DIR} ${LIBRARY_DIR}/common) - -file(GLOB CommonSources ${LIBRARY_DIR}/common/*.c) -file(GLOB CompressSources ${LIBRARY_DIR}/compress/*.c) -if (MSVC) - file(GLOB DecompressSources ${LIBRARY_DIR}/decompress/*.c) - add_compile_options(-DZSTD_DISABLE_ASM) -else () - file(GLOB DecompressSources ${LIBRARY_DIR}/decompress/*.c ${LIBRARY_DIR}/decompress/*.S) -endif () -file(GLOB DictBuilderSources ${LIBRARY_DIR}/dictBuilder/*.c) - -set(Sources - ${CommonSources} - ${CompressSources} - ${DecompressSources} - ${DictBuilderSources}) - -file(GLOB CommonHeaders ${LIBRARY_DIR}/common/*.h) -file(GLOB CompressHeaders ${LIBRARY_DIR}/compress/*.h) -file(GLOB DecompressHeaders ${LIBRARY_DIR}/decompress/*.h) -file(GLOB DictBuilderHeaders ${LIBRARY_DIR}/dictBuilder/*.h) - -set(Headers - ${LIBRARY_DIR}/zstd.h - ${CommonHeaders} - ${CompressHeaders} - ${DecompressHeaders} - ${DictBuilderHeaders}) - -if (ZSTD_LEGACY_SUPPORT) - set(LIBRARY_LEGACY_DIR ${LIBRARY_DIR}/legacy) - include_directories(${LIBRARY_LEGACY_DIR}) - - set(Sources ${Sources} - ${LIBRARY_LEGACY_DIR}/zstd_v01.c - ${LIBRARY_LEGACY_DIR}/zstd_v02.c - ${LIBRARY_LEGACY_DIR}/zstd_v03.c - ${LIBRARY_LEGACY_DIR}/zstd_v04.c - ${LIBRARY_LEGACY_DIR}/zstd_v05.c - ${LIBRARY_LEGACY_DIR}/zstd_v06.c - ${LIBRARY_LEGACY_DIR}/zstd_v07.c) - - set(Headers ${Headers} - ${LIBRARY_LEGACY_DIR}/zstd_legacy.h - ${LIBRARY_LEGACY_DIR}/zstd_v01.h - ${LIBRARY_LEGACY_DIR}/zstd_v02.h - ${LIBRARY_LEGACY_DIR}/zstd_v03.h - ${LIBRARY_LEGACY_DIR}/zstd_v04.h - ${LIBRARY_LEGACY_DIR}/zstd_v05.h - ${LIBRARY_LEGACY_DIR}/zstd_v06.h - ${LIBRARY_LEGACY_DIR}/zstd_v07.h) -endif () - -if (MSVC) - set(MSVC_RESOURCE_DIR ${ZSTD_SOURCE_DIR}/build/VS2010/libzstd-dll) - set(PlatformDependResources ${MSVC_RESOURCE_DIR}/libzstd-dll.rc) -endif () - -# Explicitly set the language to C for all files, including ASM files. -# Our assembly expects to be compiled by a C compiler, and is only enabled for -# __GNUC__ compatible compilers. Otherwise all the ASM code is disabled by -# macros. -set_source_files_properties(${Sources} PROPERTIES LANGUAGE C) - -# Split project to static and shared libraries build -set(library_targets) -if (ZSTD_BUILD_SHARED) - add_library(libzstd_shared SHARED ${Sources} ${Headers} ${PlatformDependResources}) - list(APPEND library_targets libzstd_shared) - if (ZSTD_MULTITHREAD_SUPPORT) - set_property(TARGET libzstd_shared APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_MULTITHREAD") - if (UNIX) - target_link_libraries(libzstd_shared ${THREADS_LIBS}) - endif () - endif() -endif () -if (ZSTD_BUILD_STATIC) - add_library(libzstd_static STATIC ${Sources} ${Headers}) - list(APPEND library_targets libzstd_static) - if (ZSTD_MULTITHREAD_SUPPORT) - set_property(TARGET libzstd_static APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_MULTITHREAD") - if (UNIX) - target_link_libraries(libzstd_static ${THREADS_LIBS}) - endif () - endif () -endif () - -# Add specific compile definitions for MSVC project -if (MSVC) - if (ZSTD_BUILD_SHARED) - set_property(TARGET libzstd_shared APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;_CONSOLE;_CRT_SECURE_NO_WARNINGS") - endif () - if (ZSTD_BUILD_STATIC) - set_property(TARGET libzstd_static APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_HEAPMODE=0;_CRT_SECURE_NO_WARNINGS") - endif () -endif () - -# With MSVC static library needs to be renamed to avoid conflict with import library -if (MSVC OR (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT MINGW)) - set(STATIC_LIBRARY_BASE_NAME zstd_static) -else () - set(STATIC_LIBRARY_BASE_NAME zstd) -endif () - -# Define static and shared library names -if (ZSTD_BUILD_SHARED) - set_target_properties( - libzstd_shared - PROPERTIES - OUTPUT_NAME zstd - VERSION ${zstd_VERSION_MAJOR}.${zstd_VERSION_MINOR}.${zstd_VERSION_PATCH} - SOVERSION ${zstd_VERSION_MAJOR}) -endif () - -if (ZSTD_BUILD_STATIC) - set_target_properties( - libzstd_static - PROPERTIES - POSITION_INDEPENDENT_CODE On - OUTPUT_NAME ${STATIC_LIBRARY_BASE_NAME}) -endif () - -# pkg-config -include(JoinPaths) # can be replaced by cmake_path(APPEND) in CMake 3.20 -set(PREFIX "${CMAKE_INSTALL_PREFIX}") -set(EXEC_PREFIX "\${prefix}") -join_paths(LIBDIR "\${exec_prefix}" "${CMAKE_INSTALL_LIBDIR}") -join_paths(INCLUDEDIR "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}") -set(LIBS_PRIVATE "${THREADS_LIBS}") -set(VERSION "${zstd_VERSION}") - -configure_file("${LIBRARY_DIR}/libzstd.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/libzstd.pc" @ONLY) -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libzstd.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") - -# install target -install(FILES - "${LIBRARY_DIR}/zstd.h" - "${LIBRARY_DIR}/zdict.h" - "${LIBRARY_DIR}/zstd_errors.h" - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") - -install(TARGETS ${library_targets} - EXPORT zstdExports - INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" - BUNDLE DESTINATION "${CMAKE_INSTALL_BINDIR}" - ) - -# uninstall target -if (NOT TARGET uninstall) - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" - IMMEDIATE @ONLY) - - add_custom_target(uninstall - COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) -endif () diff --git a/src/dependencies/zstd-1.5.4/build/cmake/lib/cmake_uninstall.cmake.in b/src/dependencies/zstd-1.5.4/build/cmake/lib/cmake_uninstall.cmake.in deleted file mode 100644 index 9f1d045..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/lib/cmake_uninstall.cmake.in +++ /dev/null @@ -1,22 +0,0 @@ - -if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") - message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") -endif() - -file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) -string(REGEX REPLACE "\n" ";" files "${files}") -foreach(file ${files}) - message(STATUS "Uninstalling $ENV{DESTDIR}${file}") - if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") - exec_program( - "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" - OUTPUT_VARIABLE rm_out - RETURN_VALUE rm_retval - ) - if(NOT "${rm_retval}" STREQUAL 0) - message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") - endif() - else() - message(STATUS "File $ENV{DESTDIR}${file} does not exist.") - endif() -endforeach() diff --git a/src/dependencies/zstd-1.5.4/build/cmake/programs/.gitignore b/src/dependencies/zstd-1.5.4/build/cmake/programs/.gitignore deleted file mode 100644 index ae3a8a3..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/programs/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# produced by make -zstd -zstd-frugal -unzstd -zstdcat diff --git a/src/dependencies/zstd-1.5.4/build/cmake/programs/CMakeLists.txt b/src/dependencies/zstd-1.5.4/build/cmake/programs/CMakeLists.txt deleted file mode 100644 index 58d998e..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/programs/CMakeLists.txt +++ /dev/null @@ -1,137 +0,0 @@ -# ################################################################ -# Copyright (c) Meta Platforms, Inc. and affiliates. -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ################################################################ - -project(programs C) - -set(CMAKE_INCLUDE_CURRENT_DIR TRUE) - -# Define programs directory, where sources and header files are located -set(LIBRARY_DIR ${ZSTD_SOURCE_DIR}/lib) -set(PROGRAMS_DIR ${ZSTD_SOURCE_DIR}/programs) -include_directories(${PROGRAMS_DIR} ${LIBRARY_DIR} ${LIBRARY_DIR}/common ${LIBRARY_DIR}/compress ${LIBRARY_DIR}/dictBuilder) - -if (ZSTD_LEGACY_SUPPORT) - set(PROGRAMS_LEGACY_DIR ${PROGRAMS_DIR}/legacy) - include_directories(${PROGRAMS_LEGACY_DIR} ${LIBRARY_DIR}/legacy) -endif () - -if (ZSTD_PROGRAMS_LINK_SHARED) - set(PROGRAMS_ZSTD_LINK_TARGET libzstd_shared) -else () - set(PROGRAMS_ZSTD_LINK_TARGET libzstd_static) -endif () - -if (MSVC) - set(MSVC_RESOURCE_DIR ${ZSTD_SOURCE_DIR}/build/VS2010/zstd) - set(PlatformDependResources ${MSVC_RESOURCE_DIR}/zstd.rc) -endif () - -add_executable(zstd ${PROGRAMS_DIR}/zstdcli.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${PROGRAMS_DIR}/fileio.c ${PROGRAMS_DIR}/fileio_asyncio.c ${PROGRAMS_DIR}/benchfn.c ${PROGRAMS_DIR}/benchzstd.c ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/dibio.c ${PROGRAMS_DIR}/zstdcli_trace.c ${PlatformDependResources}) -target_link_libraries(zstd ${PROGRAMS_ZSTD_LINK_TARGET}) -if (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") - target_link_libraries(zstd rt) -endif () -install(TARGETS zstd - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" - BUNDLE DESTINATION "${CMAKE_INSTALL_BINDIR}") - -if (UNIX) - add_custom_target(zstdcat ALL ${CMAKE_COMMAND} -E create_symlink zstd zstdcat DEPENDS zstd COMMENT "Creating zstdcat symlink") - add_custom_target(unzstd ALL ${CMAKE_COMMAND} -E create_symlink zstd unzstd DEPENDS zstd COMMENT "Creating unzstd symlink") - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/zstdcat DESTINATION "${CMAKE_INSTALL_BINDIR}") - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/unzstd DESTINATION "${CMAKE_INSTALL_BINDIR}") - install(PROGRAMS ${PROGRAMS_DIR}/zstdgrep DESTINATION "${CMAKE_INSTALL_BINDIR}") - install(PROGRAMS ${PROGRAMS_DIR}/zstdless DESTINATION "${CMAKE_INSTALL_BINDIR}") - - add_custom_target(zstd.1 ALL - ${CMAKE_COMMAND} -E copy ${PROGRAMS_DIR}/zstd.1 . - COMMENT "Copying manpage zstd.1") - add_custom_target(zstdgrep.1 ALL - ${CMAKE_COMMAND} -E copy ${PROGRAMS_DIR}/zstdgrep.1 . - COMMENT "Copying manpage zstdgrep.1") - add_custom_target(zstdless.1 ALL - ${CMAKE_COMMAND} -E copy ${PROGRAMS_DIR}/zstdless.1 . - COMMENT "Copying manpage zstdless.1") - add_custom_target(zstdcat.1 ALL ${CMAKE_COMMAND} -E create_symlink zstd.1 zstdcat.1 DEPENDS zstd.1 COMMENT "Creating zstdcat.1 symlink") - add_custom_target(unzstd.1 ALL ${CMAKE_COMMAND} -E create_symlink zstd.1 unzstd.1 DEPENDS zstd.1 COMMENT "Creating unzstd.1 symlink") - - # Define MAN_INSTALL_DIR if necessary - if (MAN_INSTALL_DIR) - else () - set(MAN_INSTALL_DIR ${CMAKE_INSTALL_MANDIR}/man1) - endif () - - install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/zstd.1 - ${CMAKE_CURRENT_BINARY_DIR}/zstdcat.1 - ${CMAKE_CURRENT_BINARY_DIR}/unzstd.1 - ${CMAKE_CURRENT_BINARY_DIR}/zstdgrep.1 - ${CMAKE_CURRENT_BINARY_DIR}/zstdless.1 - DESTINATION "${MAN_INSTALL_DIR}") - - add_executable(zstd-frugal ${PROGRAMS_DIR}/zstdcli.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${PROGRAMS_DIR}/fileio.c ${PROGRAMS_DIR}/fileio_asyncio.c) - target_link_libraries(zstd-frugal ${PROGRAMS_ZSTD_LINK_TARGET}) - set_property(TARGET zstd-frugal APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_NOBENCH;ZSTD_NODICT;ZSTD_NOTRACE") -endif () - -# Add multi-threading support definitions - -if (ZSTD_MULTITHREAD_SUPPORT) - set_property(TARGET zstd APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_MULTITHREAD") - - if (UNIX) - target_link_libraries(zstd ${THREADS_LIBS}) - - add_custom_target(zstdmt ALL ${CMAKE_COMMAND} -E create_symlink zstd zstdmt DEPENDS zstd COMMENT "Creating zstdmt symlink") - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/zstdmt DESTINATION "${CMAKE_INSTALL_BINDIR}") - endif () -endif () - -option(ZSTD_ZLIB_SUPPORT "ZLIB SUPPORT" OFF) -option(ZSTD_LZMA_SUPPORT "LZMA SUPPORT" OFF) -option(ZSTD_LZ4_SUPPORT "LZ4 SUPPORT" OFF) - -# Add gzip support -if (ZSTD_ZLIB_SUPPORT) - find_package(ZLIB REQUIRED) - - if (ZLIB_FOUND) - include_directories(${ZLIB_INCLUDE_DIRS}) - target_link_libraries(zstd ${ZLIB_LIBRARIES}) - set_property(TARGET zstd APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_GZCOMPRESS;ZSTD_GZDECOMPRESS") - else () - message(SEND_ERROR "zlib library is missing") - endif () -endif () - -# Add lzma support -if (ZSTD_LZMA_SUPPORT) - find_package(LibLZMA REQUIRED) - - if (LIBLZMA_FOUND) - include_directories(${LIBLZMA_INCLUDE_DIRS}) - target_link_libraries(zstd ${LIBLZMA_LIBRARIES}) - set_property(TARGET zstd APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_LZMACOMPRESS;ZSTD_LZMADECOMPRESS") - else () - message(SEND_ERROR "lzma library is missing") - endif () -endif () - -# Add lz4 support -if (ZSTD_LZ4_SUPPORT) - find_package(LibLZ4 REQUIRED) - - if (LIBLZ4_FOUND) - include_directories(${LIBLZ4_INCLUDE_DIRS}) - target_link_libraries(zstd ${LIBLZ4_LIBRARIES}) - set_property(TARGET zstd APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_LZ4COMPRESS;ZSTD_LZ4DECOMPRESS") - else () - message(SEND_ERROR "lz4 library is missing") - endif () -endif () diff --git a/src/dependencies/zstd-1.5.4/build/cmake/tests/.gitignore b/src/dependencies/zstd-1.5.4/build/cmake/tests/.gitignore deleted file mode 100644 index ca2947f..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/tests/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# produced by make -datagen -fullbench -fuzzer -paramgrill - diff --git a/src/dependencies/zstd-1.5.4/build/cmake/tests/CMakeLists.txt b/src/dependencies/zstd-1.5.4/build/cmake/tests/CMakeLists.txt deleted file mode 100644 index 250f050..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/tests/CMakeLists.txt +++ /dev/null @@ -1,118 +0,0 @@ -# ################################################################ -# zstd - Makefile -# Copyright (c) Meta Platforms, Inc. and affiliates. -# All rights reserved. -# -# BSD license -# -# 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 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 : https://facebook.github.io/zstd/ -# ################################################################ - -project(tests) - -# name: Cache variable name. The value is expected to be a semicolon-separated -# list of command line flags -# default_value: Value to initialize the option with. Can be space separated. -function(AddTestFlagsOption name default_value doc) - string(STRIP "${default_value}" default_value) - string(REGEX REPLACE " +" ";" default_value "${default_value}") - set(${name} ${default_value} CACHE STRING "${doc}") - mark_as_advanced(${name}) -endfunction() - -set(CMAKE_INCLUDE_CURRENT_DIR TRUE) - -# Define programs directory, where sources and header files are located -set(LIBRARY_DIR ${ZSTD_SOURCE_DIR}/lib) -set(PROGRAMS_DIR ${ZSTD_SOURCE_DIR}/programs) -set(TESTS_DIR ${ZSTD_SOURCE_DIR}/tests) -include_directories(${TESTS_DIR} ${PROGRAMS_DIR} ${LIBRARY_DIR} ${LIBRARY_DIR}/common ${LIBRARY_DIR}/compress ${LIBRARY_DIR}/dictBuilder) - -add_executable(datagen ${PROGRAMS_DIR}/datagen.c ${TESTS_DIR}/datagencli.c) -target_link_libraries(datagen libzstd_static) - -# -# fullbench -# -add_executable(fullbench ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${PROGRAMS_DIR}/benchfn.c ${PROGRAMS_DIR}/benchzstd.c ${TESTS_DIR}/fullbench.c) -if (NOT MSVC) - target_compile_options(fullbench PRIVATE "-Wno-deprecated-declarations") -endif() -target_link_libraries(fullbench libzstd_static) -add_test(NAME fullbench COMMAND fullbench ${ZSTD_FULLBENCH_FLAGS}) - -# -# fuzzer -# -add_executable(fuzzer ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${TESTS_DIR}/fuzzer.c) -if (NOT MSVC) - target_compile_options(fuzzer PRIVATE "-Wno-deprecated-declarations") -endif() -target_link_libraries(fuzzer libzstd_static) -AddTestFlagsOption(ZSTD_FUZZER_FLAGS "$ENV{FUZZERTEST} $ENV{FUZZER_FLAGS}" - "Semicolon-separated list of flags to pass to the fuzzer test (see `fuzzer -h` for usage)") -add_test(NAME fuzzer COMMAND fuzzer ${ZSTD_FUZZER_FLAGS}) -# Disable the timeout since the run time is too long for the default timeout of -# 1500 seconds and varies considerably between low-end and high-end CPUs. -# set_tests_properties(fuzzer PROPERTIES TIMEOUT 0) - -# -# zstreamtest -# -add_executable(zstreamtest ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${TESTS_DIR}/seqgen.c ${TESTS_DIR}/zstreamtest.c ${TESTS_DIR}/external_matchfinder.c) -if (NOT MSVC) - target_compile_options(zstreamtest PRIVATE "-Wno-deprecated-declarations") -endif() -target_link_libraries(zstreamtest libzstd_static) -AddTestFlagsOption(ZSTD_ZSTREAM_FLAGS "$ENV{ZSTREAM_TESTTIME} $ENV{FUZZER_FLAGS}" - "Semicolon-separated list of flags to pass to the zstreamtest test (see `zstreamtest -h` for usage)") -add_test(NAME zstreamtest COMMAND zstreamtest ${ZSTD_ZSTREAM_FLAGS}) - -# -# playTests.sh -# -AddTestFlagsOption(ZSTD_PLAYTESTS_FLAGS "$ENV{PLAYTESTS_FLAGS}" - "Semicolon-separated list of flags to pass to the playTests.sh test") -add_test(NAME playTests COMMAND sh -c "\"${TESTS_DIR}/playTests.sh\" ${ZSTD_PLAYTESTS_FLAGS}") -find_program(UNAME uname) # Run script only in unix shell environments -if (ZSTD_BUILD_PROGRAMS AND UNAME) - set_property(TEST playTests APPEND PROPERTY ENVIRONMENT - "ZSTD_BIN=$" - "DATAGEN_BIN=$" - ) -else() - message(STATUS "Disabling playTests.sh test because requirements not met") - set_tests_properties(playTests PROPERTIES DISABLED YES) -endif() - -# Label the "Medium" set of tests (see TESTING.md) -set_property(TEST fuzzer zstreamtest playTests APPEND PROPERTY LABELS Medium) - -add_executable(paramgrill ${PROGRAMS_DIR}/benchfn.c ${PROGRAMS_DIR}/benchzstd.c ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${TESTS_DIR}/paramgrill.c) -if (UNIX) - target_link_libraries(paramgrill libzstd_static m) #m is math library -else() - target_link_libraries(paramgrill libzstd_static) -endif () diff --git a/src/dependencies/zstd-1.5.4/build/cmake/zstdConfig.cmake b/src/dependencies/zstd-1.5.4/build/cmake/zstdConfig.cmake deleted file mode 100644 index ebbfcc3..0000000 --- a/src/dependencies/zstd-1.5.4/build/cmake/zstdConfig.cmake +++ /dev/null @@ -1 +0,0 @@ -include("${CMAKE_CURRENT_LIST_DIR}/zstdTargets.cmake") diff --git a/src/dependencies/zstd-1.5.4/build/meson/GetZstdLibraryVersion.py b/src/dependencies/zstd-1.5.4/build/meson/GetZstdLibraryVersion.py deleted file mode 100644 index 461af5f..0000000 --- a/src/dependencies/zstd-1.5.4/build/meson/GetZstdLibraryVersion.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python3 -# ############################################################################# -# Copyright (c) 2018-present lzutao -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ############################################################################# -import re - - -def find_version_tuple(filepath): - version_file_data = None - with open(filepath) as fd: - version_file_data = fd.read() - - patterns = r"""#\s*define\s+ZSTD_VERSION_MAJOR\s+([0-9]+) -#\s*define\s+ZSTD_VERSION_MINOR\s+([0-9]+) -#\s*define\s+ZSTD_VERSION_RELEASE\s+([0-9]+) -""" - regex = re.compile(patterns, re.MULTILINE) - version_match = regex.search(version_file_data) - if version_match: - return version_match.groups() - raise Exception("Unable to find version string") - - -def main(): - import argparse - parser = argparse.ArgumentParser(description='Print zstd version from lib/zstd.h') - parser.add_argument('file', help='path to lib/zstd.h') - args = parser.parse_args() - version_tuple = find_version_tuple(args.file) - print('.'.join(version_tuple)) - - -if __name__ == '__main__': - main() diff --git a/src/dependencies/zstd-1.5.4/build/meson/InstallSymlink.py b/src/dependencies/zstd-1.5.4/build/meson/InstallSymlink.py deleted file mode 100644 index 3f2998c..0000000 --- a/src/dependencies/zstd-1.5.4/build/meson/InstallSymlink.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python3 -# ############################################################################# -# Copyright (c) 2018-present lzutao -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ############################################################################# -# This file should be synced with https://github.com/lzutao/meson-symlink - -import os -import pathlib # since Python 3.4 - - -def install_symlink(src, dst, install_dir, dst_is_dir=False, dir_mode=0o777): - if not install_dir.exists(): - install_dir.mkdir(mode=dir_mode, parents=True, exist_ok=True) - if not install_dir.is_dir(): - raise NotADirectoryError(install_dir) - - new_dst = install_dir.joinpath(dst) - if new_dst.is_symlink() and os.readlink(new_dst) == src: - print('File exists: {!r} -> {!r}'.format(new_dst, src)) - return - print('Installing symlink {!r} -> {!r}'.format(new_dst, src)) - new_dst.symlink_to(src, target_is_directory=dst_is_dir) - - -def main(): - import argparse - parser = argparse.ArgumentParser(description='Install a symlink', - usage='{0} [-h] [-d] [-m MODE] source dest install_dir\n\n' - 'example:\n' - ' {0} dash sh /bin'.format(pathlib.Path(__file__).name)) - parser.add_argument('source', help='target to link') - parser.add_argument('dest', help='link name') - parser.add_argument('install_dir', help='installation directory') - parser.add_argument('-d', '--isdir', - action='store_true', - help='dest is a directory') - parser.add_argument('-m', '--mode', - help='directory mode on creating if not exist', - default='0o755') - args = parser.parse_args() - - dir_mode = int(args.mode, 8) - - meson_destdir = os.environ.get('MESON_INSTALL_DESTDIR_PREFIX', default='') - install_dir = pathlib.Path(meson_destdir, args.install_dir) - install_symlink(args.source, args.dest, install_dir, args.isdir, dir_mode) - - -if __name__ == '__main__': - main() diff --git a/src/dependencies/zstd-1.5.4/build/meson/README.md b/src/dependencies/zstd-1.5.4/build/meson/README.md deleted file mode 100644 index d393a06..0000000 --- a/src/dependencies/zstd-1.5.4/build/meson/README.md +++ /dev/null @@ -1,38 +0,0 @@ -Meson build system for zstandard -================================ - -Meson is a build system designed to optimize programmer productivity. -It aims to do this by providing simple, out-of-the-box support for -modern software development tools and practices, such as unit tests, -coverage reports, Valgrind, CCache and the like. - -This Meson build system is provided with no guarantee and maintained -by Dima Krasner \. - -It outputs one `libzstd`, either shared or static, depending on -`default_library` option. - -## How to build - -`cd` to this meson directory (`build/meson`) - -```sh -meson setup -Dbin_programs=true -Dbin_contrib=true builddir -cd builddir -ninja # to build -ninja install # to install -``` - -You might want to install it in staging directory: - -```sh -DESTDIR=./staging ninja install -``` - -To configure build options, use: - -```sh -meson configure -``` - -See [man meson(1)](https://manpages.debian.org/testing/meson/meson.1.en.html). diff --git a/src/dependencies/zstd-1.5.4/build/meson/contrib/gen_html/meson.build b/src/dependencies/zstd-1.5.4/build/meson/contrib/gen_html/meson.build deleted file mode 100644 index 3f30253..0000000 --- a/src/dependencies/zstd-1.5.4/build/meson/contrib/gen_html/meson.build +++ /dev/null @@ -1,30 +0,0 @@ -# ############################################################################# -# Copyright (c) 2018-present lzutao -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ############################################################################# - -zstd_rootdir = '../../../..' - -gen_html_includes = include_directories(join_paths(zstd_rootdir, 'programs'), - join_paths(zstd_rootdir, 'lib'), - join_paths(zstd_rootdir, 'lib/common'), - join_paths(zstd_rootdir, 'contrib/gen_html')) - -gen_html = executable('gen_html', - join_paths(zstd_rootdir, 'contrib/gen_html/gen_html.cpp'), - include_directories: gen_html_includes, - native: true, - install: false) - -# Update zstd manual -zstd_manual_html = custom_target('zstd_manual.html', - output : 'zstd_manual.html', - command : [gen_html, - zstd_version, - join_paths(meson.current_source_dir(), zstd_rootdir, 'lib/zstd.h'), - '@OUTPUT@'], - install : false) diff --git a/src/dependencies/zstd-1.5.4/build/meson/contrib/meson.build b/src/dependencies/zstd-1.5.4/build/meson/contrib/meson.build deleted file mode 100644 index 7f6d03a..0000000 --- a/src/dependencies/zstd-1.5.4/build/meson/contrib/meson.build +++ /dev/null @@ -1,12 +0,0 @@ -# ############################################################################# -# Copyright (c) 2018-present Dima Krasner -# lzutao -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ############################################################################# - -subdir('pzstd') -subdir('gen_html') diff --git a/src/dependencies/zstd-1.5.4/build/meson/contrib/pzstd/meson.build b/src/dependencies/zstd-1.5.4/build/meson/contrib/pzstd/meson.build deleted file mode 100644 index b95dc79..0000000 --- a/src/dependencies/zstd-1.5.4/build/meson/contrib/pzstd/meson.build +++ /dev/null @@ -1,25 +0,0 @@ -# ############################################################################# -# Copyright (c) 2018-present lzutao -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ############################################################################# - -zstd_rootdir = '../../../..' - -pzstd_includes = include_directories(join_paths(zstd_rootdir, 'programs'), - join_paths(zstd_rootdir, 'contrib/pzstd')) -pzstd_sources = [join_paths(zstd_rootdir, 'programs/util.c'), - join_paths(zstd_rootdir, 'contrib/pzstd/main.cpp'), - join_paths(zstd_rootdir, 'contrib/pzstd/Options.cpp'), - join_paths(zstd_rootdir, 'contrib/pzstd/Pzstd.cpp'), - join_paths(zstd_rootdir, 'contrib/pzstd/SkippableFrame.cpp')] -pzstd = executable('pzstd', - pzstd_sources, - cpp_args: pzstd_warning_flags, - include_directories: pzstd_includes, - dependencies: [ libzstd_dep, thread_dep ], - override_options: ['b_ndebug=true'], - install: true) diff --git a/src/dependencies/zstd-1.5.4/build/meson/lib/meson.build b/src/dependencies/zstd-1.5.4/build/meson/lib/meson.build deleted file mode 100644 index 68db2ca..0000000 --- a/src/dependencies/zstd-1.5.4/build/meson/lib/meson.build +++ /dev/null @@ -1,167 +0,0 @@ -# ############################################################################# -# Copyright (c) 2018-present Dima Krasner -# lzutao -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ############################################################################# - -zstd_rootdir = '../../..' - -libzstd_includes = [include_directories(join_paths(zstd_rootdir,'lib'), - join_paths(zstd_rootdir, 'lib/common'), - join_paths(zstd_rootdir, 'lib/compress'), - join_paths(zstd_rootdir, 'lib/decompress'), - join_paths(zstd_rootdir, 'lib/dictBuilder'))] - -libzstd_sources = [join_paths(zstd_rootdir, 'lib/common/entropy_common.c'), - join_paths(zstd_rootdir, 'lib/common/fse_decompress.c'), - join_paths(zstd_rootdir, 'lib/common/threading.c'), - join_paths(zstd_rootdir, 'lib/common/pool.c'), - join_paths(zstd_rootdir, 'lib/common/zstd_common.c'), - join_paths(zstd_rootdir, 'lib/common/error_private.c'), - join_paths(zstd_rootdir, 'lib/common/xxhash.c'), - join_paths(zstd_rootdir, 'lib/compress/hist.c'), - join_paths(zstd_rootdir, 'lib/compress/fse_compress.c'), - join_paths(zstd_rootdir, 'lib/compress/huf_compress.c'), - join_paths(zstd_rootdir, 'lib/compress/zstd_compress.c'), - join_paths(zstd_rootdir, 'lib/compress/zstd_compress_literals.c'), - join_paths(zstd_rootdir, 'lib/compress/zstd_compress_sequences.c'), - join_paths(zstd_rootdir, 'lib/compress/zstd_compress_superblock.c'), - join_paths(zstd_rootdir, 'lib/compress/zstdmt_compress.c'), - join_paths(zstd_rootdir, 'lib/compress/zstd_fast.c'), - join_paths(zstd_rootdir, 'lib/compress/zstd_double_fast.c'), - join_paths(zstd_rootdir, 'lib/compress/zstd_lazy.c'), - join_paths(zstd_rootdir, 'lib/compress/zstd_opt.c'), - join_paths(zstd_rootdir, 'lib/compress/zstd_ldm.c'), - join_paths(zstd_rootdir, 'lib/decompress/huf_decompress.c'), - join_paths(zstd_rootdir, 'lib/decompress/zstd_decompress.c'), - join_paths(zstd_rootdir, 'lib/decompress/zstd_decompress_block.c'), - join_paths(zstd_rootdir, 'lib/decompress/zstd_ddict.c'), - join_paths(zstd_rootdir, 'lib/dictBuilder/cover.c'), - join_paths(zstd_rootdir, 'lib/dictBuilder/fastcover.c'), - join_paths(zstd_rootdir, 'lib/dictBuilder/divsufsort.c'), - join_paths(zstd_rootdir, 'lib/dictBuilder/zdict.c')] - -# really we need anything that defines __GNUC__ as that is what ZSTD_ASM_SUPPORTED is gated on -# but these are the two compilers that are supported in tree and actually handle this correctly -# Otherwise, explicitly disable assembly. -if [compiler_gcc, compiler_clang].contains(cc_id) - libzstd_sources += join_paths(zstd_rootdir, 'lib/decompress/huf_decompress_amd64.S') -else - add_project_arguments('-DZSTD_DISABLE_ASM', language: 'c') -endif - -# Explicit define legacy support -add_project_arguments('-DZSTD_LEGACY_SUPPORT=@0@'.format(legacy_level), - language: 'c') - -if legacy_level == 0 - message('Legacy support: DISABLED') -else - # See ZSTD_LEGACY_SUPPORT of lib/README.md - message('Enable legacy support back to version 0.@0@'.format(legacy_level)) - - libzstd_includes += [ include_directories(join_paths(zstd_rootdir, 'lib/legacy')) ] - foreach i : [1, 2, 3, 4, 5, 6, 7] - if legacy_level <= i - libzstd_sources += join_paths(zstd_rootdir, 'lib/legacy/zstd_v0@0@.c'.format(i)) - endif - endforeach -endif - -libzstd_deps = [] -if use_multi_thread - message('Enable multi-threading support') - add_project_arguments('-DZSTD_MULTITHREAD', language: 'c') - libzstd_deps = [ thread_dep ] -endif - -libzstd_c_args = [] -if cc_id == compiler_msvc - if default_library_type != 'static' - libzstd_sources += [windows_mod.compile_resources( - join_paths(zstd_rootdir, 'build/VS2010/libzstd-dll/libzstd-dll.rc'), - include_directories: libzstd_includes)] - libzstd_c_args += ['-DZSTD_DLL_EXPORT=1', - '-DZSTD_HEAPMODE=0', - '-D_CONSOLE', - '-D_CRT_SECURE_NO_WARNINGS'] - else - libzstd_c_args += ['-DZSTD_HEAPMODE=0', - '-D_CRT_SECURE_NO_WARNINGS'] - endif -endif - -mingw_ansi_stdio_flags = [] -if host_machine_os == os_windows and cc_id == compiler_gcc - mingw_ansi_stdio_flags = [ '-D__USE_MINGW_ANSI_STDIO' ] -endif -libzstd_c_args += mingw_ansi_stdio_flags - -libzstd_debug_cflags = [] -if use_debug - libzstd_c_args += '-DDEBUGLEVEL=@0@'.format(debug_level) - if cc_id == compiler_gcc or cc_id == compiler_clang - libzstd_debug_cflags = ['-Wstrict-aliasing=1', '-Wswitch-enum', - '-Wdeclaration-after-statement', '-Wstrict-prototypes', - '-Wundef', '-Wpointer-arith', '-Wvla', - '-Wformat=2', '-Winit-self', '-Wfloat-equal', '-Wwrite-strings', - '-Wredundant-decls', '-Wmissing-prototypes', '-Wc++-compat'] - endif -endif -libzstd_c_args += cc.get_supported_arguments(libzstd_debug_cflags) - -libzstd = library('zstd', - libzstd_sources, - include_directories: libzstd_includes, - c_args: libzstd_c_args, - gnu_symbol_visibility: 'hidden', - dependencies: libzstd_deps, - install: true, - version: zstd_libversion) - -libzstd_dep = declare_dependency(link_with: libzstd, - include_directories: libzstd_includes) - -# we link to both: -# - the shared library (for public symbols) -# - the static library (for private symbols) -# -# this is needed because internally private symbols are used all the time, and -# -fvisibility=hidden means those cannot be found -if get_option('default_library') == 'static' - libzstd_static = libzstd - libzstd_internal_dep = libzstd_dep -else - if get_option('default_library') == 'shared' - libzstd_static = static_library('zstd_objlib', - objects: libzstd.extract_all_objects(recursive: true), - build_by_default: false) - else - libzstd_static = libzstd.get_static_lib() - endif - - if cc_id == compiler_msvc - # msvc does not actually support linking to both, but errors out with: - # error LNK2005: ZSTD_ already defined in zstd.lib(zstd-1.dll) - libzstd_internal_dep = declare_dependency(link_with: libzstd_static) - else - libzstd_internal_dep = declare_dependency(link_with: libzstd, - # the static library must be linked after the shared one - dependencies: declare_dependency(link_with: libzstd_static)) - endif -endif - -pkgconfig.generate(libzstd, - name: 'libzstd', - filebase: 'libzstd', - description: 'fast lossless compression algorithm library', - version: zstd_libversion, - url: 'https://facebook.github.io/zstd/') - -install_headers(join_paths(zstd_rootdir, 'lib/zstd.h'), - join_paths(zstd_rootdir, 'lib/zdict.h'), - join_paths(zstd_rootdir, 'lib/zstd_errors.h')) diff --git a/src/dependencies/zstd-1.5.4/build/meson/meson.build b/src/dependencies/zstd-1.5.4/build/meson/meson.build deleted file mode 100644 index 576dc44..0000000 --- a/src/dependencies/zstd-1.5.4/build/meson/meson.build +++ /dev/null @@ -1,145 +0,0 @@ -# ############################################################################# -# Copyright (c) 2018-present Dima Krasner -# lzutao -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ############################################################################# - -project('zstd', - ['c', 'cpp'], - license: ['BSD', 'GPLv2'], - default_options : [ - # There shouldn't be any need to force a C standard convention for zstd - # but in case one would want that anyway, this can be done here. - # 'c_std=gnu99', - # c++11 standard is useful for pzstd - 'cpp_std=c++11', - 'buildtype=release', - 'warning_level=3', - # -Wdocumentation does not actually pass, nor do the test binaries, - # so this isn't safe - #'werror=true' - ], - version: run_command( - find_program('GetZstdLibraryVersion.py'), '../../lib/zstd.h', - check: true).stdout().strip(), - meson_version: '>=0.50.0') - -cc = meson.get_compiler('c') -cxx = meson.get_compiler('cpp') -pkgconfig = import('pkgconfig') -windows_mod = import('windows') - -host_machine_os = host_machine.system() -os_windows = 'windows' -os_linux = 'linux' -os_darwin = 'darwin' -os_freebsd = 'freebsd' -os_sun = 'sunos' - -cc_id = cc.get_id() -compiler_gcc = 'gcc' -compiler_clang = 'clang' -compiler_msvc = 'msvc' - -zstd_version = meson.project_version() - -zstd_libversion = zstd_version - -# ============================================================================= -# Installation directories -# ============================================================================= - -zstd_prefix = get_option('prefix') -zstd_bindir = get_option('bindir') -zstd_datadir = get_option('datadir') -zstd_mandir = get_option('mandir') -zstd_docdir = join_paths(zstd_datadir, 'doc', meson.project_name()) - -# ============================================================================= -# Project options -# ============================================================================= - -# Built-in options -use_debug = get_option('debug') -buildtype = get_option('buildtype') -default_library_type = get_option('default_library') - -# Custom options -debug_level = get_option('debug_level') -legacy_level = get_option('legacy_level') -use_backtrace = get_option('backtrace') -use_static_runtime = get_option('static_runtime') - -bin_programs = get_option('bin_programs') -bin_contrib = get_option('bin_contrib') -bin_tests = get_option('bin_tests') - -feature_multi_thread = get_option('multi_thread') -feature_zlib = get_option('zlib') -feature_lzma = get_option('lzma') -feature_lz4 = get_option('lz4') - -# ============================================================================= -# Dependencies -# ============================================================================= - -libm_dep = cc.find_library('m', required: false) -thread_dep = dependency('threads', required: feature_multi_thread) -use_multi_thread = thread_dep.found() -# Arguments in dependency should be equivalent to those passed to pkg-config -zlib_dep = dependency('zlib', required: feature_zlib) -use_zlib = zlib_dep.found() -lzma_dep = dependency('liblzma', required: feature_lzma) -use_lzma = lzma_dep.found() -lz4_dep = dependency('liblz4', required: feature_lz4) -use_lz4 = lz4_dep.found() - -# ============================================================================= -# Compiler flags -# ============================================================================= - -add_project_arguments('-DXXH_NAMESPACE=ZSTD_', language: ['c']) - -pzstd_warning_flags = [] -if [compiler_gcc, compiler_clang].contains(cc_id) - common_warning_flags = [ '-Wundef', '-Wshadow', '-Wcast-align', '-Wcast-qual' ] - pzstd_warning_flags = ['-Wno-shadow', '-Wno-deprecated-declarations'] - if cc_id == compiler_clang - common_warning_flags += ['-Wconversion', '-Wno-sign-conversion', '-Wdocumentation'] - endif - cc_compile_flags = cc.get_supported_arguments(common_warning_flags + ['-Wstrict-prototypes']) - cxx_compile_flags = cxx.get_supported_arguments(common_warning_flags) - add_project_arguments(cc_compile_flags, language : 'c') - add_project_arguments(cxx_compile_flags, language : 'cpp') -elif cc_id == compiler_msvc - msvc_compile_flags = [ '/D_UNICODE', '/DUNICODE' ] - if use_multi_thread - msvc_compile_flags += '/MP' - endif - if use_static_runtime - msvc_compile_flags += '/MT' - endif - add_project_arguments(msvc_compile_flags, language: ['c', 'cpp']) -endif - -# ============================================================================= -# Subdirs -# ============================================================================= - -subdir('lib') - -if bin_programs - subdir('programs') -endif - -if bin_tests - subdir('tests') -endif - -if bin_contrib - subdir('contrib') -endif diff --git a/src/dependencies/zstd-1.5.4/build/meson/meson_options.txt b/src/dependencies/zstd-1.5.4/build/meson/meson_options.txt deleted file mode 100644 index f35cd5f..0000000 --- a/src/dependencies/zstd-1.5.4/build/meson/meson_options.txt +++ /dev/null @@ -1,36 +0,0 @@ -# ############################################################################# -# Copyright (c) 2018-present Dima Krasner -# lzutao -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ############################################################################# - -# Read guidelines from https://wiki.gnome.org/Initiatives/GnomeGoals/MesonPorting - -option('legacy_level', type: 'integer', min: 0, max: 7, value: 5, - description: 'Support any legacy format: 7 to 1 for v0.7+ to v0.1+') -option('debug_level', type: 'integer', min: 0, max: 9, value: 1, - description: 'Enable run-time debug. See lib/common/debug.h') -option('backtrace', type: 'feature', value: 'disabled', - description: 'Display a stack backtrace when execution generates a runtime exception') -option('static_runtime', type: 'boolean', value: false, - description: 'Link to static run-time libraries on MSVC') - -option('bin_programs', type: 'boolean', value: true, - description: 'Enable programs build') -option('bin_tests', type: 'boolean', value: false, - description: 'Enable tests build') -option('bin_contrib', type: 'boolean', value: false, - description: 'Enable contrib build') - -option('multi_thread', type: 'feature', value: 'enabled', - description: 'Enable multi-threading when pthread is detected') -option('zlib', type: 'feature', value: 'auto', - description: 'Enable zlib support') -option('lzma', type: 'feature', value: 'auto', - description: 'Enable lzma support') -option('lz4', type: 'feature', value: 'auto', - description: 'Enable lz4 support') diff --git a/src/dependencies/zstd-1.5.4/build/meson/programs/meson.build b/src/dependencies/zstd-1.5.4/build/meson/programs/meson.build deleted file mode 100644 index e611dc3..0000000 --- a/src/dependencies/zstd-1.5.4/build/meson/programs/meson.build +++ /dev/null @@ -1,116 +0,0 @@ -# ############################################################################# -# Copyright (c) 2018-present Dima Krasner -# lzutao -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ############################################################################# - -zstd_rootdir = '../../..' - -zstd_programs_sources = [join_paths(zstd_rootdir, 'programs/zstdcli.c'), - join_paths(zstd_rootdir, 'programs/util.c'), - join_paths(zstd_rootdir, 'programs/timefn.c'), - join_paths(zstd_rootdir, 'programs/fileio.c'), - join_paths(zstd_rootdir, 'programs/fileio_asyncio.c'), - join_paths(zstd_rootdir, 'programs/benchfn.c'), - join_paths(zstd_rootdir, 'programs/benchzstd.c'), - join_paths(zstd_rootdir, 'programs/datagen.c'), - join_paths(zstd_rootdir, 'programs/dibio.c'), - join_paths(zstd_rootdir, 'programs/zstdcli_trace.c')] - -zstd_deps = [ libzstd_internal_dep ] -zstd_c_args = libzstd_debug_cflags - -zstd_frugal_deps = [ libzstd_internal_dep ] -zstd_frugal_c_args = [ '-DZSTD_NOBENCH', '-DZSTD_NODICT', '-DZSTD_NOTRACE' ] - -if use_multi_thread - zstd_deps += [ thread_dep ] - zstd_c_args += [ '-DZSTD_MULTITHREAD' ] - zstd_frugal_deps += [ thread_dep ] - zstd_frugal_c_args += [ '-DZSTD_MULTITHREAD' ] -endif - -if use_zlib - zstd_deps += [ zlib_dep ] - zstd_c_args += [ '-DZSTD_GZCOMPRESS', '-DZSTD_GZDECOMPRESS' ] -endif - -if use_lzma - zstd_deps += [ lzma_dep ] - zstd_c_args += [ '-DZSTD_LZMACOMPRESS', '-DZSTD_LZMADECOMPRESS' ] -endif - -if use_lz4 - zstd_deps += [ lz4_dep ] - zstd_c_args += [ '-DZSTD_LZ4COMPRESS', '-DZSTD_LZ4DECOMPRESS' ] -endif - -export_dynamic_on_windows = false -# explicit backtrace enable/disable for Linux & Darwin -have_execinfo = cc.has_header('execinfo.h', required: use_backtrace) -if not have_execinfo - zstd_c_args += '-DBACKTRACE_ENABLE=0' -elif use_debug and host_machine_os == os_windows # MinGW target - zstd_c_args += '-DBACKTRACE_ENABLE=1' - export_dynamic_on_windows = true -endif - -if cc_id == compiler_msvc - if default_library_type != 'static' - zstd_programs_sources += [windows_mod.compile_resources( - join_paths(zstd_rootdir, 'build/VS2010/zstd/zstd.rc'), - include_directories: libzstd_includes)] - endif -endif - -zstd = executable('zstd', - zstd_programs_sources, - c_args: zstd_c_args, - dependencies: zstd_deps, - export_dynamic: export_dynamic_on_windows, # Since Meson 0.45.0 - install: true) - -zstd_frugal_sources = [join_paths(zstd_rootdir, 'programs/zstdcli.c'), - join_paths(zstd_rootdir, 'programs/timefn.c'), - join_paths(zstd_rootdir, 'programs/util.c'), - join_paths(zstd_rootdir, 'programs/fileio.c'), - join_paths(zstd_rootdir, 'programs/fileio_asyncio.c')] - -# Minimal target, with only zstd compression and decompression. -# No bench. No legacy. -executable('zstd-frugal', - zstd_frugal_sources, - dependencies: zstd_frugal_deps, - c_args: zstd_frugal_c_args, - install: true) - -install_data(join_paths(zstd_rootdir, 'programs/zstdgrep'), - join_paths(zstd_rootdir, 'programs/zstdless'), - install_dir: zstd_bindir) - -# ============================================================================= -# Programs and manpages installing -# ============================================================================= - -install_man(join_paths(zstd_rootdir, 'programs/zstd.1'), - join_paths(zstd_rootdir, 'programs/zstdgrep.1'), - join_paths(zstd_rootdir, 'programs/zstdless.1')) - -InstallSymlink_py = '../InstallSymlink.py' -zstd_man1_dir = join_paths(zstd_mandir, 'man1') -bin_EXT = host_machine_os == os_windows ? '.exe' : '' -man1_EXT = meson.version().version_compare('>=0.49.0') ? '.1' : '.1.gz' - -foreach f : ['zstdcat', 'unzstd'] - meson.add_install_script(InstallSymlink_py, 'zstd' + bin_EXT, f + bin_EXT, zstd_bindir) - meson.add_install_script(InstallSymlink_py, 'zstd' + man1_EXT, f + man1_EXT, zstd_man1_dir) -endforeach - -if use_multi_thread - meson.add_install_script(InstallSymlink_py, 'zstd' + bin_EXT, 'zstdmt' + bin_EXT, zstd_bindir) - meson.add_install_script(InstallSymlink_py, 'zstd' + man1_EXT, 'zstdmt' + man1_EXT, zstd_man1_dir) -endif diff --git a/src/dependencies/zstd-1.5.4/build/meson/tests/meson.build b/src/dependencies/zstd-1.5.4/build/meson/tests/meson.build deleted file mode 100644 index e70b734..0000000 --- a/src/dependencies/zstd-1.5.4/build/meson/tests/meson.build +++ /dev/null @@ -1,215 +0,0 @@ -# ############################################################################# -# Copyright (c) 2018-present Dima Krasner -# lzutao -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ############################################################################# - -zstd_rootdir = '../../..' - -tests_supported_oses = [os_linux, 'gnu/kfreebsd', os_darwin, 'gnu', 'openbsd', - os_freebsd, 'netbsd', 'dragonfly', os_sun] - -# ============================================================================= -# Test flags -# ============================================================================= - -FUZZER_FLAGS = ['--no-big-tests'] -FUZZERTEST = '-T200s' -ZSTREAM_TESTTIME = '-T90s' -DECODECORPUS_TESTTIME = '-T30' - -# ============================================================================= -# Executables -# ============================================================================= - -test_includes = [ include_directories(join_paths(zstd_rootdir, 'programs')) ] - -testcommon_sources = [join_paths(zstd_rootdir, 'programs/datagen.c'), - join_paths(zstd_rootdir, 'programs/util.c'), - join_paths(zstd_rootdir, 'programs/timefn.c'), - join_paths(zstd_rootdir, 'programs/benchfn.c'), - join_paths(zstd_rootdir, 'programs/benchzstd.c')] - -testcommon = static_library('testcommon', - testcommon_sources, - # needed due to use of private symbol + -fvisibility=hidden - link_with: libzstd_static) - -testcommon_dep = declare_dependency(link_with: testcommon, - dependencies: libzstd_deps, - include_directories: libzstd_includes) - -datagen_sources = [join_paths(zstd_rootdir, 'tests/datagencli.c')] -datagen = executable('datagen', - datagen_sources, - c_args: [ '-DNDEBUG' ], - include_directories: test_includes, - dependencies: testcommon_dep, - install: false) - -fullbench_sources = [join_paths(zstd_rootdir, 'tests/fullbench.c')] -fullbench = executable('fullbench', - fullbench_sources, - include_directories: test_includes, - dependencies: testcommon_dep, - install: false) - -fuzzer_sources = [join_paths(zstd_rootdir, 'tests/fuzzer.c')] -fuzzer = executable('fuzzer', - fuzzer_sources, - include_directories: test_includes, - dependencies: [ testcommon_dep, thread_dep ], - install: false) - -zstreamtest_sources = [ - join_paths(zstd_rootdir, 'tests/seqgen.c'), - join_paths(zstd_rootdir, 'tests/zstreamtest.c'), - join_paths(zstd_rootdir, 'tests/external_matchfinder.c')] -zstreamtest = executable('zstreamtest', - zstreamtest_sources, - include_directories: test_includes, - dependencies: testcommon_dep, - install: false) - -paramgrill_sources = [join_paths(zstd_rootdir, 'tests/paramgrill.c')] -paramgrill = executable('paramgrill', - paramgrill_sources, - include_directories: test_includes, - dependencies: [ testcommon_dep, libm_dep ], - install: false) - -roundTripCrash_sources = [join_paths(zstd_rootdir, 'tests/roundTripCrash.c')] -roundTripCrash = executable('roundTripCrash', - roundTripCrash_sources, - dependencies: [ testcommon_dep ], - install: false) - -longmatch_sources = [join_paths(zstd_rootdir, 'tests/longmatch.c')] -longmatch = executable('longmatch', - longmatch_sources, - dependencies: [ libzstd_dep ], - install: false) - -invalidDictionaries_sources = [join_paths(zstd_rootdir, 'tests/invalidDictionaries.c')] -invalidDictionaries = executable('invalidDictionaries', - invalidDictionaries_sources, - dependencies: [ libzstd_dep ], - install: false) - -if 0 < legacy_level and legacy_level <= 4 - legacy_sources = [join_paths(zstd_rootdir, 'tests/legacy.c')] - legacy = executable('legacy', - legacy_sources, - # Use -Dlegacy_level build option to control it - #c_args: '-DZSTD_LEGACY_SUPPORT=4', - dependencies: [ libzstd_dep ], - install: false) -endif - -decodecorpus_sources = [join_paths(zstd_rootdir, 'tests/decodecorpus.c')] -decodecorpus = executable('decodecorpus', - decodecorpus_sources, - include_directories: test_includes, - dependencies: [ testcommon_dep, libm_dep ], - install: false) - -poolTests_sources = [join_paths(zstd_rootdir, 'tests/poolTests.c')] -poolTests = executable('poolTests', - poolTests_sources, - include_directories: test_includes, - dependencies: [ testcommon_dep, thread_dep ], - install: false) - -checkTag_sources = [join_paths(zstd_rootdir, 'tests/checkTag.c')] -checkTag = executable('checkTag', - checkTag_sources, - dependencies: [ libzstd_dep ], - install: false) - -# ============================================================================= -# Tests (Use "meson test --list" to list all tests) -# ============================================================================= - -if tests_supported_oses.contains(host_machine_os) - valgrind_prog = find_program('valgrind', ['/usr/bin/valgrind'], required: false) - valgrindTest_py = files('valgrindTest.py') - if valgrind_prog.found() - test('valgrindTest', - valgrindTest_py, - args: [valgrind_prog.path(), zstd, datagen, fuzzer, fullbench], - depends: [zstd, datagen, fuzzer, fullbench], - timeout: 600) # Timeout should work on HDD drive - endif -endif - -if host_machine_os != os_windows - playTests_sh = find_program(join_paths(zstd_rootdir, 'tests/playTests.sh'), required: true) - - # add slow tests only if the meson version is new enough to support - # test setups with default-excluded suites - if meson.version().version_compare('>=0.57.0') - matrix = {'fast': [], 'slow': ['--test-large-data']} - else - matrix = {'fast': []} - endif - - foreach suite, opt: matrix - test('test-zstd-'+suite, - playTests_sh, - args: opt, - env: ['ZSTD_BIN=' + zstd.full_path(), 'DATAGEN_BIN=./datagen'], - depends: [datagen], - suite: suite, - workdir: meson.current_build_dir(), - timeout: 2800) # Timeout should work on HDD drive - endforeach -endif - -test('test-fullbench-1', - fullbench, - args: ['-i1'], - depends: [datagen], - timeout: 60) -test('test-fullbench-2', - fullbench, - args: ['-i1', '-P0'], - depends: [datagen], - timeout: 60) - -if use_zlib - test('test-fuzzer', - fuzzer, - args: ['-v', FUZZERTEST] + FUZZER_FLAGS, - timeout: 480) -endif - -test('test-zstream-1', - zstreamtest, - args: ['-v', ZSTREAM_TESTTIME] + FUZZER_FLAGS, - timeout: 240) -test('test-zstream-3', - zstreamtest, - args: ['--newapi', '-t1', ZSTREAM_TESTTIME] + FUZZER_FLAGS, - timeout: 120) -test('test-longmatch', longmatch, timeout: 36) -test('test-invalidDictionaries', invalidDictionaries) # should be fast -if 0 < legacy_level and legacy_level <= 4 - test('test-legacy', legacy) # should be fast -endif -test('test-decodecorpus', - decodecorpus, - args: ['-t', DECODECORPUS_TESTTIME], - timeout: 60) -test('test-poolTests', poolTests) # should be fast - -if meson.version().version_compare('>=0.57.0') - add_test_setup('fast', - is_default: true, - exclude_suites: ['slow']) - add_test_setup('slow', - exclude_suites: ['fast']) -endif diff --git a/src/dependencies/zstd-1.5.4/build/meson/tests/valgrindTest.py b/src/dependencies/zstd-1.5.4/build/meson/tests/valgrindTest.py deleted file mode 100644 index 05d8487..0000000 --- a/src/dependencies/zstd-1.5.4/build/meson/tests/valgrindTest.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env python3 -# ############################################################################# -# Copyright (c) 2018-present lzutao -# All rights reserved. -# -# This source code is licensed under both the BSD-style license (found in the -# LICENSE file in the root directory of this source tree) and the GPLv2 (found -# in the COPYING file in the root directory of this source tree). -# ############################################################################# -import os -import subprocess -import tempfile - - -def valgrindTest(valgrind, datagen, fuzzer, zstd, fullbench): - VALGRIND_ARGS = [valgrind, '--leak-check=full', '--show-leak-kinds=all', '--error-exitcode=1'] - - print('\n ---- valgrind tests : memory analyzer ----') - - subprocess.check_call([*VALGRIND_ARGS, datagen, '-g50M'], stdout=subprocess.DEVNULL) - - if subprocess.call([*VALGRIND_ARGS, zstd], - stdout=subprocess.DEVNULL) == 0: - raise subprocess.SubprocessError('zstd without argument should have failed') - - with subprocess.Popen([datagen, '-g80'], stdout=subprocess.PIPE) as p1, \ - subprocess.Popen([*VALGRIND_ARGS, zstd, '-', '-c'], - stdin=p1.stdout, - stdout=subprocess.DEVNULL) as p2: - p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits. - p2.communicate() - if p2.returncode != 0: - raise subprocess.SubprocessError() - - with subprocess.Popen([datagen, '-g16KB'], stdout=subprocess.PIPE) as p1, \ - subprocess.Popen([*VALGRIND_ARGS, zstd, '-vf', '-', '-c'], - stdin=p1.stdout, - stdout=subprocess.DEVNULL) as p2: - p1.stdout.close() - p2.communicate() - if p2.returncode != 0: - raise subprocess.SubprocessError() - - with tempfile.NamedTemporaryFile() as tmp_fd: - with subprocess.Popen([datagen, '-g2930KB'], stdout=subprocess.PIPE) as p1, \ - subprocess.Popen([*VALGRIND_ARGS, zstd, '-5', '-vf', '-', '-o', tmp_fd.name], - stdin=p1.stdout) as p2: - p1.stdout.close() - p2.communicate() - if p2.returncode != 0: - raise subprocess.SubprocessError() - - subprocess.check_call([*VALGRIND_ARGS, zstd, '-vdf', tmp_fd.name, '-c'], - stdout=subprocess.DEVNULL) - - with subprocess.Popen([datagen, '-g64MB'], stdout=subprocess.PIPE) as p1, \ - subprocess.Popen([*VALGRIND_ARGS, zstd, '-vf', '-', '-c'], - stdin=p1.stdout, - stdout=subprocess.DEVNULL) as p2: - p1.stdout.close() - p2.communicate() - if p2.returncode != 0: - raise subprocess.SubprocessError() - - subprocess.check_call([*VALGRIND_ARGS, fuzzer, '-T1mn', '-t1']) - subprocess.check_call([*VALGRIND_ARGS, fullbench, '-i1']) - - -def main(): - import argparse - parser = argparse.ArgumentParser(description='Valgrind tests : memory analyzer') - parser.add_argument('valgrind', help='valgrind path') - parser.add_argument('zstd', help='zstd path') - parser.add_argument('datagen', help='datagen path') - parser.add_argument('fuzzer', help='fuzzer path') - parser.add_argument('fullbench', help='fullbench path') - - args = parser.parse_args() - - valgrind = args.valgrind - zstd = args.zstd - datagen = args.datagen - fuzzer = args.fuzzer - fullbench = args.fullbench - - valgrindTest(valgrind, datagen, fuzzer, zstd, fullbench) - - -if __name__ == '__main__': - main() diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/.gitignore b/src/dependencies/zstd-1.5.4/build/single_file_libs/.gitignore deleted file mode 100644 index 8c1bc71..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ - -# build artifacts -zstddeclib.c -zstdenclib.c -zstd.c -zstd.h - -# test artifacts -temp* diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/README.md b/src/dependencies/zstd-1.5.4/build/single_file_libs/README.md deleted file mode 100644 index 64c973a..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# Single File Zstandard Libraries - -The script `combine.sh` creates an _amalgamated_ source file that can be used with or without `zstd.h`. This isn't a _header-only_ file but it does offer a similar level of simplicity when integrating into a project. - -All it now takes to support Zstd in your own projects is the addition of a single file, two if using the header, with no configuration or further build steps. - -Decompressor ------------- - -This is the most common use case. The decompression library is small, adding, for example, 26kB to an Emscripten compiled WebAssembly project. Native implementations add a little more, 40-70kB depending on the compiler and platform. - -Create `zstddeclib.c` from the Zstd source using: -``` -cd zstd/build/single_file_libs -python3 combine.py -r ../../lib -x legacy/zstd_legacy.h -o zstddeclib.c zstddeclib-in.c -``` -Then add the resulting file to your project (see the [example files](examples)). - -`create_single_file_decoder.sh` will run the above script, creating the file `zstddeclib.c` (`build_decoder_test.sh` will also create `zstddeclib.c`, then compile and test the result). - -Full Library ------------- - -The same tool can amalgamate the entire Zstd library for ease of adding both compression and decompression to a project. The [roundtrip example](examples/roundtrip.c) uses the original `zstd.h` with the remaining source files combined into `zstd.c` (currently just over 1.2MB) created from `zstd-in.c`. As with the standalone decoder the most useful compile flags have already been rolled-in and the resulting file can be added to a project as-is. - -Create `zstd.c` from the Zstd source using: -``` -cd zstd/build/single_file_libs -python3 combine.py -r ../../lib -x legacy/zstd_legacy.h -k zstd.h -o zstd.c zstd-in.c -``` -It's possible to create a compressor-only library but since the decompressor is so small in comparison this doesn't bring much of a gain (but for the curious, simply remove the files in the _decompress_ section at the end of `zstd-in.c`). - -`create_single_file_library.sh` will run the script to create `zstd.c` (`build_library_test.sh` will also create `zstd.c`, then compile and test the result). diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/build_decoder_test.sh b/src/dependencies/zstd-1.5.4/build/single_file_libs/build_decoder_test.sh deleted file mode 100755 index c4ca55f..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/build_decoder_test.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/bin/sh - -# Temporary compiled binary -OUT_FILE="tempbin" - -# Optional temporary compiled WebAssembly -OUT_WASM="temp.wasm" - -# Source files to compile using Emscripten. -IN_FILES="examples/emscripten.c" - -# Emscripten build using emcc. -emscripten_emcc_build() { - # Compile the same example as above - CC_FLAGS="-Wall -Wextra -Wshadow -Werror -Os -g0 -flto" - emcc $CC_FLAGS -s WASM=1 -I. -o $OUT_WASM $IN_FILES - # Did compilation work? - if [ $? -ne 0 ]; then - echo "Compiling ${IN_FILES}: FAILED" - exit 1 - fi - echo "Compiling ${IN_FILES}: PASSED" - rm -f $OUT_WASM -} - -# Emscripten build using docker. -emscripten_docker_build() { - docker container run --rm \ - --volume $PWD:/code \ - --workdir /code \ - emscripten/emsdk:latest \ - emcc $CC_FLAGS -s WASM=1 -I. -o $OUT_WASM $IN_FILES - # Did compilation work? - if [ $? -ne 0 ]; then - echo "Compiling ${IN_FILES} (using docker): FAILED" - exit 1 - fi - echo "Compiling ${IN_FILES} (using docker): PASSED" - rm -f $OUT_WASM -} - -# Try Emscripten build using emcc or docker. -try_emscripten_build() { - which emcc > /dev/null - if [ $? -eq 0 ]; then - emscripten_emcc_build - return $? - fi - - which docker > /dev/null - if [ $? -eq 0 ]; then - emscripten_docker_build - return $? - fi - - echo "(Skipping Emscripten test)" -} - -# Amalgamate the sources -./create_single_file_decoder.sh -# Did combining work? -if [ $? -ne 0 ]; then - echo "Single file decoder creation script: FAILED" - exit 1 -fi -echo "Single file decoder creation script: PASSED" - -# Compile the generated output -cc -Wall -Wextra -Wshadow -Werror -Os -g0 -o $OUT_FILE examples/simple.c -# Did compilation work? -if [ $? -ne 0 ]; then - echo "Compiling simple.c: FAILED" - exit 1 -fi -echo "Compiling simple.c: PASSED" - -# Run then delete the compiled output -./$OUT_FILE -retVal=$? -rm -f $OUT_FILE -# Did the test work? -if [ $retVal -ne 0 ]; then - echo "Running simple.c: FAILED" - exit 1 -fi -echo "Running simple.c: PASSED" - -# Try Emscripten build if emcc or docker command is available. -try_emscripten_build - -exit 0 diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/build_library_test.sh b/src/dependencies/zstd-1.5.4/build/single_file_libs/build_library_test.sh deleted file mode 100755 index f4ba109..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/build_library_test.sh +++ /dev/null @@ -1,97 +0,0 @@ -#!/bin/sh - -# Where to find the sources (only used to copy zstd.h) -ZSTD_SRC_ROOT="../../lib" - -# Temporary compiled binary -OUT_FILE="tempbin" - -# Optional temporary compiled WebAssembly -OUT_WASM="temp.wasm" - -# Source files to compile using Emscripten. -IN_FILES="zstd.c examples/roundtrip.c" - -# Emscripten build using emcc. -emscripten_emcc_build() { - # Compile the same example as above - CC_FLAGS="-Wall -Wextra -Wshadow -Werror -Os -g0 -flto" - emcc $CC_FLAGS -s WASM=1 -I. -o $OUT_WASM $IN_FILES - # Did compilation work? - if [ $? -ne 0 ]; then - echo "Compiling ${IN_FILES}: FAILED" - exit 1 - fi - echo "Compiling ${IN_FILES}: PASSED" - rm -f $OUT_WASM -} - -# Emscripten build using docker. -emscripten_docker_build() { - docker container run --rm \ - --volume $PWD:/code \ - --workdir /code \ - emscripten/emsdk:latest \ - emcc $CC_FLAGS -s WASM=1 -I. -o $OUT_WASM $IN_FILES - # Did compilation work? - if [ $? -ne 0 ]; then - echo "Compiling ${IN_FILES} (using docker): FAILED" - exit 1 - fi - echo "Compiling ${IN_FILES} (using docker): PASSED" - rm -f $OUT_WASM -} - -# Try Emscripten build using emcc or docker. -try_emscripten_build() { - which emcc > /dev/null - if [ $? -eq 0 ]; then - emscripten_emcc_build - return $? - fi - - which docker > /dev/null - if [ $? -eq 0 ]; then - emscripten_docker_build - return $? - fi - - echo "(Skipping Emscripten test)" -} - -# Amalgamate the sources -./create_single_file_library.sh -# Did combining work? -if [ $? -ne 0 ]; then - echo "Single file library creation script: FAILED" - exit 1 -fi -echo "Single file library creation script: PASSED" - -# Copy the header to here (for the tests) -cp "$ZSTD_SRC_ROOT/zstd.h" examples/zstd.h - -# Compile the generated output -cc -Wall -Wextra -Werror -Wshadow -pthread -I. -Os -g0 -o $OUT_FILE zstd.c examples/roundtrip.c -# Did compilation work? -if [ $? -ne 0 ]; then - echo "Compiling roundtrip.c: FAILED" - exit 1 -fi -echo "Compiling roundtrip.c: PASSED" - -# Run then delete the compiled output -./$OUT_FILE -retVal=$? -rm -f $OUT_FILE -# Did the test work? -if [ $retVal -ne 0 ]; then - echo "Running roundtrip.c: FAILED" - exit 1 -fi -echo "Running roundtrip.c: PASSED" - -# Try Emscripten build if emcc or docker command is available. -try_emscripten_build - -exit 0 diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/combine.py b/src/dependencies/zstd-1.5.4/build/single_file_libs/combine.py deleted file mode 100755 index 771dd20..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/combine.py +++ /dev/null @@ -1,234 +0,0 @@ -#!/usr/bin/env python3 - -# Tool to bundle multiple C/C++ source files, inlining any includes. -# -# Note: there are two types of exclusion options: the '-x' flag, which besides -# excluding a file also adds an #error directive in place of the #include, and -# the '-k' flag, which keeps the #include and doesn't inline the file. The -# intended use cases are: '-x' for files that would normally be #if'd out, so -# features that 100% won't be used in the amalgamated file, for which every -# occurrence adds the error, and '-k' for headers that we wish to manually -# include, such as a project's public API, for which occurrences after the first -# are removed. -# -# Todo: the error handling could be better, which currently throws and halts -# (which is functional just not very friendly). -# -# Author: Carl Woffenden, Numfum GmbH (this script is released under a CC0 license/Public Domain) - -import argparse, re, sys - -from pathlib import Path -from typing import Any, List, Optional, Pattern, Set, TextIO - -# Set of file roots when searching (equivalent to -I paths for the compiler). -roots: Set[Path] = set() - -# Set of (canonical) file Path objects to exclude from inlining (and not only -# exclude but to add a compiler error directive when they're encountered). -excludes: Set[Path] = set() - -# Set of (canonical) file Path objects to keep as include directives. -keeps: Set[Path] = set() - -# Whether to keep the #pragma once directives (unlikely, since this will result -# in a warning, but the option is there). -keep_pragma: bool = False - -# Destination file object (or stdout if no output file was supplied). -destn: TextIO = sys.stdout - -# Set of file Path objects previously inlined (and to ignore if reencountering). -found: Set[Path] = set() - -# Compiled regex Pattern to handle "#pragma once" in various formats: -# -# #pragma once -# #pragma once -# # pragma once -# #pragma once -# #pragma once // comment -# -# Ignoring commented versions, same as include_regex. -# -pragma_regex: Pattern = re.compile(r'^\s*#\s*pragma\s*once\s*') - -# Compiled regex Pattern to handle the following type of file includes: -# -# #include "file" -# #include "file" -# # include "file" -# #include "file" -# #include "file" // comment -# #include "file" // comment with quote " -# -# And all combinations of, as well as ignoring the following: -# -# #include -# //#include "file" -# /*#include "file"*/ -# -# We don't try to catch errors since the compiler will do this (and the code is -# expected to be valid before processing) and we don't care what follows the -# file (whether it's a valid comment or not, since anything after the quoted -# string is ignored) -# -include_regex: Pattern = re.compile(r'^\s*#\s*include\s*"(.+?)"') - -# Simple tests to prove include_regex's cases. -# -def test_match_include() -> bool: - if (include_regex.match('#include "file"') and - include_regex.match(' #include "file"') and - include_regex.match('# include "file"') and - include_regex.match('#include "file"') and - include_regex.match('#include "file" // comment')): - if (not include_regex.match('#include ') and - not include_regex.match('//#include "file"') and - not include_regex.match('/*#include "file"*/')): - found = include_regex.match('#include "file" // "') - if (found and found.group(1) == 'file'): - print('#include match valid') - return True - return False - -# Simple tests to prove pragma_regex's cases. -# -def test_match_pragma() -> bool: - if (pragma_regex.match('#pragma once') and - pragma_regex.match(' #pragma once') and - pragma_regex.match('# pragma once') and - pragma_regex.match('#pragma once') and - pragma_regex.match('#pragma once // comment')): - if (not pragma_regex.match('//#pragma once') and - not pragma_regex.match('/*#pragma once*/')): - print('#pragma once match valid') - return True - return False - -# Finds 'file'. First the list of 'root' paths are searched, followed by the -# currently processing file's 'parent' path, returning a valid Path in -# canonical form. If no match is found None is returned. -# -def resolve_include(file: str, parent: Optional[Path] = None) -> Optional[Path]: - for root in roots: - found = root.joinpath(file).resolve() - if (found.is_file()): - return found - if (parent): - found = parent.joinpath(file).resolve(); - else: - found = Path(file) - if (found.is_file()): - return found - return None - -# Helper to resolve lists of files. 'file_list' is passed in from the arguments -# and each entry resolved to its canonical path (like any include entry, either -# from the list of root paths or the owning file's 'parent', which in this case -# is case is the input file). The results are stored in 'resolved'. -# -def resolve_excluded_files(file_list: Optional[List[str]], resolved: Set[Path], parent: Optional[Path] = None) -> None: - if (file_list): - for filename in file_list: - found = resolve_include(filename, parent) - if (found): - resolved.add(found) - else: - error_line(f'Warning: excluded file not found: {filename}') - -# Writes 'line' to the open 'destn' (or stdout). -# -def write_line(line: str) -> None: - print(line, file=destn) - -# Logs 'line' to stderr. This is also used for general notifications that we -# don't want to go to stdout (so the source can be piped). -# -def error_line(line: Any) -> None: - print(line, file=sys.stderr) - -# Inline the contents of 'file' (with any of its includes also inlined, etc.). -# -# Note: text encoding errors are ignored and replaced with ? when reading the -# input files. This isn't ideal, but it's more than likely in the comments than -# code and a) the text editor has probably also failed to read the same content, -# and b) the compiler probably did too. -# -def add_file(file: Path, file_name: str = None) -> None: - if (file.is_file()): - if (not file_name): - file_name = file.name - error_line(f'Processing: {file_name}') - with file.open('r', errors='replace') as opened: - for line in opened: - line = line.rstrip('\n') - match_include = include_regex.match(line); - if (match_include): - # We have a quoted include directive so grab the file - inc_name = match_include.group(1) - resolved = resolve_include(inc_name, file.parent) - if (resolved): - if (resolved in excludes): - # The file was excluded so error if the compiler uses it - write_line(f'#error Using excluded file: {inc_name} (re-amalgamate source to fix)') - error_line(f'Excluding: {inc_name}') - else: - if (resolved not in found): - # The file was not previously encountered - found.add(resolved) - if (resolved in keeps): - # But the include was flagged to keep as included - write_line(f'/**** *NOT* inlining {inc_name} ****/') - write_line(line) - error_line(f'Not inlining: {inc_name}') - else: - # The file was neither excluded nor seen before so inline it - write_line(f'/**** start inlining {inc_name} ****/') - add_file(resolved, inc_name) - write_line(f'/**** ended inlining {inc_name} ****/') - else: - write_line(f'/**** skipping file: {inc_name} ****/') - else: - # The include file didn't resolve to a file - write_line(f'#error Unable to find: {inc_name}') - error_line(f'Error: Unable to find: {inc_name}') - else: - # Skip any 'pragma once' directives, otherwise write the source line - if (keep_pragma or not pragma_regex.match(line)): - write_line(line) - else: - error_line(f'Error: Invalid file: {file}') - -# Start here -parser = argparse.ArgumentParser(description='Amalgamate Tool', epilog=f'example: {sys.argv[0]} -r ../my/path -r ../other/path -o out.c in.c') -parser.add_argument('-r', '--root', action='append', type=Path, help='file root search path') -parser.add_argument('-x', '--exclude', action='append', help='file to completely exclude from inlining') -parser.add_argument('-k', '--keep', action='append', help='file to exclude from inlining but keep the include directive') -parser.add_argument('-p', '--pragma', action='store_true', default=False, help='keep any "#pragma once" directives (removed by default)') -parser.add_argument('-o', '--output', type=argparse.FileType('w'), help='output file (otherwise stdout)') -parser.add_argument('input', type=Path, help='input file') -args = parser.parse_args() - -# Fail early on an invalid input (and store it so we don't recurse) -args.input = args.input.resolve(strict=True) -found.add(args.input) - -# Resolve all of the root paths upfront (we'll halt here on invalid roots) -if (args.root): - for path in args.root: - roots.add(path.resolve(strict=True)) - -# The remaining params: so resolve the excluded files and #pragma once directive -resolve_excluded_files(args.exclude, excludes, args.input.parent) -resolve_excluded_files(args.keep, keeps, args.input.parent) -keep_pragma = args.pragma; - -# Then recursively process the input file -try: - if (args.output): - destn = args.output - add_file(args.input) -finally: - if (destn): - destn.close() diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/combine.sh b/src/dependencies/zstd-1.5.4/build/single_file_libs/combine.sh deleted file mode 100755 index 222c2c3..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/combine.sh +++ /dev/null @@ -1,249 +0,0 @@ -#!/bin/sh -e - -# Tool to bundle multiple C/C++ source files, inlining any includes. -# -# TODO: ROOTS, FOUND, etc., as arrays (since they fail on paths with spaces) -# -# Author: Carl Woffenden, Numfum GmbH (this script is released under a CC0 license/Public Domain) - -# Common file roots -ROOTS="." - -# -x option excluded includes -XINCS="" - -# -k option includes to keep as include directives -KINCS="" - -# Files previously visited -FOUND="" - -# Optional destination file (empty string to write to stdout) -DESTN="" - -# Whether the "#pragma once" directives should be written to the output -PONCE=0 - -# Prints the script usage then exits -usage() { - echo "Usage: $0 [-r ] [-x
] [-k
] [-o ] infile" - echo " -r file root search path" - echo " -x file to completely exclude from inlining" - echo " -k file to exclude from inlining but keep the include directive" - echo " -p keep any '#pragma once' directives (removed by default)" - echo " -o output file (otherwise stdout)" - echo "Example: $0 -r ../my/path - r ../other/path -o out.c in.c" - exit 1 -} - -# Tests that the grep implementation works as expected (older OSX grep fails) -test_deps() { - if ! echo '#include "foo"' | grep -Eq '^\s*#\s*include\s*".+"'; then - echo "Aborting: the grep implementation fails to parse include lines" - exit 1 - fi - if ! echo '"foo.h"' | sed -E 's/"([^"]+)"/\1/' | grep -Eq '^foo\.h$'; then - echo "Aborting: sed is unavailable or non-functional" - exit 1 - fi -} - -# Test if glob pattern $1 matches subject $2 (see fnmatch(3)) -fnmatch() { - case "$2" in - $1) - return 0 - ;; - esac - return 1 -} - -# Test if line $1 is local include directive -is_include_line() { - fnmatch "*#*include*" "$1" || return 1 - printf "%s\n" "$1" | grep -Eq '^\s*#\s*include\s*".+"' -} - -# Test if line $1 is pragma once directive -is_pragma_once_line() { - fnmatch "*#*pragma*once*" "$1" || return 1 - printf "%s\n" "$1" | grep -Eq '^\s*#\s*pragma\s*once\s*' -} - -# Tests if list $1 has item $2 (returning zero on a match) -# (originally used grep -Eq "(^|\s*)$2(\$|\s*)) -readonly list_FS="$IFS" -list_has_item() { - # Re: escaping glob pattern special characters in item string: - # - # bash (tested 3.2.57, 5.1.4), dash (tested 0.5.10.2), NetBSD /bin/sh - # (tested 8.2), and Solaris /bin/sh (tested 11.4) require escaping - # backslashes in a bracket expression despite POSIX specifying that - # backslash loses significance in a bracket expression. - # - # Conversely, neither FreeBSD /bin/sh (tested 12.2) nor OpenBSD /bin/sh - # (tested 7.1) obey backslash-escaping in case statement patterns even - # outside bracket expressions, so escape special characters using bracket - # expressions. - # - # Solaris /bin/sh (tested 11.4) requires vertical bar (|) to be escaped. - # - # All accommodations should behave as expected under strict POSIX semantics. - if fnmatch "*[\\*?[|]*" "$2"; then - set -- "$1" "$(printf '%s\n' "$2" | sed -e 's/[*?[|]/[&]/g; s/[\]/[\\&]/g')" - fi - for item_P in "*[$list_FS]$2[$list_FS]*" "*[$list_FS]$2" "$2[$list_FS]*" "$2"; do - fnmatch "${item_P}" "$1" && return 0 - done - return 1 -} - -# Adds a new line with the supplied arguments to $DESTN (or stdout) -write_line() { - if [ -n "$DESTN" ]; then - printf '%s\n' "$@" >> "$DESTN" - else - printf '%s\n' "$@" - fi -} - -log_line() { - echo $@ >&2 -} - -# Find this file! -resolve_include() { - local srcdir=$1 - local inc=$2 - for root in $srcdir $ROOTS; do - if [ -f "$root/$inc" ]; then - # Try to reduce the file path into a canonical form (so that multiple) - # includes of the same file are successfully deduplicated, even if they - # are expressed differently. - local relpath="$(realpath --relative-to . "$root/$inc" 2>/dev/null)" - if [ "$relpath" != "" ]; then # not all realpaths support --relative-to - echo "$relpath" - return 0 - fi - local relpath="$(realpath "$root/$inc" 2>/dev/null)" - if [ "$relpath" != "" ]; then # not all distros have realpath... - echo "$relpath" - return 0 - fi - # Fallback on Python to reduce the path if the above fails. - local relpath=$(python -c "import os,sys; print os.path.relpath(sys.argv[1])" "$root/$inc" 2>/dev/null) - if [ "$relpath" != "" ]; then # not all distros have realpath... - echo "$relpath" - return 0 - fi - # Worst case, fall back to just the root + relative include path. The - # problem with this is that it is possible to emit multiple different - # resolved paths to the same file, depending on exactly how its included. - # Since the main loop below keeps a list of the resolved paths it's - # already included, in order to avoid repeated includes, this failure to - # produce a canonical/reduced path can lead to multiple inclusions of the - # same file. But it seems like the resulting single file library still - # works (hurray include guards!), so I guess it's ok. - echo "$root/$inc" - return 0 - fi - done - return 1 -} - -# Adds the contents of $1 with any of its includes inlined -add_file() { - local file=$1 - if [ -n "$file" ]; then - log_line "Processing: $file" - # Get directory of the current so we can resolve relative includes - local srcdir="$(dirname "$file")" - # Read the file - local line= - while IFS= read -r line; do - if is_include_line "$line"; then - # We have an include directive so strip the (first) file - local inc=$(echo "$line" | grep -Eo '".*"' | sed -E 's/"([^"]+)"/\1/' | head -1) - local res_inc="$(resolve_include "$srcdir" "$inc")" - if list_has_item "$XINCS" "$inc"; then - # The file was excluded so error if the source attempts to use it - write_line "#error Using excluded file: $inc (re-amalgamate source to fix)" - log_line "Excluding: $inc" - else - if ! list_has_item "$FOUND" "$res_inc"; then - # The file was not previously encountered - FOUND="$FOUND $res_inc" - if list_has_item "$KINCS" "$inc"; then - # But the include was flagged to keep as included - write_line "/**** *NOT* inlining $inc ****/" - write_line "$line" - log_line "Not Inlining: $inc" - else - # The file was neither excluded nor seen before so inline it - write_line "/**** start inlining $inc ****/" - add_file "$res_inc" - write_line "/**** ended inlining $inc ****/" - fi - else - write_line "/**** skipping file: $inc ****/" - fi - fi - else - # Skip any 'pragma once' directives, otherwise write the source line - local write=$PONCE - if [ $write -eq 0 ]; then - if ! is_pragma_once_line "$line"; then - write=1 - fi - fi - if [ $write -ne 0 ]; then - write_line "$line" - fi - fi - done < "$file" - else - write_line "#error Unable to find \"$1\"" - log_line "Error: Unable to find: \"$1\"" - fi -} - -while getopts ":r:x:k:po:" opts; do - case $opts in - r) - ROOTS="$ROOTS $OPTARG" - ;; - x) - XINCS="$XINCS $OPTARG" - ;; - k) - KINCS="$KINCS $OPTARG" - ;; - p) - PONCE=1 - ;; - o) - DESTN="$OPTARG" - ;; - *) - usage - ;; - esac -done -shift $((OPTIND-1)) - -if [ -n "$1" ]; then - if [ -f "$1" ]; then - if [ -n "$DESTN" ]; then - printf "" > "$DESTN" - fi - test_deps - log_line "Processing using the slower shell script; this might take a while" - add_file "$1" - else - echo "Input file not found: \"$1\"" - exit 1 - fi -else - usage -fi -exit 0 diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/create_single_file_decoder.sh b/src/dependencies/zstd-1.5.4/build/single_file_libs/create_single_file_decoder.sh deleted file mode 100755 index 3c0c577..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/create_single_file_decoder.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -# Where to find the sources -ZSTD_SRC_ROOT="../../lib" - -# Amalgamate the sources -echo "Amalgamating files..." -# Using the faster Python script if we have 3.8 or higher -if python3 -c 'import sys; assert sys.version_info >= (3,8)' 2>/dev/null; then - ./combine.py -r "$ZSTD_SRC_ROOT" -x legacy/zstd_legacy.h -o zstddeclib.c zstddeclib-in.c -else - ./combine.sh -r "$ZSTD_SRC_ROOT" -x legacy/zstd_legacy.h -o zstddeclib.c zstddeclib-in.c -fi -# Did combining work? -if [ $? -ne 0 ]; then - echo "Combine script: FAILED" - exit 1 -fi -echo "Combine script: PASSED" diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/create_single_file_library.sh b/src/dependencies/zstd-1.5.4/build/single_file_libs/create_single_file_library.sh deleted file mode 100755 index a6f71f0..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/create_single_file_library.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -# Where to find the sources -ZSTD_SRC_ROOT="../../lib" - -# Amalgamate the sources -echo "Amalgamating files..." -# Using the faster Python script if we have 3.8 or higher -if python3 -c 'import sys; assert sys.version_info >= (3,8)' 2>/dev/null; then - ./combine.py -r "$ZSTD_SRC_ROOT" -x legacy/zstd_legacy.h -o zstd.c zstd-in.c -else - ./combine.sh -r "$ZSTD_SRC_ROOT" -x legacy/zstd_legacy.h -o zstd.c zstd-in.c -fi -# Did combining work? -if [ $? -ne 0 ]; then - echo "Combine script: FAILED" - exit 1 -fi -echo "Combine script: PASSED" diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/README.md b/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/README.md deleted file mode 100644 index e93bee3..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Single File ZStandard Examples - -The examples `#include` the generated `zstddeclib.c` directly but work equally as well when including `zstd.h` and compiling the amalgamated source separately. - -`simple.c` is the most basic example of decompressing content and verifying the result. - -`emscripten.c` is a bare-bones [Emscripten](https://github.com/emscripten-core/emscripten) compiled WebGL demo using Zstd to further compress a DXT1 texture (see the [original PNG image](testcard.png)). The 256x256 texture would normally be 32kB, but even when bundled with the Zstd decompressor the resulting WebAssembly weighs in at 41kB (`shell.html` is a support file to run the Wasm). - -`roundtrip.c` is an example to use with the optional [amalgamated library](../create_single_file_library.sh) showing compression the decompression. - -The example files in this directory are released under a [Creative Commons Zero license](https://creativecommons.org/publicdomain/zero/1.0/) (or Public Domain, whichever is applicable in your jurisdiction). diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/emscripten.c b/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/emscripten.c deleted file mode 100644 index 10dae86..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/emscripten.c +++ /dev/null @@ -1,340 +0,0 @@ -/** - * \file emscripten.c - * Emscripten example of using the single-file \c zstddeclib. Draws a rotating - * textured quad with data from the in-line Zstd compressed DXT1 texture (DXT1 - * being hardware compression, further compressed with Zstd). - * \n - * Compile using: - * \code - * export CC_FLAGS="-Wall -Wextra -Werror -Os -g0 -flto --llvm-lto 3 -lGL -DNDEBUG=1" - * export EM_FLAGS="-s WASM=1 -s ENVIRONMENT=web --shell-file shell.html --closure 1" - * emcc $CC_FLAGS $EM_FLAGS -o out.html emscripten.c - * \endcode - * - * \author Carl Woffenden, Numfum GmbH (released under a CC0 license) - */ - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "../zstddeclib.c" - -//************************* Test Data (DXT texture) **************************/ - -/** - * Zstd compressed DXT1 256x256 texture source. - * \n - * See \c testcard.png for the original. - */ -static uint8_t const srcZstd[] = { -#include "testcard-zstd.inl" -}; - -/** - * Uncompressed size of \c #srcZstd. - */ -#define DXT1_256x256 32768 - -/** - * Destination for decoding \c #srcZstd. - */ -static uint8_t dstDxt1[DXT1_256x256] = {}; - -#ifndef ZSTD_VERSION_MAJOR -/** - * For the case where the decompression library hasn't been included we add a - * dummy function to fake the process and stop the buffers being optimised out. - */ -size_t ZSTD_decompress(void* dst, size_t dstLen, const void* src, size_t srcLen) { - return (memcmp(dst, src, (srcLen < dstLen) ? srcLen : dstLen)) ? dstLen : 0; -} -#endif - -//*************************** Program and Shaders ***************************/ - -/** - * Program object ID. - */ -static GLuint progId = 0; - -/** - * Vertex shader ID. - */ -static GLuint vertId = 0; - -/** - * Fragment shader ID. - */ -static GLuint fragId = 0; - -//********************************* Uniforms *********************************/ - -/** - * Quad rotation angle ID. - */ -static GLint uRotId = -1; - -/** - * Draw colour ID. - */ -static GLint uTx0Id = -1; - -//******************************* Shader Source ******************************/ - -/** - * Vertex shader to draw texture mapped polys with an applied rotation. - */ -static GLchar const vertShader2D[] = -#if GL_ES_VERSION_2_0 - "#version 100\n" - "precision mediump float;\n" -#else - "#version 120\n" -#endif - "uniform float uRot;" // rotation - "attribute vec2 aPos;" // vertex position coords - "attribute vec2 aUV0;" // vertex texture UV0 - "varying vec2 vUV0;" // (passed to fragment shader) - "void main() {" - " float cosA = cos(radians(uRot));" - " float sinA = sin(radians(uRot));" - " mat3 rot = mat3(cosA, -sinA, 0.0," - " sinA, cosA, 0.0," - " 0.0, 0.0, 1.0);" - " gl_Position = vec4(rot * vec3(aPos, 1.0), 1.0);" - " vUV0 = aUV0;" - "}"; - -/** - * Fragment shader for the above polys. - */ -static GLchar const fragShader2D[] = -#if GL_ES_VERSION_2_0 - "#version 100\n" - "precision mediump float;\n" -#else - "#version 120\n" -#endif - "uniform sampler2D uTx0;" - "varying vec2 vUV0;" // (passed from fragment shader) - "void main() {" - " gl_FragColor = texture2D(uTx0, vUV0);" - "}"; - -/** - * Helper to compile a shader. - * - * \param type shader type - * \param text shader source - * \return the shader ID (or zero if compilation failed) - */ -static GLuint compileShader(GLenum const type, const GLchar* text) { - GLuint shader = glCreateShader(type); - if (shader) { - glShaderSource (shader, 1, &text, NULL); - glCompileShader(shader); - GLint compiled; - glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); - if (compiled) { - return shader; - } else { - GLint logLen; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLen); - if (logLen > 1) { - GLchar* logStr = malloc(logLen); - glGetShaderInfoLog(shader, logLen, NULL, logStr); - #ifndef NDEBUG - printf("Shader compilation error: %s\n", logStr); - #endif - free(logStr); - } - glDeleteShader(shader); - } - } - return 0; -} - -//********************************** Helpers *********************************/ - -/** - * Vertex position index. - */ -#define GL_VERT_POSXY_ID 0 - -/** - * Vertex UV0 index. - */ -#define GL_VERT_TXUV0_ID 1 - - /** - * \c GL vec2 storage type. - */ -struct vec2 { - float x; - float y; -}; - -/** - * Combined 2D vertex and 2D texture coordinates. - */ -struct posTex2d { - struct vec2 pos; - struct vec2 uv0; -}; - -//****************************************************************************/ - -/** - * Current quad rotation angle (in degrees, updated per frame). - */ -static float rotDeg = 0.0f; - -/** - * Emscripten (single) GL context. - */ -static EMSCRIPTEN_WEBGL_CONTEXT_HANDLE glCtx = 0; - -/** - * Emscripten resize handler. - */ -static EM_BOOL resize(int type, const EmscriptenUiEvent* e, void* data) { - double surfaceW; - double surfaceH; - if (emscripten_get_element_css_size ("#canvas", &surfaceW, &surfaceH) == EMSCRIPTEN_RESULT_SUCCESS) { - emscripten_set_canvas_element_size("#canvas", surfaceW, surfaceH); - if (glCtx) { - glViewport(0, 0, (int) surfaceW, (int) surfaceH); - } - } - (void) type; - (void) data; - (void) e; - return EM_FALSE; -} - -/** - * Boilerplate to create a WebGL context. - */ -static EM_BOOL initContext() { - // Default attributes - EmscriptenWebGLContextAttributes attr; - emscripten_webgl_init_context_attributes(&attr); - if ((glCtx = emscripten_webgl_create_context("#canvas", &attr))) { - // Bind the context and fire a resize to get the initial size - emscripten_webgl_make_context_current(glCtx); - emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, EM_FALSE, resize); - resize(0, NULL, NULL); - return EM_TRUE; - } - return EM_FALSE; -} - -/** - * Called once per frame (clears the screen and draws the rotating quad). - */ -static void tick() { - glClearColor(1.0f, 0.0f, 1.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - if (uRotId >= 0) { - glUniform1f(uRotId, rotDeg); - rotDeg += 0.1f; - if (rotDeg >= 360.0f) { - rotDeg -= 360.0f; - } - } - - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); - glFlush(); -} - -/** - * Creates the GL context, shaders and quad data, decompresses the Zstd data - * and 'uploads' the resulting texture. - * - * As a (naive) comparison, removing Zstd and building with "-Os -g0 s WASM=1 - * -lGL emscripten.c" results in a 15kB WebAssembly file; re-adding Zstd - * increases the Wasm by 26kB. - */ -int main() { - if (initContext()) { - // Compile shaders and set the initial GL state - if ((progId = glCreateProgram())) { - vertId = compileShader(GL_VERTEX_SHADER, vertShader2D); - fragId = compileShader(GL_FRAGMENT_SHADER, fragShader2D); - - glBindAttribLocation(progId, GL_VERT_POSXY_ID, "aPos"); - glBindAttribLocation(progId, GL_VERT_TXUV0_ID, "aUV0"); - - glAttachShader(progId, vertId); - glAttachShader(progId, fragId); - glLinkProgram (progId); - glUseProgram (progId); - uRotId = glGetUniformLocation(progId, "uRot"); - uTx0Id = glGetUniformLocation(progId, "uTx0"); - if (uTx0Id >= 0) { - glUniform1i(uTx0Id, 0); - } - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glDisable(GL_DITHER); - - glCullFace(GL_BACK); - glEnable(GL_CULL_FACE); - } - - GLuint vertsBuf = 0; - GLuint indexBuf = 0; - GLuint txName = 0; - // Create the textured quad (vert positions then UVs) - struct posTex2d verts2d[] = { - {{-0.85f, -0.85f}, {0.0f, 0.0f}}, // BL - {{ 0.85f, -0.85f}, {1.0f, 0.0f}}, // BR - {{-0.85f, 0.85f}, {0.0f, 1.0f}}, // TL - {{ 0.85f, 0.85f}, {1.0f, 1.0f}}, // TR - }; - uint16_t index2d[] = { - 0, 1, 2, - 2, 1, 3, - }; - glGenBuffers(1, &vertsBuf); - glBindBuffer(GL_ARRAY_BUFFER, vertsBuf); - glBufferData(GL_ARRAY_BUFFER, - sizeof(verts2d), verts2d, GL_STATIC_DRAW); - glVertexAttribPointer(GL_VERT_POSXY_ID, 2, - GL_FLOAT, GL_FALSE, sizeof(struct posTex2d), 0); - glVertexAttribPointer(GL_VERT_TXUV0_ID, 2, - GL_FLOAT, GL_FALSE, sizeof(struct posTex2d), - (void*) offsetof(struct posTex2d, uv0)); - glGenBuffers(1, &indexBuf); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - sizeof(index2d), index2d, GL_STATIC_DRAW); - glEnableVertexAttribArray(GL_VERT_POSXY_ID); - glEnableVertexAttribArray(GL_VERT_TXUV0_ID); - - // Decode the Zstd data and create the texture - if (ZSTD_decompress(dstDxt1, DXT1_256x256, srcZstd, sizeof srcZstd) == DXT1_256x256) { - glGenTextures(1, &txName); - glBindTexture(GL_TEXTURE_2D, txName); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glCompressedTexImage2D(GL_TEXTURE_2D, 0, - GL_COMPRESSED_RGB_S3TC_DXT1_EXT, - 256, 256, 0, DXT1_256x256, dstDxt1); - } else { - printf("Failed to decode Zstd data\n"); - } - emscripten_set_main_loop(tick, 0, EM_FALSE); - emscripten_exit_with_live_runtime(); - } - return EXIT_FAILURE; -} diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/roundtrip.c b/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/roundtrip.c deleted file mode 100644 index b228de8..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/roundtrip.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * \file roundtrip.c - * In this example we include \c zstd.h and compile separately the amalgamated - * \c zstd.c: - * \code - * cc -Wall -Wextra -Werror -I. -Os -g0 zstd.c examples/roundtrip.c - * \endcode - * - * \author Carl Woffenden, Numfum GmbH (released under a CC0 license) - */ - -#include -#include -#include -#include -#include - -#include "zstd.h" - -//************************** Test Data (DXT texture) **************************/ - -/** - * Raw test data (borrowed from the Emscripten example). - * \n - * See \c testcard.png for the original. - */ -static uint8_t const rawData[] = { -#include "testcard-dxt1.inl" -}; - -#ifndef ZSTD_VERSION_MAJOR -/* - * For the case where the decompression library hasn't been included we add - * dummy functions to fake the process and stop the buffers being optimised out. - */ -size_t ZSTD_compressBound(size_t maxSrc) { - return maxSrc + 32; -} -int ZSTD_maxCLevel(void) { - return 20; -} -size_t ZSTD_compress(void* dst, size_t dstLen, const void* src, size_t srcLen, int level) { - return (memcmp(dst, src, (srcLen < dstLen) ? srcLen : dstLen)) ? level : dstLen; -} -unsigned ZSTD_isError(size_t code) { - return ((int) code) < 0; -} -size_t ZSTD_decompress(void* dst, size_t dstLen, const void* src, size_t srcLen) { - return (memcmp(dst, src, (srcLen < dstLen) ? srcLen : dstLen)) ? 0 : dstLen; -} -#endif - -//*****************************************************************************/ - -/** - * Simple single-file test to compress \c rawData, decompress the result, then - * compare the decompressed version with the original. - */ -int main() { - size_t bounds = ZSTD_compressBound(sizeof rawData); - void* compBuf = malloc(bounds); - void* testBuf = malloc(sizeof rawData); - int compare = -1; - if (compBuf && testBuf) { - size_t compSize = ZSTD_compress(compBuf, bounds, rawData, sizeof rawData, ZSTD_maxCLevel()); - if (!ZSTD_isError(compSize)) { - printf("Compression: PASSED (size: %lu, uncompressed: %lu)\n", (unsigned long) compSize, (unsigned long) (sizeof rawData)); - size_t decSize = ZSTD_decompress(testBuf, sizeof rawData, compBuf, compSize); - if (!ZSTD_isError(decSize)) { - printf("Decompression: PASSED\n"); - compare = memcmp(rawData, testBuf, decSize); - printf("Byte comparison: %s\n", (compare == 0) ? "PASSED" : "FAILED"); - } else { - printf("Decompression: FAILED\n"); - } - } else { - printf("Compression: FAILED\n"); - } - free(compBuf); - free(testBuf); - } - return (compare == 0) ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/shell.html b/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/shell.html deleted file mode 100644 index 5beb0e6..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/shell.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - Emscripten Shell - - - - - -{{{ SCRIPT }}} - - diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/simple.c b/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/simple.c deleted file mode 100644 index ee63416..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/simple.c +++ /dev/null @@ -1,75 +0,0 @@ -/** - * \file simple.c - * Simple standalone example of using the single-file \c zstddeclib. - * - * \note In this simple example we include the amalgamated source and compile - * just this single file, but we could equally (and more conventionally) - * include \c zstd.h and compile both this file and \c zstddeclib.c (the - * resulting binaries differ slightly in size but perform the same). - * - * \author Carl Woffenden, Numfum GmbH (released under a CC0 license) - */ - -#include -#include -#include -#include -#include - -#include "../zstddeclib.c" - -//************************* Test Data (DXT texture) **************************/ - -/** - * Raw 256x256 DXT1 data (used to compare the result). - * \n - * See \c testcard.png for the original. - */ -static uint8_t const rawDxt1[] = { -#include "testcard-dxt1.inl" -}; - -/** - * Zstd compressed version of \c #rawDxt1. - * \n - * See \c testcard.png for the original. - */ -static uint8_t const srcZstd[] = { -#include "testcard-zstd.inl" -}; - -/** - * Destination for decoding \c #srcZstd. - */ -static uint8_t dstDxt1[sizeof rawDxt1] = {}; - -#ifndef ZSTD_VERSION_MAJOR -/** - * For the case where the decompression library hasn't been included we add a - * dummy function to fake the process and stop the buffers being optimised out. - */ -size_t ZSTD_decompress(void* dst, size_t dstLen, const void* src, size_t srcLen) { - return (memcmp(dst, src, (srcLen < dstLen) ? srcLen : dstLen)) ? 0 : dstLen; -} -#endif - -//****************************************************************************/ - -/** - * Simple single-file test to decompress \c #srcZstd into \c # dstDxt1 then - * compare the resulting bytes with \c #rawDxt1. - * \n - * As a (naive) comparison, removing Zstd and building with "-Os -g0 simple.c" - * results in a 44kB binary (macOS 10.14, Clang 10); re-adding Zstd increases - * the binary by 56kB (after calling \c strip). - */ -int main() { - size_t size = ZSTD_decompress(dstDxt1, sizeof dstDxt1, srcZstd, sizeof srcZstd); - int compare = memcmp(rawDxt1, dstDxt1, sizeof dstDxt1); - printf("Decompressed size: %s\n", (size == sizeof dstDxt1) ? "PASSED" : "FAILED"); - printf("Byte comparison: %s\n", (compare == 0) ? "PASSED" : "FAILED"); - if (size == sizeof dstDxt1 && compare == 0) { - return EXIT_SUCCESS; - } - return EXIT_FAILURE; -} diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/testcard-dxt1.inl b/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/testcard-dxt1.inl deleted file mode 100644 index e099e66..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/testcard-dxt1.inl +++ /dev/null @@ -1,2731 +0,0 @@ -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0x30, 0x84, 0x00, 0x55, 0x55, 0xb5, -0xde, 0xf7, 0x30, 0x84, 0x00, 0x15, 0x35, 0x20, 0xdf, 0xff, 0x30, 0x84, -0x00, 0xd4, 0x80, 0x54, 0xde, 0xf7, 0x30, 0x84, 0x00, 0x2b, 0x7e, 0x55, -0xde, 0xf7, 0x10, 0x84, 0x00, 0xa0, 0x55, 0x55, 0xdf, 0xff, 0xe7, 0x39, -0x00, 0x2a, 0x3f, 0x3f, 0x82, 0x10, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0xff, 0xff, 0x28, 0x42, 0x00, 0xff, 0xff, 0xff, 0x41, 0x08, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0x8a, 0x52, 0x00, 0x3f, 0x3f, 0x3f, -0xff, 0xff, 0x08, 0x42, 0x00, 0xa8, 0xfc, 0xfc, 0xde, 0xf7, 0x30, 0x84, -0x00, 0x02, 0x55, 0x55, 0xff, 0xff, 0x10, 0x84, 0x00, 0xfa, 0xaf, 0x55, -0xdf, 0xff, 0x30, 0x84, 0x00, 0x15, 0x20, 0x35, 0xde, 0xf7, 0x30, 0x84, -0x00, 0x54, 0x54, 0x80, 0xff, 0xff, 0x30, 0x84, 0x00, 0x55, 0x55, 0x57, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x10, 0x84, 0x15, 0x15, 0x15, 0x2d, 0xff, 0xff, 0x30, 0x84, -0x54, 0xd4, 0x88, 0x5c, 0xff, 0xff, 0x10, 0x84, 0xb5, 0xe2, 0x57, 0x55, -0x7d, 0xef, 0x30, 0x84, 0xe0, 0x55, 0x55, 0x55, 0x41, 0x08, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xff, 0xff, 0x30, 0x84, 0xd4, 0x54, 0x54, 0x54, -0x9d, 0xef, 0x30, 0x84, 0x82, 0xd5, 0x55, 0x55, 0xff, 0xff, 0x10, 0x84, -0x57, 0xe2, 0xb5, 0x55, 0xff, 0xff, 0x30, 0x84, 0x15, 0x15, 0x38, 0x2d, -0xff, 0xff, 0x10, 0x84, 0x54, 0x54, 0x54, 0x5c, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x41, 0x08, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0x9e, 0xf7, 0x10, 0x84, 0x55, 0x55, 0x35, 0xe2, -0x5c, 0xe7, 0x10, 0x84, 0xb5, 0x83, 0x5c, 0x55, 0xff, 0xff, 0x30, 0x84, -0x38, 0x15, 0x15, 0x15, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xde, 0xf7, 0x30, 0x84, -0x88, 0x94, 0x54, 0x54, 0x5c, 0xe7, 0x10, 0x84, 0x57, 0x70, 0x0d, 0xd5, -0xbe, 0xf7, 0x30, 0x84, 0x55, 0x55, 0x57, 0x62, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0xff, 0xff, 0x08, 0x42, -0x3f, 0x3f, 0x2f, 0x00, 0x51, 0x8c, 0xdf, 0xff, 0x61, 0x25, 0x01, 0x55, -0xff, 0xff, 0x49, 0x4a, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0xff, 0xff, 0x69, 0x4a, -0x2f, 0xff, 0xff, 0x00, 0x51, 0x8c, 0xff, 0xff, 0x42, 0x66, 0x60, 0x55, -0xff, 0xff, 0x28, 0x42, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0x99, 0xff, 0x00, 0x5a, -0xff, 0xff, 0xff, 0xff, 0x99, 0xff, 0x00, 0x5a, 0xff, 0xff, 0xff, 0xff, -0x99, 0xff, 0x00, 0x5a, 0xff, 0xff, 0xff, 0xff, 0x99, 0xff, 0x00, 0x5a, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0xde, 0xf7, 0x10, 0x84, 0x00, 0x55, 0xd5, 0x25, 0xbe, 0xf7, 0x30, 0x84, -0x00, 0xc9, 0x58, 0x57, 0xff, 0xff, 0x08, 0x42, 0x00, 0x3f, 0x3f, 0x3f, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, -0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, -0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x42, -0x00, 0xbc, 0xfc, 0xfc, 0xbe, 0xf7, 0x10, 0x84, 0x00, 0x58, 0xc9, 0x35, -0xff, 0xff, 0x10, 0x84, 0x00, 0x55, 0x55, 0x56, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0xf6, 0xff, 0xc1, 0x59, 0xff, 0xff, 0xff, 0xff, -0xf6, 0xff, 0xc1, 0x59, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xc1, 0x59, -0xff, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xc1, 0x59, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0x99, 0xff, 0x00, 0x5a, 0xff, 0xff, 0xff, 0xff, -0x99, 0xff, 0x00, 0x5a, 0xff, 0xff, 0xff, 0xff, 0x99, 0xff, 0x00, 0x5a, -0xff, 0xff, 0xff, 0xff, 0xe9, 0x93, 0xc7, 0x8b, 0xaa, 0xaa, 0xaa, 0x2a, -0xbe, 0xf7, 0x10, 0x84, 0x54, 0x94, 0x8c, 0x70, 0x7d, 0xef, 0x10, 0x84, -0x63, 0x5c, 0x55, 0x55, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, -0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, -0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0x71, 0x8c, 0xcf, 0x7b, 0xbf, 0xff, 0xff, 0xff, 0x9d, 0xef, 0x10, 0x84, -0x72, 0x8d, 0x95, 0x55, 0xbe, 0xf7, 0x10, 0x84, 0x15, 0x15, 0x1c, 0x23, -0xf6, 0xff, 0xc1, 0x59, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xc1, 0x59, -0xff, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xc1, 0x59, 0xff, 0xff, 0xff, 0xff, -0xf6, 0xff, 0xc1, 0x59, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0x99, 0xff, 0x00, 0x5a, 0xff, 0xff, 0xff, 0xff, 0x99, 0xff, 0x00, 0x5a, -0xff, 0xff, 0xff, 0xff, 0x56, 0xd6, 0xa1, 0x72, 0xff, 0xff, 0xff, 0x3f, -0x5c, 0xef, 0x2a, 0x94, 0x15, 0x8d, 0x73, 0x54, 0x41, 0x08, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, -0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, -0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x30, 0x84, 0x25, 0x15, 0x15, 0x15, 0x7c, 0xf7, 0x09, 0x94, -0x55, 0x5c, 0x73, 0x85, 0x09, 0x94, 0xa7, 0x8b, 0xff, 0xff, 0xff, 0xfe, -0xf6, 0xff, 0xc1, 0x59, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xc1, 0x59, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0x99, 0xff, 0x00, 0x5a, -0xff, 0xff, 0xff, 0xff, 0x7c, 0xf7, 0xc8, 0x8b, 0x55, 0x55, 0xd5, 0x35, -0x3b, 0xef, 0x09, 0x94, 0x05, 0x61, 0x58, 0x57, 0x2a, 0x9c, 0xc7, 0x8b, -0xfc, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, -0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, -0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0xf9, 0xe6, 0x60, 0x6a, 0x3f, 0xff, 0xff, 0xff, -0x9d, 0xf7, 0x09, 0x94, 0x56, 0x52, 0x49, 0x35, 0xc2, 0x72, 0xce, 0xac, -0xaa, 0xaa, 0xaa, 0xa9, 0xf6, 0xff, 0xc1, 0x59, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x10, 0x84, 0x00, 0x54, 0xd4, 0x34, -0xde, 0xf7, 0xef, 0x7b, 0x00, 0x73, 0x5c, 0x57, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, -0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, -0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0xde, 0xf7, 0xef, 0x7b, 0x00, 0x73, 0xcd, 0x35, -0xff, 0xff, 0x10, 0x84, 0x00, 0x15, 0x15, 0x17, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0x5d, 0xf7, 0xef, 0xaa, 0x55, 0x55, 0xd5, 0x35, -0xde, 0xf7, 0xef, 0x7b, 0xcc, 0x70, 0x5c, 0x54, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, -0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, -0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x2c, 0x63, 0xd3, 0x9c, 0x6a, 0xaa, 0xaa, 0xaa, 0xde, 0xf7, 0xef, 0x7b, -0x1c, 0x33, 0x0d, 0x35, 0xd4, 0x62, 0x57, 0x94, 0xaa, 0xaa, 0xaa, 0xa9, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xd8, 0xdd, 0xcb, 0x99, 0xff, 0xff, 0xff, 0x3f, -0xdb, 0xee, 0x30, 0xb3, 0x85, 0x61, 0x50, 0x54, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, -0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, -0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x1d, 0xe7, 0xb6, 0x83, 0x54, 0x52, 0x41, 0x85, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0x30, 0xb3, 0x0f, 0xb3, 0xff, 0xff, 0xff, 0xbf, -0x9e, 0xf7, 0x30, 0xb3, 0x35, 0xcd, 0x71, 0x5a, 0xf2, 0xbb, 0xae, 0xaa, -0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, -0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, -0x76, 0xfe, 0x01, 0xd8, 0xff, 0xff, 0xff, 0xff, 0x76, 0xfe, 0x01, 0xd8, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, -0xff, 0xff, 0xff, 0xff, 0xda, 0xf7, 0x81, 0xf7, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x5e, 0xef, 0x96, 0x7b, -0x15, 0xd5, 0x55, 0x55, 0x9e, 0xf7, 0xb6, 0x7b, 0x57, 0x5c, 0x53, 0x69, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0x7d, 0xf7, 0x2f, 0xb3, 0x95, 0x35, 0xc5, 0x69, 0xdb, 0xee, 0x0f, 0xb3, -0x54, 0x57, 0x55, 0x55, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0x5e, 0xef, 0xf2, 0x49, 0x8f, 0x3f, 0xbf, 0xff, 0x7e, 0xef, 0x96, 0x7b, -0x55, 0x57, 0x54, 0x5a, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x7d, 0xf7, 0x2f, 0xb3, 0x55, 0x55, 0x95, 0x35, 0x7d, 0xf7, 0x30, 0xb3, -0x53, 0x5c, 0x56, 0x55, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0x7e, 0xef, 0xb6, 0x83, 0x71, 0x4d, 0xa5, 0x15, -0x73, 0x5a, 0xb8, 0x9c, 0xaa, 0xaa, 0xaa, 0xa9, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xfc, 0xee, 0x70, 0xb3, -0xc5, 0x49, 0x51, 0x58, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0x19, 0xa5, 0xaf, 0x28, 0x2a, 0xaa, 0xaa, 0xaa, 0x1d, 0xe7, 0xd6, 0x83, -0x54, 0x58, 0x51, 0x49, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0xff, 0xff, 0x10, 0x84, -0x15, 0x15, 0x35, 0x00, 0x9e, 0xf7, 0x30, 0xb3, 0x54, 0x57, 0x55, 0x55, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, -0x41, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x08, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0x3d, 0xe7, 0xb6, 0x7b, 0xc5, 0x35, 0x15, 0xd5, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0x08, 0x42, -0x00, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x71, 0x8c, 0x00, 0x11, 0x1b, 0x14, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x1f, 0x62, 0x1e, 0x5a, 0xea, 0xaa, 0xaa, 0xea, -0x1f, 0x62, 0xfd, 0x59, 0xfe, 0xfa, 0xfe, 0xfe, 0x1e, 0x5a, 0xfd, 0x59, -0x5f, 0x57, 0x57, 0x57, 0xfd, 0x59, 0xdb, 0x51, 0xfa, 0xfa, 0xfa, 0xfa, -0xfc, 0x51, 0xba, 0x51, 0xfe, 0xfe, 0xfa, 0xfe, 0xda, 0x51, 0x99, 0x49, -0xea, 0xea, 0xe8, 0xea, 0xb9, 0x51, 0x98, 0x49, 0x7e, 0x7e, 0x7e, 0x7e, -0x97, 0x49, 0x76, 0x41, 0xe8, 0xe8, 0xe8, 0xe8, 0x97, 0x49, 0x75, 0x41, -0x5f, 0x5f, 0x5f, 0x5f, 0x75, 0x41, 0x32, 0x39, 0xea, 0xea, 0xea, 0xea, -0x53, 0x39, 0x32, 0x39, 0x7e, 0x7e, 0x5e, 0x7e, 0x31, 0x39, 0x10, 0x31, -0xfa, 0xfa, 0x78, 0x7a, 0x0f, 0x31, 0xcd, 0x28, 0xa0, 0x80, 0x80, 0x80, -0xee, 0x30, 0xed, 0x28, 0x5e, 0x7e, 0x5e, 0x5e, 0xcc, 0x28, 0xaa, 0x20, -0xa0, 0xa0, 0xa0, 0xa0, 0xcc, 0x28, 0xaa, 0x20, 0x5f, 0x5f, 0x5f, 0x5f, -0xaa, 0x20, 0x88, 0x18, 0xfa, 0xfa, 0xfa, 0xfa, 0x88, 0x18, 0x66, 0x18, -0xe8, 0xe8, 0xe8, 0xe8, 0x87, 0x18, 0x45, 0x10, 0xfa, 0xfa, 0xfa, 0xfa, -0x66, 0x10, 0x44, 0x10, 0x7e, 0x7e, 0x7e, 0x7e, 0x44, 0x10, 0x22, 0x08, -0xa8, 0xe8, 0xa8, 0xe8, 0x44, 0x10, 0x22, 0x08, 0x5f, 0x7f, 0x7f, 0x7f, -0x22, 0x08, 0x01, 0x08, 0xea, 0xfa, 0xfa, 0xea, 0x01, 0x08, 0x00, 0x00, -0xaa, 0xea, 0xaa, 0xaa, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x51, 0x8c, -0x00, 0x50, 0x78, 0x44, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x3c, 0xe7, 0x69, 0x4a, 0xbf, 0x3f, 0x2f, 0x8f, -0xff, 0xff, 0xef, 0x7b, 0x16, 0x17, 0x15, 0x15, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x1f, 0x62, 0x1e, 0x5a, 0xaa, 0xea, 0xaa, 0xea, 0x1f, 0x62, 0xfd, 0x59, -0xfe, 0xfe, 0xfe, 0xfe, 0x1e, 0x5a, 0xfd, 0x59, 0x57, 0x57, 0x57, 0x57, -0xfd, 0x59, 0xdb, 0x51, 0xfa, 0xfa, 0xfa, 0xfa, 0xdb, 0x51, 0xb9, 0x51, -0xa0, 0xa0, 0xa0, 0x80, 0xba, 0x51, 0xb9, 0x49, 0xe8, 0xe8, 0xe8, 0xe8, -0xda, 0x51, 0x98, 0x49, 0x5f, 0x7f, 0x7f, 0x5f, 0x97, 0x49, 0x76, 0x41, -0xe8, 0xe8, 0xe8, 0xe0, 0x97, 0x49, 0x75, 0x41, 0x57, 0x57, 0x5f, 0x5f, -0x75, 0x41, 0x32, 0x39, 0xea, 0xea, 0xea, 0xea, 0x53, 0x39, 0x32, 0x39, -0x5c, 0x5e, 0x7e, 0x5e, 0x32, 0x39, 0x0f, 0x31, 0xfa, 0xfa, 0xfa, 0xfa, -0x0f, 0x31, 0xee, 0x28, 0xe0, 0xe0, 0xa0, 0xa0, 0x10, 0x31, 0xed, 0x28, -0x5f, 0x5f, 0x5f, 0x5f, 0xcc, 0x28, 0xcb, 0x20, 0xe0, 0xe8, 0xe8, 0xe0, -0xcc, 0x28, 0xaa, 0x20, 0x5f, 0x5f, 0x5f, 0x5f, 0xa9, 0x20, 0x88, 0x18, -0xe8, 0xe8, 0xe8, 0xe8, 0x88, 0x18, 0x66, 0x18, 0xe8, 0xe8, 0xe8, 0xe8, -0x67, 0x18, 0x65, 0x10, 0xfe, 0xfa, 0xfe, 0xfa, 0x66, 0x10, 0x44, 0x10, -0x7e, 0x7e, 0x7e, 0x7e, 0x44, 0x10, 0x22, 0x08, 0xa8, 0xa8, 0xa8, 0xa8, -0x44, 0x10, 0x22, 0x08, 0x5f, 0x7f, 0x7f, 0x7f, 0x22, 0x08, 0x01, 0x08, -0xf8, 0xe8, 0xea, 0xea, 0x01, 0x08, 0x00, 0x00, 0xaa, 0xe8, 0xea, 0xe8, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x10, 0x84, 0xe4, 0x34, 0x94, 0xd4, -0x3c, 0xe7, 0x69, 0x4a, 0xff, 0xff, 0xfe, 0xfc, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x9d, 0xef, 0x30, 0x84, 0x4d, 0x79, 0x51, 0x5a, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x1f, 0x62, 0x1e, 0x5a, -0xea, 0xea, 0xea, 0xea, 0x1f, 0x62, 0xfd, 0x59, 0xfe, 0xfe, 0xfa, 0xfe, -0x1e, 0x5a, 0xfd, 0x59, 0x57, 0x5f, 0x57, 0x57, 0xfd, 0x59, 0xdb, 0x51, -0xfa, 0xfa, 0xfa, 0xfa, 0xdb, 0x51, 0xba, 0x51, 0xe0, 0xe0, 0xe0, 0xe0, -0xba, 0x51, 0xb9, 0x49, 0xe8, 0xe8, 0xe8, 0xe8, 0xda, 0x51, 0x98, 0x49, -0x5f, 0x5f, 0x5f, 0x5f, 0x97, 0x49, 0x76, 0x41, 0xe8, 0xe0, 0xe8, 0xe0, -0x97, 0x49, 0x75, 0x41, 0x5f, 0x5f, 0x5f, 0x5f, 0x75, 0x41, 0x32, 0x39, -0xea, 0xea, 0xea, 0xea, 0x53, 0x39, 0x32, 0x39, 0x7e, 0x7a, 0x7a, 0x7e, -0x31, 0x39, 0x10, 0x31, 0x78, 0xf8, 0xf8, 0x78, 0x0f, 0x31, 0xee, 0x28, -0xa0, 0xe0, 0xa0, 0xe0, 0x10, 0x31, 0xed, 0x28, 0x5f, 0x5f, 0x5f, 0x5f, -0xed, 0x28, 0xaa, 0x20, 0xea, 0xea, 0xea, 0xea, 0xcc, 0x28, 0xaa, 0x20, -0x5f, 0x5f, 0x5f, 0x5f, 0xaa, 0x20, 0x88, 0x18, 0xfa, 0xfa, 0xfa, 0xfa, -0x88, 0x18, 0x66, 0x18, 0xe8, 0xe8, 0xe8, 0xe8, 0x67, 0x18, 0x65, 0x10, -0xfa, 0xfa, 0xf8, 0xfa, 0x66, 0x10, 0x44, 0x10, 0x7e, 0x7e, 0x7e, 0x7e, -0x44, 0x10, 0x22, 0x08, 0xa8, 0xa8, 0xa8, 0xa8, 0x44, 0x10, 0x22, 0x08, -0x5f, 0x5f, 0x7f, 0x5f, 0x22, 0x08, 0x01, 0x08, 0xea, 0xea, 0xea, 0xe8, -0x01, 0x08, 0x00, 0x00, 0xea, 0xea, 0xe8, 0xea, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x08, 0x42, 0xfc, 0xfc, 0xfc, 0xfc, 0x9e, 0xf7, 0x30, 0x84, -0x5c, 0x5b, 0x51, 0x69, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0xff, 0xff, 0xef, 0x7b, 0x55, 0xd5, 0x95, 0x00, 0xbe, 0xf7, 0x10, 0x84, -0x5c, 0x54, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x1f, 0x62, 0x1e, 0x5a, 0xea, 0xaa, 0xea, 0xea, -0x1f, 0x62, 0xfd, 0x59, 0xfe, 0xfe, 0xfe, 0xfe, 0x1e, 0x5a, 0xfd, 0x59, -0x57, 0x57, 0x57, 0x57, 0xfd, 0x59, 0xdb, 0x51, 0xea, 0xfa, 0xfa, 0xea, -0xdb, 0x51, 0xb9, 0x51, 0x80, 0x80, 0xa0, 0x80, 0xba, 0x51, 0xb8, 0x49, -0xa8, 0xa8, 0xa8, 0xa0, 0xb9, 0x51, 0x98, 0x49, 0x7e, 0x7e, 0x7e, 0x7e, -0x97, 0x49, 0x76, 0x41, 0xa8, 0xe8, 0xe8, 0xe0, 0x97, 0x49, 0x75, 0x41, -0x5f, 0x5f, 0x57, 0x5f, 0x75, 0x41, 0x32, 0x39, 0xea, 0xea, 0xea, 0xea, -0x53, 0x39, 0x32, 0x39, 0x58, 0x7e, 0x7a, 0x7a, 0x32, 0x39, 0x0f, 0x31, -0xfa, 0xfa, 0xfa, 0xfa, 0x0f, 0x31, 0xee, 0x28, 0xa0, 0xe0, 0xe0, 0xe0, -0xef, 0x30, 0xed, 0x28, 0x5e, 0x7f, 0x5e, 0x7f, 0xed, 0x28, 0xaa, 0x20, -0xea, 0xea, 0xea, 0xea, 0xcc, 0x28, 0xaa, 0x20, 0x5f, 0x5f, 0x5f, 0x5f, -0xa9, 0x20, 0x88, 0x18, 0xf8, 0xe8, 0xe8, 0xe8, 0x88, 0x18, 0x66, 0x18, -0xe8, 0xe8, 0xe8, 0xe8, 0x67, 0x18, 0x65, 0x10, 0xfa, 0xfa, 0xfa, 0xfa, -0x66, 0x10, 0x44, 0x10, 0x7e, 0x7e, 0x7e, 0x7e, 0x44, 0x10, 0x22, 0x08, -0xa8, 0xa8, 0xa8, 0xe0, 0x44, 0x10, 0x22, 0x08, 0x7f, 0x7f, 0x5f, 0x5f, -0x22, 0x08, 0x01, 0x08, 0xfa, 0xf8, 0xfa, 0xf8, 0x01, 0x08, 0x00, 0x00, -0xa8, 0xa8, 0xa8, 0xa8, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0xbe, 0xf7, 0x10, 0x84, 0x4d, 0xc5, 0xb5, 0x00, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0xff, 0xff, 0x30, 0x84, -0x00, 0xe5, 0x45, 0x6d, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x8c, 0xf8, 0x6b, 0xf0, 0xaa, 0xaa, 0xaa, 0xea, 0x8c, 0xf0, 0x6b, 0xf0, -0xff, 0xdf, 0xff, 0xff, 0x8b, 0xf0, 0x6b, 0xe8, 0x5f, 0x5f, 0x7f, 0x5f, -0x6b, 0xe8, 0x6a, 0xd8, 0xfa, 0xfa, 0xfa, 0xfa, 0x6a, 0xd8, 0x6a, 0xd0, -0xe0, 0xa0, 0xe0, 0xe0, 0x6a, 0xd0, 0x69, 0xc8, 0xf8, 0xf8, 0x78, 0xf8, -0x69, 0xc8, 0x49, 0xb8, 0xa8, 0xe8, 0xe8, 0xe8, 0x69, 0xc0, 0x48, 0xb0, -0xfa, 0xfa, 0xfa, 0xfe, 0x69, 0xb8, 0x48, 0xa8, 0x5f, 0x5f, 0x5f, 0x5f, -0x48, 0xa8, 0x47, 0x98, 0x7a, 0xfa, 0xfa, 0xfa, 0x47, 0x98, 0x47, 0x90, -0x7c, 0x5c, 0x58, 0x5c, 0x47, 0x90, 0x46, 0x80, 0x7a, 0x7e, 0x7a, 0x7e, -0x46, 0x80, 0x45, 0x70, 0xf8, 0xf8, 0xf8, 0xf8, 0x45, 0x70, 0x25, 0x68, -0x78, 0x78, 0x78, 0x78, 0x25, 0x68, 0x24, 0x58, 0xfa, 0xfa, 0xfa, 0xfa, -0x24, 0x58, 0x24, 0x50, 0x78, 0x78, 0x78, 0x78, 0x24, 0x50, 0x23, 0x40, -0xfa, 0xfa, 0xfa, 0xfa, 0x23, 0x40, 0x23, 0x38, 0x78, 0x78, 0x78, 0x78, -0x23, 0x38, 0x02, 0x28, 0xea, 0xea, 0xea, 0xea, 0x22, 0x30, 0x02, 0x20, -0xfa, 0xfe, 0xfa, 0xfa, 0x02, 0x20, 0x01, 0x18, 0xe8, 0xe8, 0xe8, 0xf8, -0x01, 0x18, 0x01, 0x10, 0xf8, 0xf8, 0xf8, 0xe8, 0x01, 0x10, 0x00, 0x08, -0xe8, 0xe8, 0xe8, 0xe0, 0x01, 0x10, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0xff, 0xff, 0x10, 0x84, 0x00, 0xd5, 0x55, 0x55, 0xff, 0xff, 0x10, 0x84, -0x00, 0x56, 0x54, 0x5e, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0x7d, 0xef, 0x10, 0x84, 0x79, 0x51, 0x53, 0x5a, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x6c, 0xf8, 0x6b, 0xf0, -0xe8, 0xa8, 0xe8, 0xa8, 0x8b, 0xf8, 0x6b, 0xe8, 0xea, 0xfa, 0xfa, 0xea, -0x8b, 0xf0, 0x6b, 0xe8, 0x57, 0x57, 0x57, 0x57, 0x6b, 0xe8, 0x6a, 0xd8, -0xfa, 0xfa, 0xfa, 0xfa, 0x6a, 0xd8, 0x6a, 0xd0, 0xa0, 0xa0, 0xa0, 0xe0, -0x6a, 0xd0, 0x69, 0xc8, 0x60, 0x68, 0xf8, 0xe8, 0x6a, 0xd0, 0x69, 0xc0, -0x5f, 0x5f, 0x5f, 0x5f, 0x69, 0xc0, 0x48, 0xb0, 0xfa, 0xfa, 0xfa, 0xfa, -0x68, 0xb0, 0x48, 0xa8, 0x7e, 0x7a, 0x7e, 0x7a, 0x48, 0xa8, 0x47, 0x98, -0x7a, 0xfa, 0x7a, 0xfa, 0x47, 0x90, 0x47, 0x98, 0x09, 0x09, 0x09, 0x09, -0x47, 0x90, 0x46, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x46, 0x80, 0x25, 0x70, -0xe8, 0xe8, 0xe8, 0xf8, 0x46, 0x78, 0x25, 0x68, 0x7e, 0x7e, 0x7e, 0x7e, -0x45, 0x68, 0x24, 0x58, 0xfa, 0xfe, 0xfa, 0xfa, 0x24, 0x58, 0x24, 0x50, -0x78, 0x78, 0x78, 0x78, 0x24, 0x50, 0x23, 0x40, 0xfa, 0xfa, 0xfa, 0xfa, -0x23, 0x40, 0x23, 0x38, 0x78, 0x78, 0x78, 0x78, 0x23, 0x38, 0x02, 0x28, -0xea, 0xea, 0xfa, 0xea, 0x02, 0x30, 0x22, 0x20, 0xfe, 0xfe, 0xfa, 0xfa, -0x22, 0x28, 0x01, 0x18, 0x7e, 0x7e, 0xfe, 0xfe, 0x01, 0x18, 0x01, 0x10, -0xe8, 0xe8, 0xe8, 0xe8, 0x01, 0x10, 0x00, 0x08, 0xe8, 0xe8, 0xe8, 0xe0, -0x01, 0x08, 0x00, 0x08, 0xff, 0xff, 0xfb, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x7d, 0xef, 0x10, 0x84, 0x5b, 0x51, 0x71, 0x69, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xdf, 0xff, 0x10, 0x84, 0x54, 0x54, 0xd4, 0x94, -0x1c, 0xe7, 0xef, 0x7b, 0x5c, 0x54, 0x54, 0x56, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x8c, 0xf8, 0x6b, 0xf0, 0xfa, 0xea, 0xea, 0xea, -0x8c, 0xf0, 0x6b, 0xf0, 0xfa, 0xfe, 0xfa, 0xff, 0x8b, 0xf0, 0x6b, 0xe8, -0x5f, 0x5f, 0x5e, 0x5f, 0x6b, 0xe8, 0x6a, 0xd8, 0xfa, 0xfa, 0xfa, 0xfa, -0x6a, 0xd8, 0x6a, 0xd0, 0xe0, 0xa0, 0xa0, 0xe0, 0x6a, 0xd0, 0x69, 0xc8, -0xf8, 0xe8, 0xf8, 0xf8, 0x6a, 0xc8, 0x69, 0xc0, 0x7e, 0x7e, 0x5e, 0x5e, -0x69, 0xc0, 0x48, 0xb0, 0xfa, 0xfa, 0xfa, 0xfa, 0x68, 0xb0, 0x48, 0xa8, -0x7e, 0x5e, 0x7a, 0x7e, 0x48, 0xa8, 0x47, 0x98, 0x7a, 0x7a, 0x7a, 0xfa, -0x47, 0x90, 0x47, 0x98, 0x09, 0x09, 0x09, 0x09, 0x47, 0x90, 0x46, 0x80, -0x7e, 0x7e, 0x7a, 0x7e, 0x46, 0x80, 0x25, 0x70, 0xfa, 0xea, 0xea, 0xea, -0x46, 0x78, 0x25, 0x68, 0x7e, 0x7e, 0x7e, 0x7e, 0x45, 0x68, 0x24, 0x58, -0xfe, 0xfa, 0xfe, 0xfe, 0x24, 0x58, 0x24, 0x50, 0x78, 0x78, 0x78, 0x78, -0x24, 0x50, 0x23, 0x40, 0xfa, 0xfa, 0xfa, 0xfa, 0x23, 0x40, 0x23, 0x38, -0x78, 0x78, 0x78, 0x78, 0x23, 0x38, 0x22, 0x28, 0xea, 0xfa, 0xfa, 0xfa, -0x22, 0x30, 0x02, 0x20, 0xfa, 0xfe, 0xfa, 0xfa, 0x22, 0x28, 0x01, 0x18, -0xfe, 0xfe, 0xfe, 0xfe, 0x01, 0x18, 0x01, 0x10, 0xe8, 0xe8, 0xe8, 0xf8, -0x01, 0x10, 0x00, 0x08, 0xe8, 0xe8, 0xe0, 0xe8, 0x01, 0x10, 0x00, 0x00, -0xfe, 0xfa, 0xfa, 0xfe, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x7d, 0xef, 0x10, 0x84, 0x4d, 0x45, 0xe5, 0xa5, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xff, 0xff, 0x10, 0x84, 0x94, 0x14, 0xb4, 0x00, 0xdf, 0xff, 0xef, 0x7b, -0x57, 0x55, 0x55, 0x00, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0x8c, 0xf8, 0x6b, 0xf0, 0xea, 0xea, 0xea, 0xea, 0x8c, 0xf0, 0x6b, 0xf0, -0xff, 0xff, 0xff, 0xfb, 0x6b, 0xf0, 0x6b, 0xe0, 0xea, 0xfa, 0xea, 0xfa, -0x6b, 0xe8, 0x6a, 0xd8, 0xfa, 0xfa, 0xfa, 0xfa, 0x6a, 0xd8, 0x6a, 0xd0, -0xe0, 0xe0, 0xa0, 0xe0, 0x6a, 0xd0, 0x69, 0xc8, 0x70, 0xe8, 0x78, 0xe8, -0x6a, 0xd0, 0x69, 0xc0, 0x5f, 0x5f, 0x5f, 0x5f, 0x69, 0xc0, 0x48, 0xb0, -0xfe, 0xfe, 0xfa, 0x7a, 0x68, 0xb0, 0x48, 0xa8, 0x7a, 0x7a, 0x7e, 0x7a, -0x48, 0xa8, 0x47, 0x98, 0xfa, 0xfa, 0xfa, 0xfa, 0x47, 0x90, 0x47, 0x98, -0x09, 0x09, 0x09, 0x09, 0x47, 0x90, 0x46, 0x80, 0x7a, 0x7a, 0x7e, 0x7e, -0x46, 0x80, 0x25, 0x70, 0xe8, 0xe8, 0xe8, 0xe8, 0x45, 0x70, 0x25, 0x68, -0x78, 0x78, 0x78, 0x78, 0x25, 0x68, 0x24, 0x58, 0xfa, 0xfa, 0xfa, 0xfa, -0x24, 0x58, 0x24, 0x50, 0x78, 0x78, 0x78, 0x78, 0x24, 0x50, 0x23, 0x40, -0xfa, 0xfa, 0xfa, 0xfa, 0x23, 0x40, 0x23, 0x38, 0x78, 0x78, 0x78, 0x78, -0x23, 0x38, 0x02, 0x28, 0xea, 0xfa, 0xea, 0xea, 0x22, 0x30, 0x02, 0x20, -0xfa, 0xfa, 0xfa, 0xfe, 0x22, 0x28, 0x01, 0x18, 0xfe, 0xfe, 0xfe, 0x7e, -0x01, 0x18, 0x01, 0x10, 0xe8, 0xe8, 0xf8, 0xe8, 0x01, 0x10, 0x00, 0x08, -0xa8, 0xe8, 0xa0, 0xa8, 0x01, 0x10, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0xff, 0xff, 0x10, 0x84, -0xb5, 0x15, 0x95, 0x00, 0xff, 0xff, 0x10, 0x84, 0x15, 0x15, 0x17, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xf7, 0x30, 0x84, -0x00, 0x44, 0x44, 0x6c, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x41, 0x08, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0xbe, 0xf7, 0x10, 0x84, 0x00, 0x14, 0x14, 0x1c, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xde, 0xf7, 0x30, 0x84, 0x6c, 0x78, 0x78, 0x50, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf7, 0x30, 0x84, -0x1e, 0x1b, 0x1b, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xdf, 0xff, 0x10, 0x84, 0x50, 0x50, 0x58, 0x58, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x30, 0x84, 0x11, 0x11, 0x39, 0x39, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x08, 0x42, -0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0xff, 0xff, 0x08, 0x42, 0x2b, 0x2b, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xa2, 0x10, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x04, 0x21, 0xbe, 0xf7, -0x55, 0x5a, 0x5a, 0x5a, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xff, 0xff, 0x28, 0x42, 0xfc, 0xfc, 0xfc, 0xfc, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, -0xde, 0xff, 0xc8, 0x88, 0xff, 0xff, 0xff, 0xff, 0xde, 0xff, 0xc8, 0x88, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x71, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x39, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf7, 0x49, 0x4a, 0x0f, 0x0f, 0x0f, 0x0f, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xff, 0xff, 0x28, 0x42, -0xfc, 0xfc, 0xfc, 0xfc, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x10, 0x84, 0xdf, 0xff, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xa2, 0x10, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xd3, 0x9d, 0x02, 0x10, -0xff, 0xff, 0xff, 0xff, 0xd3, 0x9d, 0x02, 0x10, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0xbe, 0xf7, 0xaa, 0x52, -0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0x08, 0x42, 0x00, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0x08, 0x42, 0x00, 0x2b, 0x2b, 0x2b, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0x10, 0x84, -0x58, 0x58, 0x50, 0x50, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xdf, 0xff, 0x30, 0x84, 0x39, 0x39, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xde, 0xf7, 0x30, 0x84, 0x50, 0x78, 0x78, 0x6c, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf7, 0x30, 0x84, -0x11, 0x1b, 0x1b, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xbe, 0xf7, 0x30, 0x84, 0x4c, 0x44, 0x44, 0x00, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x41, 0x08, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0xbe, 0xf7, 0x10, 0x84, 0x1c, 0x14, 0x14, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xff, 0xff, 0x10, 0x84, -0x00, 0xb4, 0x14, 0x94, 0xdf, 0xff, 0xef, 0x7b, 0x00, 0x55, 0x55, 0x57, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0x10, 0x84, 0x00, 0x95, 0x15, 0xb5, -0xff, 0xff, 0x10, 0x84, 0x00, 0x17, 0x15, 0x15, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xdf, 0xff, 0x10, 0x84, 0x94, 0xd4, 0x54, 0x54, -0x3c, 0xe7, 0xef, 0x7b, 0x56, 0x54, 0x54, 0x5c, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x7d, 0xef, 0x10, 0x84, 0xa5, 0xe5, 0x45, 0x4d, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0x5d, 0xef, 0x10, 0x84, -0x5a, 0x53, 0x51, 0x79, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x7d, 0xef, 0x10, 0x84, -0x69, 0x71, 0x51, 0x5b, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0xff, 0xff, 0x30, 0x84, 0x6d, 0x45, 0xe5, 0x00, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, -0xd6, 0xb5, 0x21, 0x08, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xb5, 0x21, 0x08, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0xff, 0xff, 0x10, 0x84, -0x55, 0x55, 0xd5, 0x00, 0xff, 0xff, 0x10, 0x84, 0x5e, 0x54, 0x56, 0x00, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0xff, 0xff, 0xef, 0x7b, 0x00, 0x95, 0xd5, 0x55, 0xbe, 0xf7, 0x10, 0x84, -0x00, 0x57, 0x54, 0x5c, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, -0xff, 0xff, 0xff, 0xff, 0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x1e, 0xf0, 0x14, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, -0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, -0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0xbe, 0xf7, 0x10, 0x84, 0x00, 0xb5, 0xc5, 0x4d, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x9e, 0xf7, 0x30, 0x84, 0x5a, 0x51, 0x79, 0x4d, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, -0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, -0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, -0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x42, 0xfc, 0xfc, 0xfc, 0xfc, -0x9e, 0xf7, 0x30, 0x84, 0x69, 0x51, 0x5b, 0x5c, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x3c, 0xe7, 0x69, 0x4a, 0x8f, 0x2f, 0x3f, 0xbf, 0xff, 0xff, 0xef, 0x7b, -0x15, 0x15, 0x17, 0x16, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, 0x14, 0x06, 0xde, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, -0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, -0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x10, 0x84, 0xd4, 0x94, 0x34, 0xe4, 0x1c, 0xe7, 0x69, 0x4a, -0xfc, 0xfe, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0xff, 0xff, 0x08, 0x42, -0xff, 0xff, 0xff, 0x00, 0xdf, 0xff, 0x71, 0x8c, 0x14, 0x1b, 0x11, 0x00, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, -0xff, 0xff, 0xff, 0xff, 0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x1e, 0xf0, 0x14, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, -0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, -0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x51, 0x8c, -0x44, 0x78, 0x50, 0x00, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0xff, 0xff, 0x10, 0x84, 0x00, 0x35, 0x15, 0x15, 0xbe, 0xef, 0xb0, 0x4c, -0x55, 0x55, 0x57, 0x54, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, -0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, -0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, -0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0x5b, 0xe7, 0x29, 0x7c, -0xd5, 0x15, 0x35, 0xc5, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x9d, 0xe7, 0xd0, 0x54, 0x5a, 0x51, 0x69, 0xc5, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, 0x14, 0x06, 0xde, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, -0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, -0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xe1, 0x52, 0x70, 0xa5, -0xaa, 0xaa, 0xaa, 0x6a, 0x3a, 0xe7, 0x6a, 0x84, 0x49, 0x51, 0x58, 0x54, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x9d, 0xef, 0xb0, 0x4c, 0x35, 0x95, 0x55, 0x55, 0x9d, 0xef, 0xd0, 0x4c, -0x55, 0x56, 0x5c, 0x53, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, -0xff, 0xff, 0xff, 0xff, 0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x1e, 0xf0, 0x14, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, -0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, -0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0x9d, 0xef, 0x49, 0x84, 0x15, 0xa5, 0x4d, 0x71, -0x2e, 0x9d, 0xa6, 0x6b, 0xfc, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0x9d, 0xe7, 0xb0, 0x4c, 0x69, 0xc5, 0x35, 0x95, -0x3c, 0xd7, 0xaf, 0x4c, 0x55, 0x55, 0x57, 0x54, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, -0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, -0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, -0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0x7c, 0xef, 0xc0, 0x4a, 0xff, 0xbf, 0x3f, 0x8f, -0x9c, 0xef, 0x29, 0x7c, 0x5a, 0x54, 0x57, 0x55, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xb0, 0x4c, 0xb0, 0x44, 0x2a, 0xaa, 0xaa, 0xaa, 0xbe, 0xef, 0xb0, 0x4c, -0x5a, 0x71, 0xcd, 0x35, 0x6e, 0x3c, 0xf1, 0x5c, 0xaa, 0xaa, 0xaa, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, 0x14, 0x06, 0xde, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, -0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, -0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x7c, 0xef, 0x29, 0x7c, 0x55, 0x55, 0xd5, 0x15, -0xbd, 0xf7, 0x49, 0x7c, 0x69, 0x53, 0x5c, 0x57, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0x7d, 0xe7, 0xb0, 0x4c, 0x95, 0x55, 0x55, 0x55, -0x3b, 0xd7, 0xd0, 0x4c, 0x54, 0x50, 0x61, 0x85, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, -0xff, 0xff, 0xff, 0xff, 0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x1e, 0xf0, 0x14, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, -0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, -0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x3a, 0xe7, 0x49, 0x84, 0x85, 0x41, 0x52, 0x54, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0x9d, 0xe7, 0x8f, 0x44, -0x35, 0xd5, 0x55, 0x55, 0xde, 0xf7, 0xef, 0x7b, 0x54, 0x5c, 0x70, 0xcc, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, -0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, -0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, -0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x2c, 0x63, 0xd3, 0x9c, 0xaa, 0xaa, 0xaa, 0x6a, -0xde, 0xf7, 0xef, 0x7b, 0x35, 0x0d, 0x33, 0x1c, 0x70, 0xad, 0x85, 0x63, -0xfe, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xdf, 0xff, 0x10, 0x84, 0x34, 0xd4, 0x54, 0x00, 0xde, 0xf7, 0xef, 0x7b, -0x57, 0x5c, 0x73, 0x00, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xde, 0xf5, 0x14, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, -0xff, 0xff, 0xff, 0xff, 0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, -0xc0, 0xf5, 0x00, 0xa6, 0xff, 0xff, 0xff, 0xff, 0x14, 0x06, 0xde, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x14, 0x06, 0xde, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x14, 0x06, 0xde, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, -0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x06, 0xc0, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, -0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x1e, 0xf0, 0x14, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, -0x00, 0xf0, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xa0, -0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, -0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, -0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x14, 0x00, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0xde, 0xf7, 0xef, 0x7b, 0x35, 0xcd, 0x73, 0x00, 0xff, 0xff, 0x10, 0x84, -0x17, 0x15, 0x15, 0x00, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf6, 0x63, -0x55, 0x55, 0x55, 0x55, 0x7e, 0xef, 0xd6, 0x63, 0x35, 0xd5, 0x55, 0x55, -0x3d, 0xe7, 0x17, 0x6c, 0x57, 0x58, 0x61, 0x05, 0xd8, 0x8c, 0xf6, 0x63, -0x55, 0x55, 0x55, 0x57, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0xfd, 0xde, 0x93, 0x32, 0xff, 0xff, 0xff, 0x3f, -0x9e, 0xef, 0x37, 0x6c, 0x35, 0x49, 0x52, 0x56, 0xf6, 0x63, 0xfb, 0xb5, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x63, 0x55, 0x55, 0x55, 0x55, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf6, 0x63, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xf6, 0x63, 0x55, 0x55, 0x55, 0x55, 0x9e, 0xef, 0xf6, 0x63, -0x95, 0x55, 0x55, 0x55, 0x5e, 0xe7, 0x16, 0x6c, 0x5c, 0x73, 0x8d, 0x15, -0x41, 0x08, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, 0x84, 0x15, 0x15, 0x15, 0x25, -0x9e, 0xef, 0x36, 0x6c, 0x85, 0x73, 0x5c, 0x55, 0x16, 0x6c, 0xf6, 0x63, -0x57, 0x55, 0x55, 0x55, 0x00, 0x00, 0xf6, 0x63, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xf6, 0x63, 0x55, 0x55, 0x55, 0x55, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xf6, 0x63, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xf6, 0x63, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xf6, 0x63, 0x55, 0x55, 0x55, 0x55, -0x16, 0x6c, 0xf6, 0x63, 0xd5, 0x55, 0x55, 0x55, 0xbe, 0xf7, 0x10, 0x84, -0x70, 0x8c, 0x94, 0x54, 0x7d, 0xef, 0x10, 0x84, 0x55, 0x55, 0x5c, 0x63, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0x71, 0x8c, 0xcf, 0x7b, -0xff, 0xff, 0xff, 0xbf, 0x9d, 0xef, 0x10, 0x84, 0x55, 0x95, 0x8d, 0x72, -0xbe, 0xf7, 0x10, 0x84, 0x23, 0x1c, 0x15, 0x15, 0x00, 0x00, 0xf6, 0x63, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xf6, 0x63, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xf6, 0x63, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xf6, 0x63, -0x55, 0x55, 0x55, 0x55, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xd5, 0x0a, 0x04, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf6, 0x63, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xf6, 0x63, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xf6, 0x63, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xf6, 0x63, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0xde, 0xf7, 0x10, 0x84, 0x25, 0xd5, 0x55, 0x00, 0xbe, 0xf7, 0x30, 0x84, -0x57, 0x58, 0xc9, 0x00, 0xff, 0xff, 0x08, 0x42, 0x3f, 0x3f, 0x3f, 0x00, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0xff, 0xff, 0x08, 0x42, -0xfc, 0xfc, 0xbc, 0x00, 0xbe, 0xf7, 0x10, 0x84, 0x35, 0xc9, 0x58, 0x00, -0xff, 0xff, 0x10, 0x84, 0x56, 0x55, 0x55, 0x00, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xf6, 0x63, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xf6, 0x63, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xf6, 0x63, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xf6, 0x63, 0x55, 0x55, 0x55, 0x55, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, -0xff, 0xff, 0xff, 0xff, 0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, -0xda, 0xfd, 0x60, 0x3b, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0xff, 0xff, 0x08, 0x42, 0x00, 0x2f, 0x3f, 0x3f, 0xff, 0xff, 0x8a, 0x52, -0x00, 0xfc, 0xe0, 0x2c, 0xdf, 0xff, 0x30, 0x84, 0x00, 0x55, 0x55, 0x56, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0xdf, 0xff, 0x30, 0x84, 0x00, 0x55, 0x55, 0x25, 0xff, 0xff, 0x8a, 0x52, -0x00, 0x2f, 0x22, 0x3e, 0xff, 0xff, 0x08, 0x42, 0x00, 0xfc, 0xfc, 0xfc, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0x55, 0xa9, 0xa9, 0xa9, 0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0x55, 0xa9, 0xa9, 0xa9, -0x00, 0x00, 0xff, 0xff, 0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, -0x55, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x55, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x41, 0x08, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0x9e, 0xf7, 0x10, 0x84, 0xe2, 0x35, 0x55, 0x55, 0x3c, 0xe7, 0x10, 0x84, -0x55, 0x5c, 0x83, 0xb5, 0xff, 0xff, 0x30, 0x84, 0x15, 0x15, 0x15, 0x38, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xde, 0xf7, 0x30, 0x84, 0x54, 0x54, 0x94, 0x88, -0x5c, 0xe7, 0x10, 0x84, 0xd5, 0x0d, 0x70, 0x57, 0xbe, 0xf7, 0x30, 0x84, -0x62, 0x57, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xff, 0xff, 0x10, 0x84, 0x2d, 0x15, 0x15, 0x15, 0xff, 0xff, 0x30, 0x84, -0x5c, 0x88, 0xd4, 0x54, 0xff, 0xff, 0x10, 0x84, 0x55, 0x57, 0xe2, 0xb5, -0x9d, 0xef, 0x30, 0x84, 0x55, 0x55, 0x55, 0xe0, 0x41, 0x08, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0xff, 0xff, 0x30, 0x84, 0x54, 0x54, 0x54, 0xd4, -0x9d, 0xef, 0x30, 0x84, 0x55, 0x55, 0xd5, 0x82, 0xff, 0xff, 0x10, 0x84, -0x55, 0xb5, 0xe2, 0x57, 0xff, 0xff, 0x30, 0x84, 0x2d, 0x38, 0x15, 0x15, -0xff, 0xff, 0x10, 0x84, 0x5c, 0x54, 0x54, 0x54, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, -0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0xa9, 0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, -0xfb, 0xdf, 0x0a, 0x52, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0xff, 0xff, 0x30, 0x84, -0xb5, 0x55, 0x55, 0x00, 0xde, 0xf7, 0x30, 0x84, 0x20, 0x35, 0x15, 0x00, -0xdf, 0xff, 0x30, 0x84, 0x54, 0x80, 0xd4, 0x00, 0xde, 0xf7, 0x30, 0x84, -0x55, 0x7e, 0x2b, 0x00, 0xdf, 0xff, 0x10, 0x84, 0x55, 0x55, 0xa0, 0x00, -0xef, 0x7b, 0xdf, 0xff, 0x40, 0x40, 0x6a, 0x55, 0x82, 0x10, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0xff, 0xff, 0x28, 0x42, 0xff, 0xff, 0xff, 0x00, -0x21, 0x08, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0xc3, 0x18, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0xff, 0xff, 0x08, 0x42, 0xfc, 0xfc, 0xa8, 0x00, -0xde, 0xf7, 0x30, 0x84, 0x55, 0x55, 0x02, 0x00, 0xff, 0xff, 0x10, 0x84, -0x55, 0xaf, 0xfa, 0x00, 0xdf, 0xff, 0x30, 0x84, 0x35, 0x20, 0x15, 0x00, -0xde, 0xf7, 0x30, 0x84, 0x80, 0x54, 0x54, 0x00, 0xff, 0xff, 0x30, 0x84, -0x57, 0x55, 0x55, 0x00, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, -0xa9, 0xa9, 0xa9, 0x55, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0x6a, 0x6a, 0x6a, 0x55, 0x00, 0x00, 0xff, 0xff, 0xa9, 0xa9, 0xa9, 0x55, -0x00, 0x00, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, -0xaa, 0xaa, 0xaa, 0x55, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x6a, 0x6a, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, -0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, -0x00, 0x00, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55 \ No newline at end of file diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/testcard-zstd.inl b/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/testcard-zstd.inl deleted file mode 100644 index 9e43883..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/testcard-zstd.inl +++ /dev/null @@ -1,261 +0,0 @@ -0x28, 0xb5, 0x2f, 0xfd, 0x60, 0x00, 0x7f, 0x6d, 0x61, 0x00, 0x0a, 0x66, -0xec, 0x17, 0x48, 0x60, 0x1c, 0x5a, 0xc9, 0x5d, 0x1a, 0x38, 0x07, 0xe8, -0xc5, 0x82, 0x99, 0x68, 0xe6, 0x95, 0x45, 0x58, 0x0d, 0x0c, 0xf3, 0x36, -0xc8, 0xd9, 0x0f, 0x46, 0x2d, 0x68, 0x11, 0xf8, 0x31, 0x10, 0xa1, 0x1a, -0x2f, 0x99, 0x5c, 0x84, 0xfd, 0x92, 0x02, 0xe6, 0x3b, 0x44, 0x9b, 0x01, -0x5d, 0x92, 0xff, 0x38, 0x26, 0x00, 0x6a, 0x6b, 0xc3, 0x53, 0xb2, 0x0c, -0x25, 0xf3, 0xd8, 0x59, 0x68, 0x9b, 0x14, 0x8a, 0x89, 0x75, 0x18, 0x03, -0x1d, 0xc9, 0x0f, 0x63, 0x01, 0x73, 0x01, 0x72, 0x01, 0x4f, 0x66, 0x31, -0x58, 0x0f, 0x97, 0x4b, 0x0c, 0x4c, 0x06, 0xac, 0x07, 0x0b, 0x68, 0xd4, -0xad, 0x80, 0x64, 0x13, 0x74, 0xa1, 0x12, 0x16, 0x58, 0xcf, 0x1a, 0x95, -0x5f, 0x0d, 0x26, 0x55, 0xd0, 0x9c, 0xf4, 0x52, 0x35, 0x2e, 0x20, 0xc1, -0x06, 0x69, 0x03, 0x0a, 0x93, 0x83, 0x5e, 0x27, 0x9b, 0x4c, 0x6d, 0xee, -0x87, 0x03, 0x30, 0x6c, 0x46, 0xd7, 0x50, 0x5c, 0xca, 0xe6, 0xa6, 0x4d, -0xa8, 0xf6, 0xab, 0xd7, 0x0e, 0x27, 0x27, 0x90, 0xc4, 0xb2, 0xd1, 0x10, -0xfa, 0x43, 0x82, 0xc8, 0xf2, 0xe5, 0xff, 0xff, 0xd5, 0x52, 0x62, 0x43, -0x87, 0x26, 0x2a, 0x05, 0x70, 0x0e, 0xb0, 0x2f, 0xc4, 0x56, 0xef, 0xb5, -0xca, 0xb8, 0x53, 0xb7, 0x96, 0x0e, 0xe7, 0x00, 0x2c, 0xa8, 0xda, 0x3b, -0x07, 0x70, 0xa7, 0x78, 0x38, 0x60, 0x87, 0x7a, 0x01, 0x3b, 0x75, 0xec, -0xfa, 0x77, 0xe2, 0x46, 0x94, 0x61, 0x8e, 0x0d, 0x0c, 0xfb, 0xe7, 0x8b, -0x13, 0x50, 0x31, 0xa9, 0x27, 0xcd, 0x27, 0xef, 0x6b, 0xa6, 0xab, 0x9c, -0x4d, 0x95, 0x6c, 0x3a, 0xbb, 0x8e, 0x96, 0x92, 0x18, 0x5a, 0x7c, 0x4f, -0xff, 0x7b, 0x38, 0xf2, 0xdb, 0x86, 0xde, 0xff, 0x1f, 0x2f, 0x21, 0x86, -0x7d, 0xbf, 0x45, 0xd0, 0x6e, 0x77, 0x0a, 0xee, 0x0a, 0xee, 0x14, 0x9a, -0xb8, 0x84, 0xf3, 0xac, 0xbe, 0xc8, 0x7f, 0x8d, 0xff, 0xff, 0xcf, 0x2a, -0xfb, 0x69, 0xfc, 0xfb, 0xfd, 0x7a, 0x10, 0x22, 0x36, 0xfc, 0xff, 0x3f, -0xcf, 0xd0, 0xf1, 0x7f, 0xfe, 0xff, 0x3d, 0x24, 0xdf, 0x78, 0x4a, 0xff, -0xda, 0x9c, 0x39, 0xcf, 0xef, 0xe7, 0xfd, 0x52, 0x98, 0xb5, 0x40, 0x92, -0xee, 0xdd, 0x99, 0xf5, 0x53, 0x5b, 0x65, 0x6b, 0xb5, 0xd8, 0x7b, 0xae, -0xfa, 0xc1, 0x0f, 0x0c, 0x7f, 0x4f, 0x55, 0xa3, 0xad, 0x2c, 0xa0, 0xbd, -0xf7, 0x2a, 0x0e, 0xe8, 0xbd, 0xc7, 0x5e, 0xf5, 0xd8, 0x54, 0x9e, 0x56, -0xa3, 0xd6, 0x59, 0xd5, 0xfe, 0x1f, 0xc0, 0x30, 0x8c, 0xfc, 0x46, 0x04, -0xae, 0x60, 0xbc, 0xe8, 0xcf, 0xec, 0x3d, 0xde, 0xf9, 0xf0, 0xfe, 0xef, -0x7d, 0xcc, 0xf7, 0x2b, 0xe5, 0x1b, 0x70, 0xff, 0xff, 0x7e, 0x3f, 0x6e, -0xe4, 0x02, 0x07, 0xfc, 0x1b, 0x7a, 0xff, 0xe7, 0x58, 0xfc, 0x7e, 0x3a, -0xdc, 0x97, 0xfd, 0x57, 0xef, 0xa3, 0xfc, 0x2a, 0xc7, 0x4d, 0xf3, 0xcb, -0x9d, 0xce, 0xac, 0xfe, 0xeb, 0x2e, 0x86, 0xb9, 0x69, 0x54, 0xef, 0xf9, -0x55, 0xcf, 0xff, 0x48, 0x24, 0x72, 0x3a, 0x9d, 0x72, 0x2f, 0x2f, 0x2f, -0xff, 0x3f, 0xe7, 0x01, 0x6c, 0x4d, 0x6c, 0xcd, 0x2d, 0x5b, 0x53, 0xb7, -0x59, 0x22, 0x08, 0x0b, 0xa7, 0x92, 0x15, 0x75, 0x93, 0xb0, 0x5d, 0xaf, -0x2a, 0x63, 0x95, 0x1d, 0x25, 0xd2, 0xd2, 0xa8, 0x1c, 0x84, 0xc9, 0xdc, -0x72, 0xba, 0xd7, 0xfc, 0x69, 0xf5, 0xc7, 0x19, 0xa9, 0xbe, 0xfa, 0x26, -0x55, 0x25, 0x75, 0xb7, 0x60, 0xa3, 0xd8, 0x68, 0x54, 0xb7, 0x1b, 0xa5, -0x54, 0x62, 0xb1, 0x49, 0xde, 0xe2, 0xac, 0xa2, 0xe8, 0x7b, 0xff, 0x5f, -0x75, 0x4e, 0xb8, 0xa2, 0xdd, 0x6a, 0xb7, 0xda, 0x6e, 0x2e, 0x04, 0xcd, -0x08, 0x2f, 0xec, 0x8e, 0x49, 0xaf, 0x49, 0x6f, 0x8b, 0x4f, 0x2e, 0x1a, -0xc5, 0x62, 0x7b, 0x6b, 0x3e, 0x32, 0x3e, 0x32, 0xbe, 0x08, 0x35, 0x4d, -0x63, 0x93, 0xa6, 0xc8, 0x42, 0xe6, 0x21, 0xcc, 0x59, 0xc8, 0x4c, 0xe5, -0x86, 0xe1, 0x03, 0x06, 0xa4, 0xec, 0xff, 0xb7, 0x78, 0x7e, 0x62, 0x43, -0xc7, 0x2c, 0x50, 0x30, 0x4a, 0xc8, 0x9b, 0xf3, 0xbf, 0xe6, 0x62, 0xa0, -0x50, 0xa6, 0x9c, 0xe3, 0x6e, 0x5b, 0xaf, 0x77, 0x8b, 0xbb, 0xe1, 0x70, -0xaa, 0xaa, 0xaa, 0x92, 0xb4, 0x52, 0xad, 0x14, 0x87, 0x93, 0x0b, 0xe6, -0x82, 0x39, 0x11, 0xb9, 0x20, 0x9a, 0x16, 0x34, 0x22, 0x68, 0xb2, 0x68, -0xb2, 0x76, 0xd3, 0xe8, 0x6e, 0xda, 0x6b, 0x62, 0x34, 0x2e, 0x8d, 0xbd, -0x2d, 0x3d, 0x6b, 0x4c, 0x26, 0x33, 0xda, 0x33, 0xf3, 0x91, 0x51, 0x46, -0x79, 0xbd, 0x3e, 0x39, 0x9f, 0xcf, 0xd2, 0xb8, 0x5c, 0xfa, 0x22, 0xf8, -0x8e, 0xb6, 0xbe, 0x08, 0x40, 0x14, 0x49, 0x40, 0x14, 0xf2, 0x0c, 0x2d, -0x30, 0x85, 0x3c, 0x63, 0x29, 0xd3, 0x98, 0x85, 0x6c, 0xb5, 0xdb, 0xad, -0x5c, 0x63, 0x9e, 0x72, 0xcf, 0x43, 0xe6, 0xaf, 0x77, 0xa6, 0xe2, 0x21, -0x0c, 0x4d, 0xd3, 0x49, 0x1e, 0xc2, 0x14, 0x6f, 0xee, 0xdb, 0x7b, 0x7b, -0x08, 0xb3, 0xa4, 0x60, 0x3b, 0x9d, 0x6e, 0x8b, 0x37, 0x4b, 0x0a, 0x74, -0x35, 0x33, 0xbc, 0xf9, 0x64, 0x85, 0x63, 0x32, 0x29, 0x20, 0x59, 0x0c, -0x3c, 0x96, 0x67, 0x62, 0xb7, 0x8a, 0x92, 0x4d, 0xa0, 0xd3, 0xf3, 0xd1, -0x85, 0x80, 0x38, 0xcb, 0x64, 0x60, 0xc9, 0xb5, 0xaf, 0x97, 0x8d, 0x20, -0x45, 0x28, 0xb8, 0xab, 0xe8, 0xc9, 0x0a, 0x88, 0x1f, 0xd6, 0x47, 0x54, -0xf1, 0xd3, 0xfb, 0x62, 0xa7, 0xfd, 0xf2, 0x8b, 0xfd, 0xb6, 0xe4, 0x2e, -0xb6, 0x91, 0x73, 0x1c, 0xd0, 0x7b, 0xba, 0x83, 0xc9, 0xac, 0x51, 0x39, -0x92, 0xc5, 0x4f, 0x30, 0x1e, 0x2e, 0xd5, 0xf1, 0xa8, 0xa6, 0xa5, 0x80, -0x70, 0xb9, 0xbc, 0xb7, 0xc2, 0x52, 0x32, 0x6c, 0xe3, 0x3d, 0xed, 0x41, -0xa4, 0x4b, 0x31, 0x2a, 0xe6, 0x62, 0x11, 0x19, 0x95, 0x73, 0x1d, 0xbf, -0xe1, 0x6c, 0xfc, 0x47, 0x75, 0x6c, 0x37, 0x63, 0x02, 0xf8, 0x34, 0x40, -0x9a, 0x00, 0x1d, 0xf7, 0x32, 0x56, 0x77, 0xda, 0x5b, 0x9f, 0x9f, 0x0f, -0xbb, 0x91, 0x5b, 0xbd, 0xe7, 0x58, 0x82, 0x4a, 0x20, 0xcd, 0x4f, 0x47, -0x15, 0xf3, 0x51, 0xf1, 0x43, 0x51, 0x10, 0x96, 0xae, 0xba, 0xf7, 0x21, -0x50, 0xef, 0x55, 0x27, 0x0c, 0x1f, 0xe0, 0x54, 0xf8, 0xc9, 0x69, 0xef, -0xb9, 0x53, 0xf7, 0x83, 0x73, 0x9d, 0xce, 0x86, 0x07, 0x83, 0x44, 0x61, -0x37, 0x35, 0x35, 0x33, 0x4e, 0x33, 0x33, 0x3e, 0x9f, 0x50, 0x48, 0x24, -0xe6, 0xd0, 0x79, 0x49, 0xc3, 0x2d, 0xa0, 0x46, 0x31, 0x9a, 0x72, 0xc3, -0x84, 0xff, 0x7a, 0x95, 0xbb, 0x00, 0x22, 0xcc, 0x14, 0x00, 0x04, 0xac, -0x60, 0x64, 0x86, 0xe4, 0x6f, 0xb1, 0x58, 0xf4, 0xdc, 0xb0, 0x05, 0x00, -0x72, 0x38, 0xf8, 0xce, 0xce, 0x8e, 0xcf, 0x37, 0x33, 0x43, 0x24, 0x0a, -0x85, 0x33, 0x35, 0x35, 0x37, 0xc2, 0xa8, 0x28, 0x27, 0x1b, 0x9d, 0xce, -0x29, 0x18, 0xe4, 0xfc, 0x09, 0x53, 0xa5, 0x51, 0xad, 0x74, 0x79, 0x7b, -0xb5, 0x4a, 0x65, 0x94, 0x36, 0x89, 0xf5, 0x62, 0x9b, 0xd8, 0x9a, 0xe8, -0x2b, 0xff, 0xa1, 0x73, 0xfe, 0x2e, 0x2c, 0x41, 0x45, 0x37, 0xef, 0x6e, -0x7b, 0x38, 0xca, 0xa5, 0xd2, 0xb8, 0x1c, 0x3b, 0x96, 0x21, 0xbb, 0x5d, -0xad, 0xd1, 0xdb, 0x1c, 0xf6, 0x5e, 0x4b, 0xd9, 0x59, 0x1b, 0x67, 0xf5, -0x7a, 0x7c, 0x9a, 0x91, 0x3e, 0x8e, 0xe3, 0xee, 0x7b, 0xb9, 0xa4, 0xb9, -0xf5, 0x70, 0xee, 0x1d, 0x4e, 0x4f, 0xcc, 0xd6, 0x7b, 0x07, 0x71, 0x48, -0xf2, 0x06, 0xd0, 0x10, 0x82, 0x21, 0xe4, 0x55, 0x2e, 0xa5, 0x1d, 0xbe, -0x48, 0x8c, 0x69, 0xbb, 0x24, 0x40, 0x68, 0x9b, 0xba, 0x5a, 0x5a, 0xa7, -0xe2, 0xd1, 0xac, 0xc2, 0xd8, 0x87, 0x9c, 0xe3, 0x78, 0xee, 0xa6, 0xcd, -0xdd, 0x68, 0x6e, 0xdd, 0xdb, 0x2e, 0xc6, 0xbb, 0x8b, 0xe9, 0xc1, 0xd9, -0xf6, 0x62, 0x7e, 0x72, 0x7e, 0x72, 0x34, 0xe4, 0x68, 0xc8, 0x11, 0x32, -0x10, 0x32, 0x20, 0x32, 0xf0, 0x12, 0x19, 0x90, 0xe0, 0x45, 0x91, 0xe0, -0x25, 0x83, 0xba, 0xc9, 0x20, 0x26, 0x87, 0xa5, 0x72, 0xa9, 0x64, 0x72, -0x80, 0x21, 0x54, 0x13, 0xeb, 0x29, 0x18, 0x42, 0x34, 0x84, 0x94, 0x34, -0x84, 0xa4, 0x1d, 0xa4, 0x1d, 0x82, 0x1c, 0xef, 0xaf, 0x0e, 0x63, 0x47, -0x6d, 0x10, 0xb9, 0xec, 0xd8, 0x2d, 0x3b, 0x9e, 0x21, 0xb1, 0x67, 0x48, -0x34, 0x24, 0x1a, 0x52, 0xdb, 0xa4, 0x6d, 0x62, 0xd3, 0xfa, 0xff, 0xfa, -0x03, 0x34, 0xef, 0x9d, 0xc9, 0xe1, 0x5d, 0xec, 0xf5, 0xf1, 0x79, 0x8c, -0x97, 0xd2, 0x24, 0xc1, 0x2d, 0xe0, 0x39, 0x16, 0x1e, 0xa9, 0x41, 0xc3, -0xbf, 0x4a, 0xd9, 0x3c, 0xea, 0x77, 0x96, 0x55, 0xe6, 0x95, 0xc3, 0xf1, -0x8e, 0x7b, 0x4f, 0xad, 0x61, 0xf8, 0xe7, 0x01, 0xad, 0x46, 0xf5, 0x2c, -0xac, 0x55, 0x2c, 0x94, 0xaa, 0x46, 0xfb, 0x5e, 0xcd, 0xaa, 0x1f, 0x78, -0x4f, 0x2f, 0xd1, 0xc9, 0x02, 0xd6, 0x2c, 0x67, 0xef, 0x3f, 0x54, 0xab, -0xda, 0x03, 0x79, 0x1f, 0xab, 0xfd, 0x0c, 0x38, 0x3c, 0xbc, 0xe1, 0xd5, -0x01, 0xf6, 0xfb, 0xfb, 0xf1, 0x70, 0xee, 0xfd, 0x90, 0x13, 0x97, 0xc4, -0xbc, 0x08, 0xe7, 0x4b, 0x88, 0x34, 0xf7, 0x56, 0x1e, 0x0c, 0xdb, 0xe4, -0x9c, 0x78, 0xf1, 0xf4, 0x62, 0x4c, 0xb5, 0xf7, 0xdd, 0xd9, 0x4c, 0x5a, -0x69, 0xa6, 0x36, 0x27, 0x03, 0xbe, 0x86, 0xc2, 0x72, 0xa2, 0x60, 0x73, -0xf1, 0xe0, 0x17, 0x50, 0xb5, 0x93, 0x81, 0xac, 0xf1, 0xc9, 0xd4, 0x66, -0x73, 0x71, 0xce, 0x63, 0xa8, 0x60, 0x98, 0xda, 0x86, 0x46, 0x72, 0xec, -0x54, 0xc1, 0xe6, 0x8a, 0x10, 0x23, 0x2d, 0x0c, 0xdd, 0x44, 0x0b, 0xa0, -0x44, 0xa4, 0x9d, 0x0e, 0x64, 0x31, 0x30, 0x45, 0xb1, 0x97, 0x4c, 0x6d, -0x9f, 0x43, 0x99, 0x71, 0xa8, 0x9a, 0xe6, 0xbd, 0x3a, 0xe1, 0xff, 0x7f, -0x33, 0x61, 0xf1, 0x48, 0xda, 0x48, 0x28, 0x10, 0x23, 0x9b, 0x24, 0xeb, -0xee, 0xbd, 0x35, 0x0e, 0x6e, 0x75, 0x23, 0x20, 0xd6, 0x95, 0x8c, 0xa5, -0x24, 0xec, 0x44, 0x67, 0x52, 0x2e, 0x78, 0x2a, 0xba, 0x3e, 0x3a, 0x4e, -0xc9, 0x5c, 0x23, 0xb0, 0xd5, 0xfb, 0x29, 0xaf, 0x9a, 0x0b, 0x90, 0x89, -0xd8, 0xec, 0xa9, 0xa8, 0x13, 0xfc, 0x22, 0xfa, 0xf2, 0x74, 0x2f, 0x4e, -0x35, 0xb0, 0x6d, 0x6c, 0xfd, 0xc4, 0xfe, 0xd0, 0x98, 0x3d, 0xe5, 0x43, -0x0a, 0xd0, 0x33, 0x26, 0x3b, 0x12, 0x7d, 0x65, 0xa1, 0xff, 0xff, 0x6f, -0x53, 0x0e, 0x28, 0x84, 0xa7, 0xa2, 0x2e, 0xf8, 0x4a, 0xb6, 0xa1, 0x47, -0xf5, 0xd0, 0x13, 0x9d, 0xd9, 0x50, 0xef, 0x9f, 0x31, 0xb4, 0x13, 0x67, -0xf9, 0x0a, 0x99, 0xb5, 0x80, 0xec, 0x4a, 0x1a, 0x59, 0x21, 0x3b, 0xce, -0xc5, 0x7e, 0x96, 0x85, 0x92, 0xc5, 0xb0, 0x75, 0xaa, 0x41, 0x16, 0xa9, -0xd3, 0xde, 0x13, 0x7d, 0xd9, 0x61, 0x30, 0x1c, 0x73, 0x61, 0x54, 0x90, -0xcf, 0xd4, 0xe8, 0xfe, 0xbf, 0xbf, 0x36, 0x57, 0x26, 0x38, 0xab, 0x06, -0xc4, 0x7e, 0x3c, 0x5b, 0x35, 0xd2, 0x7c, 0x2c, 0x0a, 0x82, 0xf2, 0xa8, -0xf2, 0x8b, 0x48, 0xa9, 0x90, 0x00, 0x01, 0x10, 0x10, 0x14, 0x04, 0x00, -0x32, 0xa2, 0x06, 0x82, 0x28, 0x90, 0xc2, 0xb4, 0x85, 0xda, 0x01, 0x52, -0xe9, 0x18, 0x85, 0x60, 0x00, 0x00, 0x20, 0x0c, 0x00, 0x14, 0x41, 0x00, -0x40, 0xa0, 0x04, 0x40, 0x00, 0x80, 0x50, 0x03, 0x01, 0x10, 0x18, 0x01, -0x80, 0xd4, 0x14, 0x99, 0x01, 0xfd, 0x07, 0xf8, 0x16, 0x0e, 0xd9, 0x5d, -0xa3, 0x70, 0xfe, 0xda, 0x17, 0xfa, 0xce, 0x46, 0x9a, 0x99, 0x81, 0x1a, -0x39, 0xba, 0x63, 0xb1, 0x18, 0x11, 0x58, 0xd7, 0xc7, 0xba, 0x03, 0x3e, -0x01, 0xf2, 0xf9, 0x4e, 0x12, 0xa3, 0x50, 0x7b, 0xaf, 0x7b, 0x60, 0x5c, -0x83, 0x23, 0xd2, 0x60, 0x27, 0x84, 0xad, 0xb8, 0x02, 0xed, 0xfe, 0xb4, -0x9c, 0x08, 0x9f, 0x49, 0xae, 0x55, 0x02, 0x94, 0xc0, 0x1b, 0x90, 0x75, -0x0b, 0x90, 0xc4, 0xc7, 0x43, 0x9e, 0x67, 0x25, 0x70, 0x61, 0x0d, 0xb8, -0x7a, 0x97, 0x43, 0xfc, 0xd1, 0x7e, 0x68, 0xed, 0x03, 0xb7, 0x1e, 0x75, -0xe9, 0x4d, 0x7a, 0x23, 0x18, 0x37, 0x63, 0x6f, 0xab, 0x5f, 0x7c, 0x5b, -0x1c, 0x05, 0xdf, 0x3f, 0x00, 0x86, 0x37, 0xa0, 0xfa, 0x0c, 0xe0, 0xed, -0x35, 0x35, 0x2f, 0xd8, 0xd1, 0x75, 0xba, 0x37, 0x34, 0x7e, 0xb0, 0x84, -0x2a, 0x01, 0x0c, 0x98, 0xed, 0x47, 0xf9, 0x86, 0x81, 0x74, 0x00, 0x5d, -0x8b, 0x4c, 0x18, 0x8a, 0x31, 0xcd, 0xae, 0x07, 0x44, 0xb5, 0xd5, 0x07, -0xa0, 0xdf, 0xf4, 0xfa, 0xa6, 0x42, 0xd0, 0x4f, 0x17, 0xd8, 0xdf, 0xb6, -0x34, 0x44, 0xe3, 0x01, 0xc4, 0xb6, 0x2d, 0xb5, 0x56, 0xc6, 0x2a, 0x1f, -0x05, 0x6c, 0x35, 0xe0, 0x09, 0x31, 0xef, 0x60, 0xfe, 0xaf, 0x07, 0x80, -0x32, 0xa0, 0xe9, 0xd3, 0x96, 0x45, 0xa7, 0xaa, 0xb6, 0xfb, 0x03, 0x10, -0xe3, 0x97, 0x96, 0x8d, 0x3a, 0x01, 0xdd, 0x58, 0x58, 0x78, 0x00, 0xab, -0xff, 0x06, 0xa0, 0xd6, 0x01, 0x58, 0x08, 0xb7, 0xdc, 0x2d, 0xa7, 0xfb, -0x22, 0xa8, 0x67, 0x00, 0xe3, 0xcf, 0x82, 0x43, 0xfc, 0x96, 0x1b, 0x40, -0x63, 0xcf, 0x9d, 0x42, 0x5d, 0x66, 0x40, 0xaa, 0xaf, 0x28, 0x94, 0xd3, -0x2a, 0xd4, 0x02, 0x13, 0xd2, 0xdf, 0x03, 0x9c, 0x60, 0x6b, 0x16, 0x94, -0xb4, 0xbe, 0x62, 0xc2, 0x35, 0x60, 0x45, 0x09, 0x23, 0x5a, 0xe0, 0x85, -0xb3, 0x03, 0x50, 0x68, 0x0c, 0x20, 0xa5, 0xf9, 0x94, 0xd2, 0x35, 0x80, -0xad, 0x4c, 0x4e, 0x40, 0x41, 0x97, 0x92, 0x75, 0xbe, 0x0c, 0x03, 0x50, -0x85, 0x08, 0xaf, 0x36, 0x00, 0x68, 0xaf, 0x09, 0xb3, 0x0c, 0x20, 0x4f, -0x81, 0x6a, 0x6a, 0xf5, 0x0d, 0x70, 0x69, 0x00, 0x4c, 0xb4, 0x0f, 0x59, -0xe7, 0x31, 0x0a, 0x45, 0x9f, 0xde, 0x90, 0xd6, 0x38, 0x80, 0x6b, 0x2c, -0xb9, 0x2f, 0xd4, 0x01, 0x40, 0x14, 0xd5, 0xed, 0x8e, 0x01, 0x53, 0xbf, -0x03, 0x18, 0x1e, 0xb0, 0xc1, 0x85, 0x32, 0xec, 0x78, 0x2b, 0xf0, 0xbb, -0xbb, 0x6c, 0xf3, 0x4d, 0xdc, 0x73, 0x40, 0xfd, 0x10, 0x09, 0x9e, 0x20, -0xe2, 0x12, 0x8c, 0xe0, 0xd2, 0xed, 0x80, 0x6b, 0xcc, 0x78, 0x20, 0x03, -0xd0, 0x5e, 0x06, 0xf4, 0xb0, 0xc4, 0x0e, 0x15, 0x1d, 0x80, 0xb4, 0x76, -0xdf, 0x49, 0x03, 0x50, 0x82, 0xad, 0xda, 0x8b, 0x5a, 0x61, 0xc2, 0x5e, -0xb5, 0x1e, 0x46, 0xc0, 0xde, 0xaa, 0x0e, 0x15, 0x06, 0xd2, 0xf4, 0xb2, -0xd1, 0xed, 0x38, 0x0a, 0x03, 0x18, 0x33, 0x1a, 0x80, 0x61, 0x3e, 0xec, -0x7c, 0x74, 0xa8, 0x1d, 0x80, 0x1a, 0xce, 0x25, 0x1d, 0x41, 0xd1, 0xc1, -0x03, 0x28, 0xb5, 0xaf, 0x72, 0x9c, 0x59, 0x7a, 0xe1, 0x7d, 0xc0, 0xa5, -0x08, 0x1e, 0x18, 0x24, 0xfa, 0xbd, 0x99, 0x4a, 0x31, 0xa0, 0xea, 0xee, -0xf8, 0x36, 0x60, 0x98, 0xc9, 0x10, 0xd1, 0xa7, 0x35, 0x00, 0x8d, 0x40, -0x8e, 0x5a, 0x35, 0x0f, 0x80, 0xb1, 0xd4, 0x32, 0x79, 0x40, 0x34, 0x05, -0x7e, 0x98, 0xc6, 0x80, 0x3e, 0x90, 0x01, 0x65, 0xf4, 0x80, 0x73, 0x08, -0x64, 0xd7, 0x36, 0xc1, 0x7c, 0xc0, 0x5c, 0x75, 0x00, 0xc5, 0x09, 0x58, -0x9c, 0x13, 0x01, 0x72, 0x37, 0x9b, 0x79, 0xe4, 0x05, 0xd1, 0x01, 0x04, -0x98, 0x08, 0x74, 0xfd, 0xfc, 0x3f, 0x1c, 0x00, 0x73, 0x01, 0xfc, 0x1c, -0xcc, 0x16, 0x43, 0x19, 0x1d, 0xac, 0x61, 0x4b, 0x11, 0xc2, 0xa0, 0xf2, -0x01, 0x0b, 0x7b, 0x3b, 0xf4, 0xfc, 0x58, 0x5d, 0x2d, 0x5c, 0x01, 0x8c, -0x62, 0x17, 0x78, 0xbe, 0x60, 0x8c, 0x01, 0x6f, 0x91, 0x49, 0x65, 0x54, -0x92, 0xe9, 0x01, 0x1e, 0x10, 0x77, 0x35, 0x00, 0xa8, 0xd4, 0xc7, 0x71, -0x07, 0xd8, 0xcd, 0xa3, 0x7d, 0x69, 0x20, 0xac, 0x07, 0x00, 0x35, 0xc7, -0x62, 0xee, 0x8c, 0x7d, 0x0c, 0xb8, 0x43, 0x0e, 0x00, 0x08, 0xfb, 0xe7, -0xec, 0x33, 0x37, 0x04, 0x80, 0x2d, 0x1d, 0xa6, 0x13, 0x34, 0x1b, 0x1d, -0xc0, 0xca, 0x00, 0x92, 0xed, 0x2e, 0x56, 0xbe, 0x91, 0x80, 0x0c, 0x88, -0xa6, 0x01, 0xdf, 0x7f, 0x90, 0x49, 0xed, 0x0c, 0xe0, 0x08, 0x73, 0x28, -0x74, 0xc7, 0xe1, 0xb1, 0x03, 0x5d, 0xc5, 0xab, 0x61, 0x42, 0xdf, 0x03, -0x43, 0xf3, 0x35, 0x04, 0xcf, 0xc6, 0x1d, 0x79, 0x07, 0x40, 0x22, 0xe4, -0x68, 0x0d, 0x01, 0x95, 0xad, 0x72, 0x69, 0x00, 0x39, 0x9d, 0x53, 0x8f, -0x13, 0x0d, 0xb0, 0x29, 0x79, 0x1a, 0x39, 0x20, 0x12, 0x28, 0x9b, 0x02, -0x8f, 0x74, 0x90, 0x4c, 0xe8, 0xd1, 0x57, 0xf4, 0x01, 0x44, 0x04, 0xe0, -0x0c, 0x82, 0x91, 0xc5, 0x4f, 0x8f, 0xc6, 0x00, 0x43, 0x85, 0x65, 0xc8, -0xe6, 0x34, 0x1d, 0x80, 0xc0, 0xca, 0xdb, 0x57, 0x6c, 0x00, 0x72, 0x42, -0x5f, 0xd0, 0x49, 0x57, 0x47, 0xd4, 0x97, 0x18, 0x18, 0x80, 0x68, 0x8e, -0x0a, 0xf1, 0x6b, 0x34, 0xf1, 0x60, 0x2c, 0x41, 0x29, 0xd3, 0x3d, 0x55, -0x95, 0xb1, 0x3c, 0xd4, 0x95, 0x42, 0xef, 0xe7, 0xca, 0x00, 0x2e, 0xce, -0x25, 0xc2, 0xca, 0xf5, 0x00, 0x17, 0x3b, 0x8c, 0x42, 0x88, 0x03, 0xde, -0x97, 0xe1, 0x3a, 0x74, 0xb0, 0x33, 0xe0, 0x8f, 0x47, 0xeb, 0x2a, 0x5f, -0x36, 0x3e, 0x5a, 0xff, 0xc5, 0x80, 0xb9, 0x13, 0xa9, 0x1f, 0xf8, 0x86, -0xc9, 0x51, 0xf8, 0x4c, 0xaa, 0xe1, 0x65, 0x80, 0xb0, 0x8b, 0x91, 0xec, -0xcc, 0xbf, 0x70, 0x19, 0x98, 0x03, 0x10, 0xf0, 0x38, 0x40, 0xc4, 0x65, -0xbe, 0x41, 0xb2, 0x58, 0x3f, 0xe0, 0xcc, 0x0e, 0x08, 0x2b, 0x73, 0xf4, -0xdd, 0x86, 0x06, 0xa0, 0xc6, 0x8f, 0x1a, 0x32, 0x66, 0x50, 0x8e, 0xe1, -0x59, 0x67, 0x00, 0xed, 0x66, 0x1d, 0xdd, 0xfa, 0x7b, 0xe2, 0x56, 0x89, -0xd9, 0xa0, 0x4f, 0x41, 0x94, 0x28, 0xb8, 0xc6, 0xc7, 0x64, 0xde, 0x9b, -0x64, 0x44, 0x33, 0x39, 0xb5, 0x6c, 0xb9, 0x42, 0xe7, 0x7e, 0x16, 0xd2, -0x01, 0x12, 0x03, 0xb3, 0x48, 0x47, 0x6b, 0x75, 0x26, 0x19, 0x8c, 0xac, -0x6f, 0xb1, 0x6f, 0xdc, 0x04, 0x27, 0x3a, 0x00, 0xd6, 0xae, 0xfa, 0xe1, -0xf7, 0x30, 0xa4, 0xdb, 0xd5, 0x86, 0x5a, 0x07, 0x11, 0xde, 0xea, 0xf4, -0xb0, 0x83, 0x16, 0xbb, 0xc6, 0x00, 0x6e, 0xf2, 0x6b, 0x40, 0x81, 0x01, -0x67, 0x0e, 0xa9, 0x82, 0x23, 0x04, 0x34, 0xed, 0x02, 0xf5, 0xe4, 0x0e, -0x58, 0xe8, 0x8a, 0x58, 0x57, 0xb0, 0x56, 0x65, 0x3d, 0x40, 0x64, 0x03, -0x6e, 0x7b, 0x07, 0x20, 0x99, 0x90, 0x36, 0x95, 0x9f, 0xdf, 0x3d, 0xe8, -0x00, 0xa0, 0x57, 0x8f, 0x6d, 0xa4, 0xb3, 0x1d, 0x7a, 0x06, 0xa8, 0x26, -0x41, 0xb0, 0x8c, 0x9c, 0x10, 0x85, 0x6c, 0xb4, 0x31, 0xa6, 0x5b, 0x7a, -0x10, 0x51, 0x15, 0x3c, 0xa2, 0x42, 0xd3, 0x23, 0x02, 0xc0, 0x17, 0x7e, -0x03, 0x28, 0xba, 0xce, 0x9b, 0xae, 0xdd, 0x1a, 0x19, 0xd0, 0x15, 0xac, -0xeb, 0x20, 0x3c, 0x3a, 0x00, 0xc6, 0xbb, 0x8a, 0xd5, 0x64, 0xc2, 0x21, -0x1d, 0x6c, 0x15, 0x5a, 0xd3, 0x44, 0x98, 0x14, 0x95, 0xb3, 0xb7, 0xdd, -0xa6, 0xea, 0x06, 0x54, 0x78, 0xc3, 0xe8, 0x79, 0x9b, 0x86, 0x29, 0x76, -0x8b, 0x6b, 0xaa, 0x0d, 0xa8, 0x2f, 0x22, 0x2a, 0xeb, 0x68, 0x81, 0x6c, -0x56, 0xfd, 0x79, 0xac, 0x79, 0x4b, 0xa0, 0x01, 0x3f, 0x17, 0x43, 0x82, -0xb4, 0xd5, 0x00, 0x14, 0xb7, 0xf5, 0x00, 0xf4, 0x15, 0xa8, 0xd7, 0x4b, -0xb1, 0xbc, 0xa8, 0x36, 0x98, 0xf0, 0x8c, 0xe7, 0xf4, 0x7b, 0x35, 0xd8, -0xad, 0x0d, 0x5f, 0x9d, 0x96, 0xab, 0xed, 0x48, 0xe2, 0xdc, 0x1c, 0xbe, -0x12, 0xfa, 0x41, 0x6f, 0xf5, 0x1e, 0xb6, 0x9f, 0xee, 0xac, 0x21, 0xf4, -0xf6, 0x00, 0x38, 0xb1, 0x1f, 0xfd, 0xd0, 0x0e, 0xc7, 0xdd, 0xa0, 0x39, -0x07, 0x8c, 0x35, 0x1f, 0x7e, 0xcc, 0xbf, 0xf6, 0xe0, 0x06, 0x66, 0x7d, -0x10, 0x3f, 0xc5, 0x3e, 0xde, 0x42, 0xf9, 0x3d, 0x00, 0x54, 0x81, 0x67, -0x8a, 0xe6, 0x63, 0x0d, 0x01, 0xd0, 0x31, 0xe0, 0x6e, 0xd0, 0xe1, 0x59, -0xf6, 0x1b, 0xf7, 0x0d, 0x52, 0x06, 0x80, 0x61, 0x4f, 0xe8, 0x77, 0xdd, -0x6f, 0x48, 0x20, 0x1d, 0xbb, 0x2a, 0x16, 0x8b, 0x54, 0x87, 0x92, 0x83, -0xe6, 0x8f, 0x55, 0x59, 0x06, 0x00, 0xe9, 0xc5, 0xce, 0x21, 0x63, 0x87, -0xaf, 0x86, 0xcc, 0xba, 0xd6, 0xe7, 0x00, 0xf6, 0x91, 0x92, 0x92, 0xea, -0xe8, 0x42, 0x06, 0x69, 0x13, 0xf5, 0x00, 0xd0, 0xb0, 0xa7, 0xcb, 0x4c, -0xb0, 0xd2, 0x2d, 0x28, 0x63, 0xf0, 0x6a, 0xc7, 0x80, 0x6a, 0x19, 0xb2, -0x66, 0x51, 0xf3, 0xb1, 0x21, 0xa0, 0x48, 0xad, 0x1e, 0x80, 0x62, 0xaf, -0x00, 0xf4, 0xa5, 0x4e, 0x83, 0x75, 0x1b, 0xfe, 0x00, 0xc4, 0xcf, 0x55, -0xb2, 0x50, 0xa6, 0xeb, 0x38, 0xed, 0x8f, 0xd3, 0x1d, 0x00, 0xf6, 0xe3, -0x90, 0x1c, 0x60, 0x9e, 0x8e, 0xeb, 0x0b, 0xba, 0x44, 0x06, 0x68, 0xbb, -0xd3, 0x10, 0x63, 0x35, 0xe1, 0x86, 0x5c, 0x5c, 0x2b, 0x85, 0xa6, 0xe7, -0x38, 0x2c, 0x18, 0x83, 0x1f, 0x8f, 0x9b, 0x8e, 0x4d, 0x26, 0xcd, 0x34, -0x0c, 0x66, 0x1d, 0x70, 0xb7, 0x01, 0xe6, 0x02, 0xa8, 0x51, 0x63, 0xcf, -0xbb, 0x03, 0xca, 0x85, 0xc6, 0x9c, 0xf6, 0xf1, 0x51, 0xe0, 0x60, 0x07, -0x40, 0x86, 0xf0, 0x1e, 0x6e, 0xef, 0x61, 0x10, 0xd9, 0x36, 0xcc, 0xfc, -0x58, 0xe2, 0x37, 0x0d, 0x58, 0xb7, 0xbe, 0xca, 0xc9, 0xd8, 0xcd, 0xaa, -0xd5, 0x5b, 0x77, 0x83, 0xcb, 0x0e, 0x30, 0xce, 0xc8, 0xb8, 0xcd, 0xbf, -0x1e, 0x63, 0x04, 0xad, 0xb7, 0xcd, 0x43, 0x62, 0x4c, 0xe0, 0x1a, 0xd4, -0x21, 0xe2, 0xdd, 0x33, 0xdf, 0xb1, 0xdd, 0xdc, 0x01, 0x22, 0x18, 0xce, -0xa1, 0xd8, 0xcb, 0x67, 0xd5, 0x38, 0x4a, 0xbc, 0xd5, 0x81, 0x3d, 0x03, -0x98, 0x35, 0x60, 0x41, 0x85, 0x0c, 0x1d, 0xe7, 0x76, 0xf8, 0x11, 0x52, -0x76, 0xf6, 0x06, 0x16, 0x02, 0x45, 0xc8, 0xd8, 0x2f, 0x5e, 0x57, 0xbc, -0x3b, 0x89, 0x97, 0x09, 0x3e, 0x03, 0x34, 0x1a, 0x9d, 0x37, 0x87, 0x48, -0x0a, 0xe0, 0xa7, 0x4f, 0x8c, 0x3a, 0xa2, 0xaf, 0xfd, 0x7b, 0x80, 0xcf, -0xe5, 0x18, 0x61, 0x68, 0xba, 0x61, 0x8b, 0x09, 0xaa, 0xa3, 0x0c, 0x47, -0x3c, 0x43, 0x03, 0xac, 0xa3, 0x2e, 0x5e, 0x72, 0x0c, 0x80, 0x19, 0x61, -0xe6, 0x6e, 0x0e, 0xd9, 0xe8, 0xe8, 0xaf, 0x11, 0x9b, 0x4a, 0x73, 0x7a, -0x61, 0x66, 0xf0, 0x54, 0x1d, 0x18, 0xc8, 0x23, 0x36, 0xbf, 0xb5, 0xf4, -0x86, 0x54, 0xed, 0xb5, 0x91, 0xee, 0xb8, 0xbc, 0xde, 0xc3, 0x87, 0x9b, -0x2f, 0x81, 0xf2, 0xee, 0xa3, 0xec, 0x02 \ No newline at end of file diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/testcard.png b/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/testcard.png deleted file mode 100755 index 43088bb..0000000 Binary files a/src/dependencies/zstd-1.5.4/build/single_file_libs/examples/testcard.png and /dev/null differ diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/zstd-in.c b/src/dependencies/zstd-1.5.4/build/single_file_libs/zstd-in.c deleted file mode 100644 index e6fca9e..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/zstd-in.c +++ /dev/null @@ -1,90 +0,0 @@ -/** - * \file zstd.c - * Single-file Zstandard library. - * - * Generate using: - * \code - * python combine.py -r ../../lib -x legacy/zstd_legacy.h -o zstd.c zstd-in.c - * \endcode - */ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ -/* - * Settings to bake for the single library file. - * - * Note: It's important that none of these affects 'zstd.h' (only the - * implementation files we're amalgamating). - * - * Note: MEM_MODULE stops xxhash redefining BYTE, U16, etc., which are also - * defined in mem.h (breaking C99 compatibility). - * - * Note: the undefs for xxHash allow Zstd's implementation to coincide with - * standalone xxHash usage (with global defines). - * - * Note: if you enable ZSTD_LEGACY_SUPPORT the combine.py script will need - * re-running without the "-x legacy/zstd_legacy.h" option (it excludes the - * legacy support at the source level). - * - * Note: multithreading is enabled for all platforms apart from Emscripten. - */ -#define DEBUGLEVEL 0 -#define MEM_MODULE -#undef XXH_NAMESPACE -#define XXH_NAMESPACE ZSTD_ -#undef XXH_PRIVATE_API -#define XXH_PRIVATE_API -#undef XXH_INLINE_ALL -#define XXH_INLINE_ALL -#define ZSTD_LEGACY_SUPPORT 0 -#ifndef __EMSCRIPTEN__ -#define ZSTD_MULTITHREAD -#endif -#define ZSTD_TRACE 0 -/* TODO: Can't amalgamate ASM function */ -#define ZSTD_DISABLE_ASM 1 - -/* Include zstd_deps.h first with all the options we need enabled. */ -#define ZSTD_DEPS_NEED_MALLOC -#define ZSTD_DEPS_NEED_MATH64 -#include "common/zstd_deps.h" - -#include "common/debug.c" -#include "common/entropy_common.c" -#include "common/error_private.c" -#include "common/fse_decompress.c" -#include "common/threading.c" -#include "common/pool.c" -#include "common/zstd_common.c" - -#include "compress/fse_compress.c" -#include "compress/hist.c" -#include "compress/huf_compress.c" -#include "compress/zstd_compress_literals.c" -#include "compress/zstd_compress_sequences.c" -#include "compress/zstd_compress_superblock.c" -#include "compress/zstd_compress.c" -#include "compress/zstd_double_fast.c" -#include "compress/zstd_fast.c" -#include "compress/zstd_lazy.c" -#include "compress/zstd_ldm.c" -#include "compress/zstd_opt.c" -#ifdef ZSTD_MULTITHREAD -#include "compress/zstdmt_compress.c" -#endif - -#include "decompress/huf_decompress.c" -#include "decompress/zstd_ddict.c" -#include "decompress/zstd_decompress.c" -#include "decompress/zstd_decompress_block.c" - -#include "dictBuilder/cover.c" -#include "dictBuilder/divsufsort.c" -#include "dictBuilder/fastcover.c" -#include "dictBuilder/zdict.c" diff --git a/src/dependencies/zstd-1.5.4/build/single_file_libs/zstddeclib-in.c b/src/dependencies/zstd-1.5.4/build/single_file_libs/zstddeclib-in.c deleted file mode 100644 index 8d9c1f5..0000000 --- a/src/dependencies/zstd-1.5.4/build/single_file_libs/zstddeclib-in.c +++ /dev/null @@ -1,62 +0,0 @@ -/** - * \file zstddeclib.c - * Single-file Zstandard decompressor. - * - * Generate using: - * \code - * python combine.py -r ../../lib -x legacy/zstd_legacy.h -o zstddeclib.c zstddeclib-in.c - * \endcode - */ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ -/* - * Settings to bake for the standalone decompressor. - * - * Note: It's important that none of these affects 'zstd.h' (only the - * implementation files we're amalgamating). - * - * Note: MEM_MODULE stops xxhash redefining BYTE, U16, etc., which are also - * defined in mem.h (breaking C99 compatibility). - * - * Note: the undefs for xxHash allow Zstd's implementation to coincide with - * standalone xxHash usage (with global defines). - * - * Note: if you enable ZSTD_LEGACY_SUPPORT the combine.py script will need - * re-running without the "-x legacy/zstd_legacy.h" option (it excludes the - * legacy support at the source level). - */ -#define DEBUGLEVEL 0 -#define MEM_MODULE -#undef XXH_NAMESPACE -#define XXH_NAMESPACE ZSTD_ -#undef XXH_PRIVATE_API -#define XXH_PRIVATE_API -#undef XXH_INLINE_ALL -#define XXH_INLINE_ALL -#define ZSTD_LEGACY_SUPPORT 0 -#define ZSTD_STRIP_ERROR_STRINGS -#define ZSTD_TRACE 0 -/* TODO: Can't amalgamate ASM function */ -#define ZSTD_DISABLE_ASM 1 - -/* Include zstd_deps.h first with all the options we need enabled. */ -#define ZSTD_DEPS_NEED_MALLOC -#include "common/zstd_deps.h" - -#include "common/debug.c" -#include "common/entropy_common.c" -#include "common/error_private.c" -#include "common/fse_decompress.c" -#include "common/zstd_common.c" - -#include "decompress/huf_decompress.c" -#include "decompress/zstd_ddict.c" -#include "decompress/zstd_decompress.c" -#include "decompress/zstd_decompress_block.c" diff --git a/src/dependencies/zstd-1.5.4/lib/dll/example/build_package.bat b/src/dependencies/zstd-1.5.4/lib/dll/example/build_package.bat deleted file mode 100644 index 8baabc7..0000000 --- a/src/dependencies/zstd-1.5.4/lib/dll/example/build_package.bat +++ /dev/null @@ -1,20 +0,0 @@ -@ECHO OFF -MKDIR bin\dll bin\static bin\example bin\include -COPY tests\fullbench.c bin\example\ -COPY programs\datagen.c bin\example\ -COPY programs\datagen.h bin\example\ -COPY programs\util.h bin\example\ -COPY programs\platform.h bin\example\ -COPY lib\common\mem.h bin\example\ -COPY lib\common\zstd_internal.h bin\example\ -COPY lib\common\error_private.h bin\example\ -COPY lib\common\xxhash.h bin\example\ -COPY lib\libzstd.a bin\static\libzstd_static.lib -COPY lib\dll\libzstd.* bin\dll\ -COPY lib\dll\example\Makefile bin\example\ -COPY lib\dll\example\fullbench-dll.* bin\example\ -COPY lib\dll\example\README.md bin\ -COPY lib\zstd.h bin\include\ -COPY lib\common\zstd_errors.h bin\include\ -COPY lib\dictBuilder\zdict.h bin\include\ -COPY programs\zstd.exe bin\zstd.exe diff --git a/src/dependencies/zstd-1.5.4/programs/benchzstd.c b/src/dependencies/zstd-1.5.4/programs/benchzstd.c deleted file mode 100644 index a76db5f..0000000 --- a/src/dependencies/zstd-1.5.4/programs/benchzstd.c +++ /dev/null @@ -1,901 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ - - -/* ************************************** -* Tuning parameters -****************************************/ -#ifndef BMK_TIMETEST_DEFAULT_S /* default minimum time per test */ -# define BMK_TIMETEST_DEFAULT_S 3 -#endif - - -/* ************************************* -* Includes -***************************************/ -#include "platform.h" /* Large Files support */ -#include "util.h" /* UTIL_getFileSize, UTIL_sleep */ -#include /* malloc, free */ -#include /* memset, strerror */ -#include /* fprintf, fopen */ -#include -#include /* assert */ - -#include "timefn.h" /* UTIL_time_t */ -#include "benchfn.h" -#include "../lib/common/mem.h" -#ifndef ZSTD_STATIC_LINKING_ONLY -#define ZSTD_STATIC_LINKING_ONLY -#endif -#include "../lib/zstd.h" -#include "datagen.h" /* RDG_genBuffer */ -#ifndef XXH_INLINE_ALL -#define XXH_INLINE_ALL -#endif -#include "../lib/common/xxhash.h" -#include "benchzstd.h" -#include "../lib/zstd_errors.h" - - -/* ************************************* -* Constants -***************************************/ -#ifndef ZSTD_GIT_COMMIT -# define ZSTD_GIT_COMMIT_STRING "" -#else -# define ZSTD_GIT_COMMIT_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_GIT_COMMIT) -#endif - -#define TIMELOOP_MICROSEC (1*1000000ULL) /* 1 second */ -#define TIMELOOP_NANOSEC (1*1000000000ULL) /* 1 second */ -#define ACTIVEPERIOD_MICROSEC (70*TIMELOOP_MICROSEC) /* 70 seconds */ -#define COOLPERIOD_SEC 10 - -#define KB *(1 <<10) -#define MB *(1 <<20) -#define GB *(1U<<30) - -#define BMK_RUNTEST_DEFAULT_MS 1000 - -static const size_t maxMemory = (sizeof(size_t)==4) ? - /* 32-bit */ (2 GB - 64 MB) : - /* 64-bit */ (size_t)(1ULL << ((sizeof(size_t)*8)-31)); - - -/* ************************************* -* console display -***************************************/ -#define DISPLAY(...) { fprintf(stderr, __VA_ARGS__); fflush(NULL); } -#define DISPLAYLEVEL(l, ...) if (displayLevel>=l) { DISPLAY(__VA_ARGS__); } -/* 0 : no display; 1: errors; 2 : + result + interaction + warnings; 3 : + progression; 4 : + information */ -#define OUTPUT(...) { fprintf(stdout, __VA_ARGS__); fflush(NULL); } -#define OUTPUTLEVEL(l, ...) if (displayLevel>=l) { OUTPUT(__VA_ARGS__); } - - -/* ************************************* -* Exceptions -***************************************/ -#ifndef DEBUG -# define DEBUG 0 -#endif -#define DEBUGOUTPUT(...) { if (DEBUG) DISPLAY(__VA_ARGS__); } - -#define RETURN_ERROR_INT(errorNum, ...) { \ - DEBUGOUTPUT("%s: %i: \n", __FILE__, __LINE__); \ - DISPLAYLEVEL(1, "Error %i : ", errorNum); \ - DISPLAYLEVEL(1, __VA_ARGS__); \ - DISPLAYLEVEL(1, " \n"); \ - return errorNum; \ -} - -#define CHECK_Z(zf) { \ - size_t const zerr = zf; \ - if (ZSTD_isError(zerr)) { \ - DEBUGOUTPUT("%s: %i: \n", __FILE__, __LINE__); \ - DISPLAY("Error : "); \ - DISPLAY("%s failed : %s", \ - #zf, ZSTD_getErrorName(zerr)); \ - DISPLAY(" \n"); \ - exit(1); \ - } \ -} - -#define RETURN_ERROR(errorNum, retType, ...) { \ - retType r; \ - memset(&r, 0, sizeof(retType)); \ - DEBUGOUTPUT("%s: %i: \n", __FILE__, __LINE__); \ - DISPLAYLEVEL(1, "Error %i : ", errorNum); \ - DISPLAYLEVEL(1, __VA_ARGS__); \ - DISPLAYLEVEL(1, " \n"); \ - r.tag = errorNum; \ - return r; \ -} - - -/* ************************************* -* Benchmark Parameters -***************************************/ - -BMK_advancedParams_t BMK_initAdvancedParams(void) { - BMK_advancedParams_t const res = { - BMK_both, /* mode */ - BMK_TIMETEST_DEFAULT_S, /* nbSeconds */ - 0, /* blockSize */ - 0, /* nbWorkers */ - 0, /* realTime */ - 0, /* additionalParam */ - 0, /* ldmFlag */ - 0, /* ldmMinMatch */ - 0, /* ldmHashLog */ - 0, /* ldmBuckSizeLog */ - 0, /* ldmHashRateLog */ - ZSTD_ps_auto, /* literalCompressionMode */ - 0 /* useRowMatchFinder */ - }; - return res; -} - - -/* ******************************************************** -* Bench functions -**********************************************************/ -typedef struct { - const void* srcPtr; - size_t srcSize; - void* cPtr; - size_t cRoom; - size_t cSize; - void* resPtr; - size_t resSize; -} blockParam_t; - -#undef MIN -#undef MAX -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -static void -BMK_initCCtx(ZSTD_CCtx* ctx, - const void* dictBuffer, size_t dictBufferSize, - int cLevel, - const ZSTD_compressionParameters* comprParams, - const BMK_advancedParams_t* adv) -{ - ZSTD_CCtx_reset(ctx, ZSTD_reset_session_and_parameters); - if (adv->nbWorkers==1) { - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_nbWorkers, 0)); - } else { - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_nbWorkers, adv->nbWorkers)); - } - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, cLevel)); - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_useRowMatchFinder, adv->useRowMatchFinder)); - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_enableLongDistanceMatching, adv->ldmFlag)); - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_ldmMinMatch, adv->ldmMinMatch)); - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_ldmHashLog, adv->ldmHashLog)); - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_ldmBucketSizeLog, adv->ldmBucketSizeLog)); - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_ldmHashRateLog, adv->ldmHashRateLog)); - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_windowLog, (int)comprParams->windowLog)); - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_hashLog, (int)comprParams->hashLog)); - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_chainLog, (int)comprParams->chainLog)); - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_searchLog, (int)comprParams->searchLog)); - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_minMatch, (int)comprParams->minMatch)); - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_targetLength, (int)comprParams->targetLength)); - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_literalCompressionMode, (int)adv->literalCompressionMode)); - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_strategy, (int)comprParams->strategy)); - CHECK_Z(ZSTD_CCtx_loadDictionary(ctx, dictBuffer, dictBufferSize)); -} - -static void BMK_initDCtx(ZSTD_DCtx* dctx, - const void* dictBuffer, size_t dictBufferSize) { - CHECK_Z(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_and_parameters)); - CHECK_Z(ZSTD_DCtx_loadDictionary(dctx, dictBuffer, dictBufferSize)); -} - - -typedef struct { - ZSTD_CCtx* cctx; - const void* dictBuffer; - size_t dictBufferSize; - int cLevel; - const ZSTD_compressionParameters* comprParams; - const BMK_advancedParams_t* adv; -} BMK_initCCtxArgs; - -static size_t local_initCCtx(void* payload) { - BMK_initCCtxArgs* ag = (BMK_initCCtxArgs*)payload; - BMK_initCCtx(ag->cctx, ag->dictBuffer, ag->dictBufferSize, ag->cLevel, ag->comprParams, ag->adv); - return 0; -} - -typedef struct { - ZSTD_DCtx* dctx; - const void* dictBuffer; - size_t dictBufferSize; -} BMK_initDCtxArgs; - -static size_t local_initDCtx(void* payload) { - BMK_initDCtxArgs* ag = (BMK_initDCtxArgs*)payload; - BMK_initDCtx(ag->dctx, ag->dictBuffer, ag->dictBufferSize); - return 0; -} - - -/* `addArgs` is the context */ -static size_t local_defaultCompress( - const void* srcBuffer, size_t srcSize, - void* dstBuffer, size_t dstSize, - void* addArgs) -{ - ZSTD_CCtx* const cctx = (ZSTD_CCtx*)addArgs; - return ZSTD_compress2(cctx, dstBuffer, dstSize, srcBuffer, srcSize); -} - -/* `addArgs` is the context */ -static size_t local_defaultDecompress( - const void* srcBuffer, size_t srcSize, - void* dstBuffer, size_t dstCapacity, - void* addArgs) -{ - size_t moreToFlush = 1; - ZSTD_DCtx* const dctx = (ZSTD_DCtx*)addArgs; - ZSTD_inBuffer in; - ZSTD_outBuffer out; - in.src = srcBuffer; in.size = srcSize; in.pos = 0; - out.dst = dstBuffer; out.size = dstCapacity; out.pos = 0; - while (moreToFlush) { - if(out.pos == out.size) { - return (size_t)-ZSTD_error_dstSize_tooSmall; - } - moreToFlush = ZSTD_decompressStream(dctx, &out, &in); - if (ZSTD_isError(moreToFlush)) { - return moreToFlush; - } - } - return out.pos; - -} - - -/* ================================================================= */ -/* Benchmark Zstandard, mem-to-mem scenarios */ -/* ================================================================= */ - -int BMK_isSuccessful_benchOutcome(BMK_benchOutcome_t outcome) -{ - return outcome.tag == 0; -} - -BMK_benchResult_t BMK_extract_benchResult(BMK_benchOutcome_t outcome) -{ - assert(outcome.tag == 0); - return outcome.internal_never_use_directly; -} - -static BMK_benchOutcome_t BMK_benchOutcome_error(void) -{ - BMK_benchOutcome_t b; - memset(&b, 0, sizeof(b)); - b.tag = 1; - return b; -} - -static BMK_benchOutcome_t BMK_benchOutcome_setValidResult(BMK_benchResult_t result) -{ - BMK_benchOutcome_t b; - b.tag = 0; - b.internal_never_use_directly = result; - return b; -} - - -/* benchMem with no allocation */ -static BMK_benchOutcome_t -BMK_benchMemAdvancedNoAlloc( - const void** srcPtrs, size_t* srcSizes, - void** cPtrs, size_t* cCapacities, size_t* cSizes, - void** resPtrs, size_t* resSizes, - void** resultBufferPtr, void* compressedBuffer, - size_t maxCompressedSize, - BMK_timedFnState_t* timeStateCompress, - BMK_timedFnState_t* timeStateDecompress, - - const void* srcBuffer, size_t srcSize, - const size_t* fileSizes, unsigned nbFiles, - const int cLevel, - const ZSTD_compressionParameters* comprParams, - const void* dictBuffer, size_t dictBufferSize, - ZSTD_CCtx* cctx, ZSTD_DCtx* dctx, - int displayLevel, const char* displayName, - const BMK_advancedParams_t* adv) -{ - size_t const blockSize = ((adv->blockSize>=32 && (adv->mode != BMK_decodeOnly)) ? adv->blockSize : srcSize) + (!srcSize); /* avoid div by 0 */ - BMK_benchResult_t benchResult; - size_t const loadedCompressedSize = srcSize; - size_t cSize = 0; - double ratio = 0.; - U32 nbBlocks; - - assert(cctx != NULL); assert(dctx != NULL); - - /* init */ - memset(&benchResult, 0, sizeof(benchResult)); - if (strlen(displayName)>17) displayName += strlen(displayName) - 17; /* display last 17 characters */ - if (adv->mode == BMK_decodeOnly) { - /* benchmark only decompression : source must be already compressed */ - const char* srcPtr = (const char*)srcBuffer; - U64 totalDSize64 = 0; - U32 fileNb; - for (fileNb=0; fileNb decodedSize) { /* size_t overflow */ - RETURN_ERROR(32, BMK_benchOutcome_t, "decompressed size is too large for local system"); - } - *resultBufferPtr = malloc(decodedSize); - if (!(*resultBufferPtr)) { - RETURN_ERROR(33, BMK_benchOutcome_t, "allocation error: not enough memory"); - } - cSize = srcSize; - srcSize = decodedSize; - ratio = (double)srcSize / (double)cSize; - } - } - - /* Init data blocks */ - { const char* srcPtr = (const char*)srcBuffer; - char* cPtr = (char*)compressedBuffer; - char* resPtr = (char*)(*resultBufferPtr); - U32 fileNb; - for (nbBlocks=0, fileNb=0; fileNbmode == BMK_decodeOnly) ? 1 : (U32)((remaining + (blockSize-1)) / blockSize); - U32 const blockEnd = nbBlocks + nbBlocksforThisFile; - for ( ; nbBlocksmode == BMK_decodeOnly) ? thisBlockSize : ZSTD_compressBound(thisBlockSize); - resPtrs[nbBlocks] = resPtr; - resSizes[nbBlocks] = (adv->mode == BMK_decodeOnly) ? (size_t) ZSTD_findDecompressedSize(srcPtr, thisBlockSize) : thisBlockSize; - srcPtr += thisBlockSize; - cPtr += cCapacities[nbBlocks]; - resPtr += thisBlockSize; - remaining -= thisBlockSize; - if (adv->mode == BMK_decodeOnly) { - cSizes[nbBlocks] = thisBlockSize; - benchResult.cSize = thisBlockSize; - } } } } - - /* warming up `compressedBuffer` */ - if (adv->mode == BMK_decodeOnly) { - memcpy(compressedBuffer, srcBuffer, loadedCompressedSize); - } else { - RDG_genBuffer(compressedBuffer, maxCompressedSize, 0.10, 0.50, 1); - } - - if (!UTIL_support_MT_measurements() && adv->nbWorkers > 1) { - OUTPUTLEVEL(2, "Warning : time measurements may be incorrect in multithreading mode... \n") - } - - /* Bench */ - { U64 const crcOrig = (adv->mode == BMK_decodeOnly) ? 0 : XXH64(srcBuffer, srcSize, 0); -# define NB_MARKS 4 - const char* marks[NB_MARKS] = { " |", " /", " =", " \\" }; - U32 markNb = 0; - int compressionCompleted = (adv->mode == BMK_decodeOnly); - int decompressionCompleted = (adv->mode == BMK_compressOnly); - BMK_benchParams_t cbp, dbp; - BMK_initCCtxArgs cctxprep; - BMK_initDCtxArgs dctxprep; - - cbp.benchFn = local_defaultCompress; /* ZSTD_compress2 */ - cbp.benchPayload = cctx; - cbp.initFn = local_initCCtx; /* BMK_initCCtx */ - cbp.initPayload = &cctxprep; - cbp.errorFn = ZSTD_isError; - cbp.blockCount = nbBlocks; - cbp.srcBuffers = srcPtrs; - cbp.srcSizes = srcSizes; - cbp.dstBuffers = cPtrs; - cbp.dstCapacities = cCapacities; - cbp.blockResults = cSizes; - - cctxprep.cctx = cctx; - cctxprep.dictBuffer = dictBuffer; - cctxprep.dictBufferSize = dictBufferSize; - cctxprep.cLevel = cLevel; - cctxprep.comprParams = comprParams; - cctxprep.adv = adv; - - dbp.benchFn = local_defaultDecompress; - dbp.benchPayload = dctx; - dbp.initFn = local_initDCtx; - dbp.initPayload = &dctxprep; - dbp.errorFn = ZSTD_isError; - dbp.blockCount = nbBlocks; - dbp.srcBuffers = (const void* const *) cPtrs; - dbp.srcSizes = cSizes; - dbp.dstBuffers = resPtrs; - dbp.dstCapacities = resSizes; - dbp.blockResults = NULL; - - dctxprep.dctx = dctx; - dctxprep.dictBuffer = dictBuffer; - dctxprep.dictBufferSize = dictBufferSize; - - OUTPUTLEVEL(2, "\r%70s\r", ""); /* blank line */ - assert(srcSize < UINT_MAX); - OUTPUTLEVEL(2, "%2s-%-17.17s :%10u -> \r", marks[markNb], displayName, (unsigned)srcSize); - - while (!(compressionCompleted && decompressionCompleted)) { - if (!compressionCompleted) { - BMK_runOutcome_t const cOutcome = BMK_benchTimedFn( timeStateCompress, cbp); - - if (!BMK_isSuccessful_runOutcome(cOutcome)) { - RETURN_ERROR(30, BMK_benchOutcome_t, "compression error"); - } - - { BMK_runTime_t const cResult = BMK_extract_runTime(cOutcome); - cSize = cResult.sumOfReturn; - ratio = (double)srcSize / (double)cSize; - { BMK_benchResult_t newResult; - newResult.cSpeed = (U64)((double)srcSize * TIMELOOP_NANOSEC / cResult.nanoSecPerRun); - benchResult.cSize = cSize; - if (newResult.cSpeed > benchResult.cSpeed) - benchResult.cSpeed = newResult.cSpeed; - } } - - { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; - assert(cSize < UINT_MAX); - OUTPUTLEVEL(2, "%2s-%-17.17s :%10u ->%10u (x%5.*f), %6.*f MB/s \r", - marks[markNb], displayName, - (unsigned)srcSize, (unsigned)cSize, - ratioAccuracy, ratio, - benchResult.cSpeed < (10 * MB_UNIT) ? 2 : 1, (double)benchResult.cSpeed / MB_UNIT); - } - compressionCompleted = BMK_isCompleted_TimedFn(timeStateCompress); - } - - if(!decompressionCompleted) { - BMK_runOutcome_t const dOutcome = BMK_benchTimedFn(timeStateDecompress, dbp); - - if(!BMK_isSuccessful_runOutcome(dOutcome)) { - RETURN_ERROR(30, BMK_benchOutcome_t, "decompression error"); - } - - { BMK_runTime_t const dResult = BMK_extract_runTime(dOutcome); - U64 const newDSpeed = (U64)((double)srcSize * TIMELOOP_NANOSEC / dResult.nanoSecPerRun); - if (newDSpeed > benchResult.dSpeed) - benchResult.dSpeed = newDSpeed; - } - - { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; - OUTPUTLEVEL(2, "%2s-%-17.17s :%10u ->%10u (x%5.*f), %6.*f MB/s, %6.1f MB/s\r", - marks[markNb], displayName, - (unsigned)srcSize, (unsigned)cSize, - ratioAccuracy, ratio, - benchResult.cSpeed < (10 * MB_UNIT) ? 2 : 1, (double)benchResult.cSpeed / MB_UNIT, - (double)benchResult.dSpeed / MB_UNIT); - } - decompressionCompleted = BMK_isCompleted_TimedFn(timeStateDecompress); - } - markNb = (markNb+1) % NB_MARKS; - } /* while (!(compressionCompleted && decompressionCompleted)) */ - - /* CRC Checking */ - { const BYTE* resultBuffer = (const BYTE*)(*resultBufferPtr); - U64 const crcCheck = XXH64(resultBuffer, srcSize, 0); - if ((adv->mode == BMK_both) && (crcOrig!=crcCheck)) { - size_t u; - DISPLAY("!!! WARNING !!! %14s : Invalid Checksum : %x != %x \n", - displayName, (unsigned)crcOrig, (unsigned)crcCheck); - for (u=0; u u) break; - bacc += srcSizes[segNb]; - } - pos = (U32)(u - bacc); - bNb = pos / (128 KB); - DISPLAY("(sample %u, block %u, pos %u) \n", segNb, bNb, pos); - { size_t const lowest = (u>5) ? 5 : u; - size_t n; - DISPLAY("origin: "); - for (n=lowest; n>0; n--) - DISPLAY("%02X ", ((const BYTE*)srcBuffer)[u-n]); - DISPLAY(" :%02X: ", ((const BYTE*)srcBuffer)[u]); - for (n=1; n<3; n++) - DISPLAY("%02X ", ((const BYTE*)srcBuffer)[u+n]); - DISPLAY(" \n"); - DISPLAY("decode: "); - for (n=lowest; n>0; n--) - DISPLAY("%02X ", resultBuffer[u-n]); - DISPLAY(" :%02X: ", resultBuffer[u]); - for (n=1; n<3; n++) - DISPLAY("%02X ", resultBuffer[u+n]); - DISPLAY(" \n"); - } - break; - } - if (u==srcSize-1) { /* should never happen */ - DISPLAY("no difference detected\n"); - } - } /* for (u=0; umode == BMK_both) && (crcOrig!=crcCheck)) */ - } /* CRC Checking */ - - if (displayLevel == 1) { /* hidden display mode -q, used by python speed benchmark */ - double const cSpeed = (double)benchResult.cSpeed / MB_UNIT; - double const dSpeed = (double)benchResult.dSpeed / MB_UNIT; - if (adv->additionalParam) { - OUTPUT("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s (param=%d)\n", cLevel, (int)cSize, ratio, cSpeed, dSpeed, displayName, adv->additionalParam); - } else { - OUTPUT("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s\n", cLevel, (int)cSize, ratio, cSpeed, dSpeed, displayName); - } - } - - OUTPUTLEVEL(2, "%2i#\n", cLevel); - } /* Bench */ - - benchResult.cMem = (1ULL << (comprParams->windowLog)) + ZSTD_sizeof_CCtx(cctx); - return BMK_benchOutcome_setValidResult(benchResult); -} - -BMK_benchOutcome_t BMK_benchMemAdvanced(const void* srcBuffer, size_t srcSize, - void* dstBuffer, size_t dstCapacity, - const size_t* fileSizes, unsigned nbFiles, - int cLevel, const ZSTD_compressionParameters* comprParams, - const void* dictBuffer, size_t dictBufferSize, - int displayLevel, const char* displayName, const BMK_advancedParams_t* adv) - -{ - int const dstParamsError = !dstBuffer ^ !dstCapacity; /* must be both NULL or none */ - - size_t const blockSize = ((adv->blockSize>=32 && (adv->mode != BMK_decodeOnly)) ? adv->blockSize : srcSize) + (!srcSize) /* avoid div by 0 */ ; - U32 const maxNbBlocks = (U32) ((srcSize + (blockSize-1)) / blockSize) + nbFiles; - - /* these are the blockTable parameters, just split up */ - const void ** const srcPtrs = (const void**)malloc(maxNbBlocks * sizeof(void*)); - size_t* const srcSizes = (size_t*)malloc(maxNbBlocks * sizeof(size_t)); - - - void ** const cPtrs = (void**)malloc(maxNbBlocks * sizeof(void*)); - size_t* const cSizes = (size_t*)malloc(maxNbBlocks * sizeof(size_t)); - size_t* const cCapacities = (size_t*)malloc(maxNbBlocks * sizeof(size_t)); - - void ** const resPtrs = (void**)malloc(maxNbBlocks * sizeof(void*)); - size_t* const resSizes = (size_t*)malloc(maxNbBlocks * sizeof(size_t)); - - BMK_timedFnState_t* timeStateCompress = BMK_createTimedFnState(adv->nbSeconds * 1000, BMK_RUNTEST_DEFAULT_MS); - BMK_timedFnState_t* timeStateDecompress = BMK_createTimedFnState(adv->nbSeconds * 1000, BMK_RUNTEST_DEFAULT_MS); - - ZSTD_CCtx* const cctx = ZSTD_createCCtx(); - ZSTD_DCtx* const dctx = ZSTD_createDCtx(); - - const size_t maxCompressedSize = dstCapacity ? dstCapacity : ZSTD_compressBound(srcSize) + (maxNbBlocks * 1024); - - void* const internalDstBuffer = dstBuffer ? NULL : malloc(maxCompressedSize); - void* const compressedBuffer = dstBuffer ? dstBuffer : internalDstBuffer; - - BMK_benchOutcome_t outcome = BMK_benchOutcome_error(); /* error by default */ - - void* resultBuffer = srcSize ? malloc(srcSize) : NULL; - - int const allocationincomplete = !srcPtrs || !srcSizes || !cPtrs || - !cSizes || !cCapacities || !resPtrs || !resSizes || - !timeStateCompress || !timeStateDecompress || - !cctx || !dctx || - !compressedBuffer || !resultBuffer; - - - if (!allocationincomplete && !dstParamsError) { - outcome = BMK_benchMemAdvancedNoAlloc(srcPtrs, srcSizes, - cPtrs, cCapacities, cSizes, - resPtrs, resSizes, - &resultBuffer, - compressedBuffer, maxCompressedSize, - timeStateCompress, timeStateDecompress, - srcBuffer, srcSize, - fileSizes, nbFiles, - cLevel, comprParams, - dictBuffer, dictBufferSize, - cctx, dctx, - displayLevel, displayName, adv); - } - - /* clean up */ - BMK_freeTimedFnState(timeStateCompress); - BMK_freeTimedFnState(timeStateDecompress); - - ZSTD_freeCCtx(cctx); - ZSTD_freeDCtx(dctx); - - free(internalDstBuffer); - free(resultBuffer); - - free((void*)srcPtrs); - free(srcSizes); - free(cPtrs); - free(cSizes); - free(cCapacities); - free(resPtrs); - free(resSizes); - - if(allocationincomplete) { - RETURN_ERROR(31, BMK_benchOutcome_t, "allocation error : not enough memory"); - } - - if(dstParamsError) { - RETURN_ERROR(32, BMK_benchOutcome_t, "Dst parameters not coherent"); - } - return outcome; -} - -BMK_benchOutcome_t BMK_benchMem(const void* srcBuffer, size_t srcSize, - const size_t* fileSizes, unsigned nbFiles, - int cLevel, const ZSTD_compressionParameters* comprParams, - const void* dictBuffer, size_t dictBufferSize, - int displayLevel, const char* displayName) { - - BMK_advancedParams_t const adv = BMK_initAdvancedParams(); - return BMK_benchMemAdvanced(srcBuffer, srcSize, - NULL, 0, - fileSizes, nbFiles, - cLevel, comprParams, - dictBuffer, dictBufferSize, - displayLevel, displayName, &adv); -} - -static BMK_benchOutcome_t BMK_benchCLevel(const void* srcBuffer, size_t benchedSize, - const size_t* fileSizes, unsigned nbFiles, - int cLevel, const ZSTD_compressionParameters* comprParams, - const void* dictBuffer, size_t dictBufferSize, - int displayLevel, const char* displayName, - BMK_advancedParams_t const * const adv) -{ - const char* pch = strrchr(displayName, '\\'); /* Windows */ - if (!pch) pch = strrchr(displayName, '/'); /* Linux */ - if (pch) displayName = pch+1; - - if (adv->realTime) { - DISPLAYLEVEL(2, "Note : switching to real-time priority \n"); - SET_REALTIME_PRIORITY; - } - - if (displayLevel == 1 && !adv->additionalParam) /* --quiet mode */ - OUTPUT("bench %s %s: input %u bytes, %u seconds, %u KB blocks\n", - ZSTD_VERSION_STRING, ZSTD_GIT_COMMIT_STRING, - (unsigned)benchedSize, adv->nbSeconds, (unsigned)(adv->blockSize>>10)); - - return BMK_benchMemAdvanced(srcBuffer, benchedSize, - NULL, 0, - fileSizes, nbFiles, - cLevel, comprParams, - dictBuffer, dictBufferSize, - displayLevel, displayName, adv); -} - -BMK_benchOutcome_t BMK_syntheticTest(int cLevel, double compressibility, - const ZSTD_compressionParameters* compressionParams, - int displayLevel, const BMK_advancedParams_t* adv) -{ - char name[20] = {0}; - size_t const benchedSize = 10000000; - void* srcBuffer; - BMK_benchOutcome_t res; - - if (cLevel > ZSTD_maxCLevel()) { - RETURN_ERROR(15, BMK_benchOutcome_t, "Invalid Compression Level"); - } - - /* Memory allocation */ - srcBuffer = malloc(benchedSize); - if (!srcBuffer) RETURN_ERROR(21, BMK_benchOutcome_t, "not enough memory"); - - /* Fill input buffer */ - RDG_genBuffer(srcBuffer, benchedSize, compressibility, 0.0, 0); - - /* Bench */ - snprintf (name, sizeof(name), "Synthetic %2u%%", (unsigned)(compressibility*100)); - res = BMK_benchCLevel(srcBuffer, benchedSize, - &benchedSize /* ? */, 1 /* ? */, - cLevel, compressionParams, - NULL, 0, /* dictionary */ - displayLevel, name, adv); - - /* clean up */ - free(srcBuffer); - - return res; -} - - - -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 && requiredMem > 0); - - free(testmem); - return (size_t)(requiredMem); -} - -/*! BMK_loadFiles() : - * Loads `buffer` with content of files listed within `fileNamesTable`. - * At most, fills `buffer` entirely. */ -static int BMK_loadFiles(void* buffer, size_t bufferSize, - size_t* fileSizes, - const char* const * fileNamesTable, unsigned nbFiles, - int displayLevel) -{ - size_t pos = 0, totalSize = 0; - unsigned n; - for (n=0; n 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) RETURN_ERROR_INT(11, "could not read %s", fileNamesTable[n]); - pos += readSize; - } - fileSizes[n] = (size_t)fileSize; - totalSize += (size_t)fileSize; - fclose(f); - } } - - if (totalSize == 0) RETURN_ERROR_INT(12, "no data to bench"); - return 0; -} - -BMK_benchOutcome_t BMK_benchFilesAdvanced( - const char* const * fileNamesTable, unsigned nbFiles, - const char* dictFileName, int cLevel, - const ZSTD_compressionParameters* compressionParams, - int displayLevel, const BMK_advancedParams_t* adv) -{ - void* srcBuffer = NULL; - size_t benchedSize; - void* dictBuffer = NULL; - size_t dictBufferSize = 0; - size_t* fileSizes = NULL; - BMK_benchOutcome_t res; - U64 const totalSizeToLoad = UTIL_getTotalFileSize(fileNamesTable, nbFiles); - - if (!nbFiles) { - RETURN_ERROR(14, BMK_benchOutcome_t, "No Files to Benchmark"); - } - - if (cLevel > ZSTD_maxCLevel()) { - RETURN_ERROR(15, BMK_benchOutcome_t, "Invalid Compression Level"); - } - - if (totalSizeToLoad == UTIL_FILESIZE_UNKNOWN) { - RETURN_ERROR(9, BMK_benchOutcome_t, "Error loading files"); - } - - fileSizes = (size_t*)calloc(nbFiles, sizeof(size_t)); - if (!fileSizes) RETURN_ERROR(12, BMK_benchOutcome_t, "not enough memory for fileSizes"); - - /* Load dictionary */ - if (dictFileName != NULL) { - U64 const dictFileSize = UTIL_getFileSize(dictFileName); - if (dictFileSize == UTIL_FILESIZE_UNKNOWN) { - DISPLAYLEVEL(1, "error loading %s : %s \n", dictFileName, strerror(errno)); - free(fileSizes); - RETURN_ERROR(9, BMK_benchOutcome_t, "benchmark aborted"); - } - if (dictFileSize > 64 MB) { - free(fileSizes); - RETURN_ERROR(10, BMK_benchOutcome_t, "dictionary file %s too large", dictFileName); - } - dictBufferSize = (size_t)dictFileSize; - dictBuffer = malloc(dictBufferSize); - if (dictBuffer==NULL) { - free(fileSizes); - RETURN_ERROR(11, BMK_benchOutcome_t, "not enough memory for dictionary (%u bytes)", - (unsigned)dictBufferSize); - } - - { int const errorCode = BMK_loadFiles(dictBuffer, dictBufferSize, - fileSizes, &dictFileName /*?*/, - 1 /*?*/, displayLevel); - if (errorCode) { - res = BMK_benchOutcome_error(); - goto _cleanUp; - } } - } - - /* 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", (unsigned)(benchedSize >> 20)); - - srcBuffer = benchedSize ? malloc(benchedSize) : NULL; - if (!srcBuffer) { - free(dictBuffer); - free(fileSizes); - RETURN_ERROR(12, BMK_benchOutcome_t, "not enough memory"); - } - - /* Load input buffer */ - { int const errorCode = BMK_loadFiles(srcBuffer, benchedSize, - fileSizes, fileNamesTable, nbFiles, - displayLevel); - if (errorCode) { - res = BMK_benchOutcome_error(); - goto _cleanUp; - } } - - /* Bench */ - { char mfName[20] = {0}; - snprintf (mfName, sizeof(mfName), " %u files", nbFiles); - { const char* const displayName = (nbFiles > 1) ? mfName : fileNamesTable[0]; - res = BMK_benchCLevel(srcBuffer, benchedSize, - fileSizes, nbFiles, - cLevel, compressionParams, - dictBuffer, dictBufferSize, - displayLevel, displayName, - adv); - } } - -_cleanUp: - free(srcBuffer); - free(dictBuffer); - free(fileSizes); - return res; -} - - -BMK_benchOutcome_t BMK_benchFiles( - const char* const * fileNamesTable, unsigned nbFiles, - const char* dictFileName, - int cLevel, const ZSTD_compressionParameters* compressionParams, - int displayLevel) -{ - BMK_advancedParams_t const adv = BMK_initAdvancedParams(); - return BMK_benchFilesAdvanced(fileNamesTable, nbFiles, dictFileName, cLevel, compressionParams, displayLevel, &adv); -} diff --git a/src/dependencies/zstd-1.5.4/programs/windres/zstd.rc b/src/dependencies/zstd-1.5.4/programs/windres/zstd.rc deleted file mode 100644 index a2118c2..0000000 --- a/src/dependencies/zstd-1.5.4/programs/windres/zstd.rc +++ /dev/null @@ -1,51 +0,0 @@ -// 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", "Meta Platforms, Inc." - VALUE "FileDescription", "Zstandard - Fast and efficient compression algorithm" - VALUE "FileVersion", ZSTD_VERSION_STRING - VALUE "InternalName", "zstd.exe" - VALUE "LegalCopyright", "Copyright (c) Meta Platforms, Inc. and affiliates." - VALUE "OriginalFilename", "zstd.exe" - VALUE "ProductName", "Zstandard" - VALUE "ProductVersion", ZSTD_VERSION_STRING - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0409, 1200 - END -END - -#endif diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/bin/unzstd b/src/dependencies/zstd-1.5.4/tests/cli-tests/bin/unzstd deleted file mode 100755 index 7a40aec..0000000 --- a/src/dependencies/zstd-1.5.4/tests/cli-tests/bin/unzstd +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -zstdname=$(basename $0) - -if [ -z "$EXEC_PREFIX" ]; then - "$ZSTD_SYMLINK_DIR/$zstdname" $@ -else - $EXEC_PREFIX "$ZSTD_SYMLINK_DIR/$zstdname" $@ -fi diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/bin/zstdcat b/src/dependencies/zstd-1.5.4/tests/cli-tests/bin/zstdcat deleted file mode 100755 index 7a40aec..0000000 --- a/src/dependencies/zstd-1.5.4/tests/cli-tests/bin/zstdcat +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -zstdname=$(basename $0) - -if [ -z "$EXEC_PREFIX" ]; then - "$ZSTD_SYMLINK_DIR/$zstdname" $@ -else - $EXEC_PREFIX "$ZSTD_SYMLINK_DIR/$zstdname" $@ -fi diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/gzip-compat.sh b/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/gzip-compat.sh deleted file mode 100755 index bb72e05..0000000 --- a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/gzip-compat.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -set -e - -# Uncomment the set -v line for debugging -# set -v - -# Test gzip specific compression option -$ZSTD_SYMLINK_DIR/gzip --fast file ; $ZSTD_SYMLINK_DIR/gzip -d file.gz -$ZSTD_SYMLINK_DIR/gzip --best file ; $ZSTD_SYMLINK_DIR/gzip -d file.gz - -# Test -n / --no-name: do not embed original filename in archive -$ZSTD_SYMLINK_DIR/gzip -n file ; grep -qv file file.gz ; $ZSTD_SYMLINK_DIR/gzip -d file.gz -$ZSTD_SYMLINK_DIR/gzip --no-name file ; grep -qv file file.gz ; $ZSTD_SYMLINK_DIR/gzip -d file.gz -$ZSTD_SYMLINK_DIR/gzip -c --no-name file | grep -qv file diff --git a/src/dependencies/zstd-1.5.4/tests/datagencli.c b/src/dependencies/zstd-1.5.4/tests/datagencli.c deleted file mode 100644 index 09ec5e9..0000000 --- a/src/dependencies/zstd-1.5.4/tests/datagencli.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ - - -/*-************************************ -* Dependencies -**************************************/ -#include "util.h" /* Compiler options */ -#include /* fprintf, stderr */ -#include "datagen.h" /* RDG_generate */ - - -/*-************************************ -* Constants -**************************************/ -#define KB *(1 <<10) -#define MB *(1 <<20) -#define GB *(1U<<30) - -#define SIZE_DEFAULT ((64 KB) + 1) -#define SEED_DEFAULT 0 -#define COMPRESSIBILITY_DEFAULT 50 - - -/*-************************************ -* Macros -**************************************/ -#define DISPLAY(...) fprintf(stderr, __VA_ARGS__) -#define DISPLAYLEVEL(l, ...) if (displayLevel>=l) { DISPLAY(__VA_ARGS__); } -static unsigned displayLevel = 2; - - -/*-******************************************************* -* Command line -*********************************************************/ -static int usage(const char* programName) -{ - DISPLAY( "Compressible data generator\n"); - DISPLAY( "Usage :\n"); - DISPLAY( " %s [args]\n", programName); - DISPLAY( "\n"); - DISPLAY( "Arguments :\n"); - DISPLAY( " -g# : generate # data (default:%i)\n", SIZE_DEFAULT); - DISPLAY( " -s# : Select seed (default:%i)\n", SEED_DEFAULT); - DISPLAY( " -P# : Select compressibility in %% (default:%i%%)\n", - COMPRESSIBILITY_DEFAULT); - DISPLAY( " -h : display help and exit\n"); - return 0; -} - - -int main(int argc, const char** argv) -{ - unsigned probaU32 = COMPRESSIBILITY_DEFAULT; - double litProba = 0.0; - U64 size = SIZE_DEFAULT; - U32 seed = SEED_DEFAULT; - const char* const programName = argv[0]; - - int argNb; - for(argNb=1; argNb='0') && (*argument<='9')) - size *= 10, size += *argument++ - '0'; - if (*argument=='K') { size <<= 10; argument++; } - if (*argument=='M') { size <<= 20; argument++; } - if (*argument=='G') { size <<= 30; argument++; } - if (*argument=='B') { argument++; } - break; - case 's': - argument++; - seed=0; - while ((*argument>='0') && (*argument<='9')) - seed *= 10, seed += *argument++ - '0'; - break; - case 'P': - argument++; - probaU32 = 0; - while ((*argument>='0') && (*argument<='9')) - probaU32 *= 10, probaU32 += *argument++ - '0'; - if (probaU32>100) probaU32 = 100; - break; - case 'L': /* hidden argument : Literal distribution probability */ - argument++; - litProba=0.; - while ((*argument>='0') && (*argument<='9')) - litProba *= 10, litProba += *argument++ - '0'; - if (litProba>100.) litProba=100.; - litProba /= 100.; - break; - case 'v': - displayLevel = 4; - argument++; - break; - default: - return usage(programName); - } - } } } /* for(argNb=1; argNb diff tests/regression/results.csv $CIRCLE_ARTIFACTS/results.csv" + diff tests/regression/results.csv $CIRCLE_ARTIFACTS/results.csv + - uses: actions/upload-artifact@v4 + with: + path: "/tmp/circleci-artifacts" diff --git a/src/dependencies/zstd-1.5.4/.github/workflows/dev-long-tests.yml b/src/dependencies/zstd-1.5.6/.github/workflows/dev-long-tests.yml similarity index 66% rename from src/dependencies/zstd-1.5.4/.github/workflows/dev-long-tests.yml rename to src/dependencies/zstd-1.5.6/.github/workflows/dev-long-tests.yml index 1c8c9ec..eb8f40a 100644 --- a/src/dependencies/zstd-1.5.4/.github/workflows/dev-long-tests.yml +++ b/src/dependencies/zstd-1.5.6/.github/workflows/dev-long-tests.yml @@ -9,11 +9,13 @@ on: pull_request: branches: [ dev, release, actionsTest ] +permissions: read-all + jobs: make-all: runs-on: ubuntu-latest steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: make all run: make all @@ -24,7 +26,7 @@ jobs: DEVNULLRIGHTS: 1 READFROMBLOCKDEVICE: 1 steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: make test run: make test @@ -32,36 +34,50 @@ jobs: make-test-osx: runs-on: macos-latest steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: OS-X test run: make test # make -c lib all doesn't work because of the fact that it's not a tty + # lasts ~24mn + make-test-32bit: + runs-on: ubuntu-latest + env: + DEVNULLRIGHTS: 1 + READFROMBLOCKDEVICE: 1 + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: make test + run: | + sudo apt-get -qqq update + make libc6install + CFLAGS="-m32" make test + no-intrinsics-fuzztest: runs-on: ubuntu-latest steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: no intrinsics fuzztest run: MOREFLAGS="-DZSTD_NO_INTRINSICS" make -C tests fuzztest tsan-zstreamtest: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: thread sanitizer zstreamtest run: CC=clang ZSTREAM_TESTTIME=-T3mn make tsan-test-zstream ubsan-zstreamtest: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: undefined behavior sanitizer zstreamtest run: CC=clang make uasan-test-zstream # lasts ~15mn tsan-fuzztest: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: thread sanitizer fuzztest run: CC=clang make tsan-fuzztest @@ -69,7 +85,7 @@ jobs: big-tests-zstreamtest32: runs-on: ubuntu-latest steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: zstream tests in 32bit mode, with big tests run: | sudo apt-get -qqq update @@ -78,9 +94,9 @@ jobs: # lasts ~23mn gcc-8-asan-ubsan-testzstd: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: gcc-8 + ASan + UBSan + Test Zstd # See https://askubuntu.com/a/1428822 run: | @@ -90,16 +106,16 @@ jobs: CC=gcc-8 make -j uasan-test-zstd msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=${{matrix.toolset}} - /t:Clean,Build /p:Platform=${{matrix.platform}} /p:Configuration=${{matrix.configuration}} + /t:Clean,Build /p:Platform=${{matrix.platform}} /p:Configuration=${{matrix.configuration}} /warnaserror + - name: Build ${{matrix.name}} + working-directory: ${{env.GITHUB_WORKSPACE}} + # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference + if: ${{ matrix.arch != '' }} + run: > + msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=${{matrix.toolset}} + /t:Clean,Build /p:Platform=${{matrix.platform}} /p:Configuration=${{matrix.configuration}} /warnaserror + /p:InstructionSet=${{matrix.arch}} - # This tests that we don't accidently grow the size too much. + # This tests that we don't accidentally grow the size too much. # If the size grows intentionally, you can raise these numbers. # But we do need to think about binary size, since it is a concern. libzstd-size: runs-on: ubuntu-latest steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: libzstd size test run: | make clean && make -j -C lib libzstd && ./tests/check_size.py lib/libzstd.so 1100000 @@ -295,7 +333,7 @@ jobs: minimal-decompressor-macros: runs-on: ubuntu-latest steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: minimal decompressor macros run: | make clean && make -j all ZSTD_LIB_MINIFY=1 MOREFLAGS="-Werror" @@ -306,11 +344,13 @@ jobs: make clean && make check MOREFLAGS="-Werror -DHUF_FORCE_DECOMPRESS_X2 -DZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG" make clean && make -j all MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" make clean && make check MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" + make clean && make check ZSTD_LIB_EXCLUDE_COMPRESSORS_DFAST_AND_UP=1 MOREFLAGS="-Werror" + make clean && make check ZSTD_LIB_EXCLUDE_COMPRESSORS_GREEDY_AND_UP=1 MOREFLAGS="-Werror" dynamic-bmi2: runs-on: ubuntu-latest steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: dynamic bmi2 tests run: | make clean && make -j check MOREFLAGS="-O0 -Werror -mbmi2" @@ -322,13 +362,12 @@ jobs: test-variants: runs-on: ubuntu-latest steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: make all variants & validate run: | make -j -C programs allVariants MOREFLAGS=-O0 ./tests/test-variants.sh - qemu-consistency: name: QEMU ${{ matrix.name }} runs-on: ubuntu-20.04 @@ -342,13 +381,15 @@ jobs: { name: PPC64LE, xcc_pkg: gcc-powerpc64le-linux-gnu, xcc: powerpc64le-linux-gnu-gcc, xemu_pkg: qemu-system-ppc, xemu: qemu-ppc64le-static }, { name: S390X, xcc_pkg: gcc-s390x-linux-gnu, xcc: s390x-linux-gnu-gcc, xemu_pkg: qemu-system-s390x, xemu: qemu-s390x-static }, { name: MIPS, xcc_pkg: gcc-mips-linux-gnu, xcc: mips-linux-gnu-gcc, xemu_pkg: qemu-system-mips, xemu: qemu-mips-static }, + { name: RISC-V, xcc_pkg: gcc-riscv64-linux-gnu, xcc: riscv64-linux-gnu-gcc, xemu_pkg: qemu-system-riscv64,xemu: qemu-riscv64-static }, { name: M68K, xcc_pkg: gcc-m68k-linux-gnu, xcc: m68k-linux-gnu-gcc, xemu_pkg: qemu-system-m68k, xemu: qemu-m68k-static }, + { name: SPARC, xcc_pkg: gcc-sparc64-linux-gnu, xcc: sparc64-linux-gnu-gcc, xemu_pkg: qemu-system-sparc, xemu: qemu-sparc64-static }, ] env: # Set environment variables XCC: ${{ matrix.xcc }} XEMU: ${{ matrix.xemu }} steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: apt update & install run: | sudo apt-get update @@ -368,6 +409,7 @@ jobs: - name: ARM64 if: ${{ matrix.name == 'ARM64' }} run: | + LDFLAGS="-static -z force-bti" MOREFLAGS="-mbranch-protection=standard" CC=$XCC QEMU_SYS=$XEMU make clean check LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check - name: PPC if: ${{ matrix.name == 'PPC' }} @@ -385,10 +427,18 @@ jobs: if: ${{ matrix.name == 'MIPS' }} run: | LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check + - name: RISC-V + if: ${{ matrix.name == 'RISC-V' }} + run: | + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check - name: M68K if: ${{ matrix.name == 'M68K' }} run: | LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check + - name: SPARC + if: ${{ matrix.name == 'SPARC' }} + run: | + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check mingw-short-test: runs-on: windows-latest @@ -404,8 +454,8 @@ jobs: run: shell: msys2 {0} steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 - - uses: msys2/setup-msys2@v2 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - uses: msys2/setup-msys2@cc11e9188b693c2b100158c3322424c4cc1dadea # tag=v2.22.0 with: msystem: ${{ matrix.msystem }} install: make diffutils @@ -440,9 +490,9 @@ jobs: platform: [x64, Win32] configuration: [Release] steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: Add MSBuild to PATH - uses: microsoft/setup-msbuild@v1.3 + uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # tag=v2.0.0 - name: Build and run tests working-directory: ${{env.GITHUB_WORKSPACE}} env: @@ -461,8 +511,8 @@ jobs: runs-on: windows-latest steps: - run: git config --global core.autocrlf input - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 - - uses: cygwin/cygwin-install-action@f5e0f048310c425e84bc789f493a828c6dc80a25 # tag=master + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - uses: cygwin/cygwin-install-action@006ad0b0946ca6d0a3ea2d4437677fa767392401 # tag=master with: platform: x86_64 packages: >- @@ -483,31 +533,12 @@ jobs: make -C tests fuzzer && ./tests/fuzzer.exe -v -T1m - intel-cet-compatibility: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 - - name: Build Zstd - run: | - make -j zstd V=1 - readelf -n zstd - - name: Get Intel SDE - run: | - curl -LO https://downloadmirror.intel.com/684899/sde-external-9.0.0-2021-11-07-lin.tar.xz - tar xJvf sde-external-9.0.0-2021-11-07-lin.tar.xz - - name: Configure Permissions - run: | - echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope - - name: Run Under SDE - run: | - sde-external-9.0.0-2021-11-07-lin/sde -cet -cet-raise 0 -cet-endbr-exe -cet-stderr -cet-abort -- ./zstd -b3 - pkg-config: runs-on: ubuntu-latest container: image: debian:testing steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: Install dependencies run: | apt -y update @@ -522,7 +553,7 @@ jobs: versions-compatibility: runs-on: ubuntu-latest steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: Versions Compatibility Test run: | make -C tests versionsTest @@ -530,7 +561,7 @@ jobs: clangbuild: runs-on: ubuntu-latest steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: make clangbuild run: | make clangbuild @@ -538,7 +569,7 @@ jobs: clang-pgo: runs-on: ubuntu-latest steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: Build PGO Zstd with Clang env: CC: clang-14 @@ -550,7 +581,7 @@ jobs: gcc-pgo: runs-on: ubuntu-latest steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 - name: Build PGO Zstd with GCC env: CC: gcc @@ -558,10 +589,29 @@ jobs: make -C programs zstd-pgo ./programs/zstd -b + intel-cet-compatibility: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 + - name: Build Zstd + run: | + make -j zstd V=1 + readelf -n zstd + - name: Get Intel SDE + run: | + curl -LO https://downloadmirror.intel.com/813591/sde-external-9.33.0-2024-01-07-lin.tar.xz + tar xJvf sde-external-9.33.0-2024-01-07-lin.tar.xz + - name: Configure Permissions + run: | + echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope + - name: Run Under SDE + run: | + sde-external-9.33.0-2024-01-07-lin/sde -cet -cet-raise 0 -cet-endbr-exe -cet-stderr -cet-abort -- ./zstd -b3 + + +# Failing tests, for reference -# For reference : icc tests # icc tests are currently failing on Github Actions, likely to issues during installation stage -# To be fixed later # # icc: # name: icc-check @@ -577,7 +627,7 @@ jobs: # sudo add-apt-repository "deb https://apt.repos.intel.com/oneapi all main" # sudo apt-get update # sudo apt-get install -y intel-basekit intel-hpckit -# - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 +# - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1 # - name: make check # run: | # make CC=/opt/intel/oneapi/compiler/latest/linux/bin/intel64/icc check diff --git a/src/dependencies/zstd-1.5.6/.github/workflows/nightly.yml b/src/dependencies/zstd-1.5.6/.github/workflows/nightly.yml new file mode 100644 index 0000000..704e789 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/.github/workflows/nightly.yml @@ -0,0 +1,65 @@ +name: facebook/zstd/nightly +on: + schedule: + - cron: 0 0 * * * + push: + branches: + - release + - dev + - master +permissions: read-all +jobs: + regression-test: + runs-on: ubuntu-latest + services: + docker: + image: fbopensource/zstd-circleci-primary:0.0.1 + options: --entrypoint /bin/bash + env: + CIRCLE_ARTIFACTS: "/tmp/circleci-artifacts" + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + key: regression-cache-{{ checksum "tests/regression/data.c" }}-v0 + path: tests/regression/cache + restore-keys: regression-cache-{{ checksum "tests/regression/data.c" }}-v0 + - uses: actions/upload-artifact@v4 + with: + path: "/tmp/circleci-artifacts" + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install libcurl4-gnutls-dev + - name: Regression Test + run: | + make -C programs zstd + make -C tests/regression test + mkdir -p $CIRCLE_ARTIFACTS + ./tests/regression/test \ + --cache tests/regression/cache \ + --output $CIRCLE_ARTIFACTS/results.csv \ + --zstd programs/zstd + echo "NOTE: The new results.csv is uploaded as an artifact to this job" + echo " If this fails, go to the Artifacts pane in CircleCI, " + echo " download /tmp/circleci-artifacts/results.csv, and if they " + echo " are still good, copy it into the repo and commit it." + echo "> diff tests/regression/results.csv $CIRCLE_ARTIFACTS/results.csv" + diff tests/regression/results.csv $CIRCLE_ARTIFACTS/results.csv + +# Longer tests + #- make -C tests test-zstd-nolegacy && make clean + #- pyenv global 3.4.4; make -C tests versionsTest && make clean + #- make zlibwrapper && make clean + #- gcc -v; make -C tests test32 MOREFLAGS="-I/usr/include/x86_64-linux-gnu" && make clean + #- make uasan && make clean + #- make asan32 && make clean + #- make -C tests test32 CC=clang MOREFLAGS="-g -fsanitize=address -I/usr/include/x86_64-linux-gnu" +# Valgrind tests + #- CFLAGS="-O1 -g" make -C zlibWrapper valgrindTest && make clean + #- make -C tests valgrindTest && make clean +# ARM, AArch64, PowerPC, PowerPC64 tests + #- make ppctest && make clean + #- make ppc64test && make clean + #- make armtest && make clean + #- make aarch64test && make clean diff --git a/src/dependencies/zstd-1.5.4/.github/workflows/publish-release-artifacts.yml b/src/dependencies/zstd-1.5.6/.github/workflows/publish-release-artifacts.yml similarity index 88% rename from src/dependencies/zstd-1.5.4/.github/workflows/publish-release-artifacts.yml rename to src/dependencies/zstd-1.5.6/.github/workflows/publish-release-artifacts.yml index 2c89a91..f7af279 100644 --- a/src/dependencies/zstd-1.5.4/.github/workflows/publish-release-artifacts.yml +++ b/src/dependencies/zstd-1.5.6/.github/workflows/publish-release-artifacts.yml @@ -5,21 +5,19 @@ on: types: - published -permissions: - contents: read +permissions: read-all jobs: publish-release-artifacts: permissions: - contents: read # to fetch code (actions/checkout) - actions: write # to attach binaries to release artifacts (skx/github-action-publish-binaries) + contents: write # to fetch code and upload artifacts runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/') steps: - name: Checkout - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v3 - name: Archive env: @@ -68,7 +66,7 @@ jobs: fi - name: Publish - uses: skx/github-action-publish-binaries@release-2.0 + uses: skx/github-action-publish-binaries@b9ca5643b2f1d7371a6cba7f35333f1461bbc703 # tag=release-2.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/src/dependencies/zstd-1.5.4/.github/workflows/scorecards.yml b/src/dependencies/zstd-1.5.6/.github/workflows/scorecards.yml similarity index 85% rename from src/dependencies/zstd-1.5.4/.github/workflows/scorecards.yml rename to src/dependencies/zstd-1.5.6/.github/workflows/scorecards.yml index 6a9e521..a5d5f02 100644 --- a/src/dependencies/zstd-1.5.4/.github/workflows/scorecards.yml +++ b/src/dependencies/zstd-1.5.6/.github/workflows/scorecards.yml @@ -27,12 +27,12 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # tag=v3 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v3 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86 # tag=v2.1.2 + uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # tag=v2.3.1 with: results_file: results.sarif results_format: sarif @@ -51,7 +51,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # tag=v3.1.2 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # tag=v4.3.1 with: name: SARIF file path: results.sarif @@ -59,6 +59,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@3ebbd71c74ef574dbc558c82f70e52732c8b44fe # tag=v2.2.1 + uses: github/codeql-action/upload-sarif@3ab4101902695724f9365a384f86c1074d94e18c # tag=v3.24.7 with: sarif_file: results.sarif diff --git a/src/dependencies/zstd-1.5.6/.github/workflows/windows-artifacts.yml b/src/dependencies/zstd-1.5.6/.github/workflows/windows-artifacts.yml new file mode 100644 index 0000000..52bc90a --- /dev/null +++ b/src/dependencies/zstd-1.5.6/.github/workflows/windows-artifacts.yml @@ -0,0 +1,58 @@ +name: windows-artifacts + +on: + push: + branches: [ test_artifacts, win_artifacts ] + release: + types: + - published + +permissions: read-all + +jobs: + windows-artifacts: + # see https://ariya.io/2020/07/on-github-actions-with-msys2 + runs-on: windows-latest + # see https://github.com/msys2/setup-msys2 + strategy: + matrix: + include: + - { msystem: mingw64, env: x86_64, ziparch: win64 } + - { msystem: mingw32, env: i686, ziparch: win32 } + defaults: + run: + shell: msys2 {0} + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v3 + - uses: msys2/setup-msys2@5beef6d11f48bba68b9eb503e3adc60b23c0cc36 # tag=v2 + with: + msystem: ${{ matrix.msystem }} + install: make zlib git p7zip mingw-w64-${{matrix.env}}-gcc + update: true + + - name: display versions + run: | + make -v + cc -v + + - name: Building zlib to static link + run: | + git clone --depth 1 --branch v1.2.11 https://github.com/madler/zlib + make -C zlib -f win32/Makefile.gcc libz.a + + - name: Building zstd programs + run: | + CPPFLAGS=-I../zlib LDFLAGS=../zlib/libz.a make -j allzstd MOREFLAGS=-static V=1 + + - name: Create artifacts + run: | + ./lib/dll/example/build_package.bat + mv bin/ zstd-${{ github.ref_name }}-${{matrix.ziparch}}/ + 7z a -tzip -mx9 zstd-${{ github.ref_name }}-${{matrix.ziparch}}.zip zstd-${{ github.ref_name }}-${{matrix.ziparch}}/ + cd .. + + - name: Publish zstd-$VERSION-${{matrix.ziparch}}.zip + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # tag=v4.3.1 + with: + path: ${{ github.workspace }}/zstd-${{ github.ref_name }}-${{matrix.ziparch}}.zip + name: zstd-${{ github.ref_name }}-${{matrix.ziparch}}.zip diff --git a/src/dependencies/zstd-1.5.4/.gitignore b/src/dependencies/zstd-1.5.6/.gitignore similarity index 89% rename from src/dependencies/zstd-1.5.4/.gitignore rename to src/dependencies/zstd-1.5.6/.gitignore index a136ea3..34e18b4 100644 --- a/src/dependencies/zstd-1.5.4/.gitignore +++ b/src/dependencies/zstd-1.5.6/.gitignore @@ -27,6 +27,8 @@ tmp* dictionary. dictionary NUL +cmakebuild/ +install/ # Build artefacts contrib/linux-kernel/linux/ @@ -37,11 +39,15 @@ buck-out/ build-* *.gcda +# IDE +.clang_complete +compile_flags.txt +.clang-format + # Other files .directory _codelite/ _zstdbench/ -.clang_complete *.idea *.swp .DS_Store diff --git a/src/dependencies/zstd-1.5.4/CHANGELOG b/src/dependencies/zstd-1.5.6/CHANGELOG similarity index 92% rename from src/dependencies/zstd-1.5.4/CHANGELOG rename to src/dependencies/zstd-1.5.6/CHANGELOG index 4010c1f..33f4341 100644 --- a/src/dependencies/zstd-1.5.4/CHANGELOG +++ b/src/dependencies/zstd-1.5.6/CHANGELOG @@ -1,3 +1,59 @@ +V1.5.6 (Mar 2024) +api: Promote `ZSTD_c_targetCBlockSize` to Stable API by @felixhandte +api: new `ZSTD_d_maxBlockSize` experimental parameter, to reduce streaming decompression memory, by @terrelln +perf: improve performance of param `ZSTD_c_targetCBlockSize`, by @Cyan4973 +perf: improved compression of arrays of integers at high compression, by @Cyan4973 +lib: reduce binary size with selective built-time exclusion, by @felixhandte +lib: improved huffman speed on small data and linux kernel, by @terrelln +lib: accept dictionaries with partial literal tables, by @terrelln +lib: fix CCtx size estimation with external sequence producer, by @embg +lib: fix corner case decoder behaviors, by @Cyan4973 and @aimuz +lib: fix zdict prototype mismatch in static_only mode, by @ldv-alt +lib: fix several bugs in magicless-format decoding, by @embg +cli: add common compressed file types to `--exclude-compressed`` by @daniellerozenblit +cli: fix mixing `-c` and `-o` commands with `--rm`, by @Cyan4973 +cli: fix erroneous exclusion of hidden files with `--output-dir-mirror` by @felixhandte +cli: improved time accuracy on BSD, by @felixhandte +cli: better errors on argument parsing, by @KapJI +tests: better compatibility with older versions of `grep`, by @Cyan4973 +tests: lorem ipsum generator as default backup content, by @Cyan4973 +build: cmake improvements by @terrelln, @sighingnow, @gjasny, @JohanMabille, @Saverio976, @gruenich, @teo-tsirpanis +build: bazel support, by @jondo2010 +build: fix cross-compiling for AArch64 with lld by @jcelerier +build: fix Apple platform compatibility, by @nidhijaju +build: fix Visual 2012 and lower compatibility, by @Cyan4973 +build: improve win32 support, by @DimitriPapadopoulos +build: better C90 compliance for zlibWrapper, by @emaste +port: make: fat binaries on macos, by @mredig +port: ARM64EC compatibility for Windows, by @dunhor +port: QNX support by @klausholstjacobsen +port: MSYS2 and Cygwin makefile installation and test support, by @QBos07 +port: risc-v support validation in CI, by @Cyan4973 +port: sparc64 support validation in CI, by @Cyan4973 +port: AIX compatibility, by @likema +port: HP-UX compatibility, by @likema +doc: Improved specification accuracy, by @elasota +bug: Fix and deprecate ZSTD_generateSequences (#3981) + +v1.5.5 (Apr 2023) +fix: fix rare corruption bug affecting the high compression mode, reported by @danlark1 (#3517, @terrelln) +perf: improve mid-level compression speed (#3529, #3533, #3543, @yoniko and #3552, @terrelln) +lib: deprecated bufferless block-level API (#3534) by @terrelln +cli: mmap large dictionaries to save memory, by @daniellerozenblit +cli: improve speed of --patch-from mode (~+50%) (#3545) by @daniellerozenblit +cli: improve i/o speed (~+10%) when processing lots of small files (#3479) by @felixhandte +cli: zstd no longer crashes when requested to write into write-protected directory (#3541) by @felixhandte +cli: fix decompression into block device using -o, reported by @georgmu (#3583) +build: fix zstd CLI compiled with lzma support but not zlib support (#3494) by @Hello71 +build: fix cmake does no longer require 3.18 as minimum version (#3510) by @kou +build: fix MSVC+ClangCL linking issue (#3569) by @tru +build: fix zstd-dll, version of zstd CLI that links to the dynamic library (#3496) by @yoniko +build: fix MSVC warnings (#3495) by @embg +doc: updated zstd specification to clarify corner cases, by @Cyan4973 +doc: document how to create fat binaries for macos (#3568) by @rickmark +misc: improve seekable format ingestion speed (~+100%) for very small chunk sizes (#3544) by @Cyan4973 +misc: tests/fullbench can benchmark multiple files (#3516) by @dloidolt + v1.5.4 (Feb 2023) perf: +20% faster huffman decompression for targets that can't compile x64 assembly (#3449, @terrelln) perf: up to +10% faster streaming compression at levels 1-2 (#3114, @embg) @@ -79,7 +135,7 @@ build: support for m68k (Motorola 68000's), by @cyan4973 build: improved AIX support, by @Helflym build: improved meson unofficial build, by @eli-schwartz cli : custom memory limit when training dictionary (#2925), by @embg -cli : report advanced parameters information when compressing in very verbose mode (``-vv`), by @Svetlitski-FB +cli : report advanced parameters information when compressing in very verbose mode (`-vv`), by @Svetlitski-FB v1.5.0 (May 11, 2021) api: Various functions promoted from experimental to stable API: (#2579-2581, @senhuang42) @@ -146,7 +202,7 @@ api: Add Function to Generate Skippable Frame (#2439, @senhuang42) perf: New Algorithms for the Long Distance Matcher (#2483, @mpu) perf: Performance Improvements for Long Distance Matcher (#2464, @mpu) perf: Don't Shrink Window Log when Streaming with a Dictionary (#2451, @terrelln) -cli: Fix `--output-dir-mirror`'s Rejection of `..`-Containing Paths (#2512, @felixhandte) +cli: Fix `--output-dir-mirror` rejection of `..` -containing paths (#2512, @felixhandte) cli: Allow Input From Console When `-f`/`--force` is Passed (#2466, @felixhandte) cli: Improve Help Message (#2500, @senhuang42) tests: Remove Flaky Tests (#2455, #2486, #2445, @Cyan4973) diff --git a/src/dependencies/zstd-1.5.4/CODE_OF_CONDUCT.md b/src/dependencies/zstd-1.5.6/CODE_OF_CONDUCT.md similarity index 100% rename from src/dependencies/zstd-1.5.4/CODE_OF_CONDUCT.md rename to src/dependencies/zstd-1.5.6/CODE_OF_CONDUCT.md diff --git a/src/dependencies/zstd-1.5.4/CONTRIBUTING.md b/src/dependencies/zstd-1.5.6/CONTRIBUTING.md similarity index 99% rename from src/dependencies/zstd-1.5.4/CONTRIBUTING.md rename to src/dependencies/zstd-1.5.6/CONTRIBUTING.md index f5e747a..47f5bb8 100644 --- a/src/dependencies/zstd-1.5.4/CONTRIBUTING.md +++ b/src/dependencies/zstd-1.5.6/CONTRIBUTING.md @@ -171,8 +171,8 @@ who want earlier signal. | Cirrus CI | Used for testing on FreeBSD | https://github.com/marketplace/cirrus-ci/ | `.cirrus.yml` | | Circle CI | Historically was used to provide faster signal,
but we may be able to migrate these to Github Actions | https://circleci.com/docs/2.0/getting-started/#setting-up-circleci
https://youtu.be/Js3hMUsSZ2c
https://circleci.com/docs/2.0/enable-checks/ | `.circleci/config.yml` | -Note: the instructions linked above mostly cover how to set up a repository with CI from scratch. -The general idea should be the same for setting up CI on your fork of zstd, but you may have to +Note: the instructions linked above mostly cover how to set up a repository with CI from scratch. +The general idea should be the same for setting up CI on your fork of zstd, but you may have to follow slightly different steps. In particular, please ignore any instructions related to setting up config files (since zstd already has configs for each of these services). @@ -216,7 +216,7 @@ will typically not be stable enough to obtain reliable benchmark results. If you hands on a desktop, this is usually a better scenario. Of course, benchmarking can be done on non-hyper-stable machines as well. You will just have to -do a little more work to ensure that you are in fact measuring the changes you've made not and +do a little more work to ensure that you are in fact measuring the changes you've made and not noise. Here are some things you can do to make your benchmarks more stable: 1. The most simple thing you can do to drastically improve the stability of your benchmark is diff --git a/src/dependencies/zstd-1.5.4/COPYING b/src/dependencies/zstd-1.5.6/COPYING similarity index 100% rename from src/dependencies/zstd-1.5.4/COPYING rename to src/dependencies/zstd-1.5.6/COPYING diff --git a/src/dependencies/zstd-1.5.4/LICENSE b/src/dependencies/zstd-1.5.6/LICENSE similarity index 100% rename from src/dependencies/zstd-1.5.4/LICENSE rename to src/dependencies/zstd-1.5.6/LICENSE diff --git a/src/dependencies/zstd-1.5.4/Makefile b/src/dependencies/zstd-1.5.6/Makefile similarity index 79% rename from src/dependencies/zstd-1.5.4/Makefile rename to src/dependencies/zstd-1.5.6/Makefile index a7890a5..11eca19 100644 --- a/src/dependencies/zstd-1.5.4/Makefile +++ b/src/dependencies/zstd-1.5.6/Makefile @@ -145,13 +145,13 @@ clean: $(Q)$(MAKE) -C contrib/largeNbDicts $@ > $(VOID) $(Q)$(MAKE) -C contrib/externalSequenceProducer $@ > $(VOID) $(Q)$(RM) zstd$(EXT) zstdmt$(EXT) tmp* - $(Q)$(RM) -r lz4 + $(Q)$(RM) -r lz4 cmakebuild install @echo Cleaning completed #------------------------------------------------------------------------------ # make install is validated only for Linux, macOS, Hurd and some BSD targets #------------------------------------------------------------------------------ -ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD DragonFly NetBSD MSYS_NT Haiku AIX)) +ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD DragonFly NetBSD MSYS_NT CYGWIN_NT Haiku AIX)) HOST_OS = POSIX @@ -197,18 +197,27 @@ uninstall: travis-install: $(MAKE) install PREFIX=~/install_test_dir +.PHONY: clangbuild-darwin-fat +clangbuild-darwin-fat: clean + clang -v + CXX=clang++ CC=clang CFLAGS="-Werror -Wconversion -Wno-sign-conversion -Wdocumentation -arch arm64" $(MAKE) zstd-release + mv programs/zstd programs/zstd_arm64 + CXX=clang++ CC=clang CFLAGS="-Werror -Wconversion -Wno-sign-conversion -Wdocumentation -arch x86_64" $(MAKE) zstd-release + mv programs/zstd programs/zstd_x64 + lipo -create programs/zstd_x64 programs/zstd_arm64 -output programs/zstd + .PHONY: gcc5build gcc6build gcc7build clangbuild m32build armbuild aarch64build ppcbuild ppc64build gcc5build: clean gcc-5 -v - CC=gcc-5 $(MAKE) all MOREFLAGS="-Werror" + CC=gcc-5 $(MAKE) all MOREFLAGS="-Werror $(MOREFLAGS)" gcc6build: clean gcc-6 -v - CC=gcc-6 $(MAKE) all MOREFLAGS="-Werror" + CC=gcc-6 $(MAKE) all MOREFLAGS="-Werror $(MOREFLAGS)" gcc7build: clean gcc-7 -v - CC=gcc-7 $(MAKE) all MOREFLAGS="-Werror" + CC=gcc-7 $(MAKE) all MOREFLAGS="-Werror $(MOREFLAGS)" clangbuild: clean clang -v @@ -232,17 +241,17 @@ ppc64build: clean .PHONY: armfuzz aarch64fuzz ppcfuzz ppc64fuzz armfuzz: clean - CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static MOREFLAGS="-static" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) fuzztest + CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static MOREFLAGS="-static $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" $(MAKE) -C $(TESTDIR) fuzztest aarch64fuzz: clean ld -v - CC=aarch64-linux-gnu-gcc QEMU_SYS=qemu-aarch64-static MOREFLAGS="-static" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) fuzztest + CC=aarch64-linux-gnu-gcc QEMU_SYS=qemu-aarch64-static MOREFLAGS="-static $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" $(MAKE) -C $(TESTDIR) fuzztest ppcfuzz: clean - CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc-static MOREFLAGS="-static" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) fuzztest + CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc-static MOREFLAGS="-static $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" $(MAKE) -C $(TESTDIR) fuzztest ppc64fuzz: clean - CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc64-static MOREFLAGS="-m64 -static" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) fuzztest + CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc64-static MOREFLAGS="-m64 -static $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" $(MAKE) -C $(TESTDIR) fuzztest .PHONY: cxxtest gcc5test gcc6test armtest aarch64test ppctest ppc64test cxxtest: CXXFLAGS += -Wall -Wextra -Wundef -Wshadow -Wcast-align -Werror @@ -251,34 +260,34 @@ cxxtest: clean gcc5test: clean gcc-5 -v - $(MAKE) all CC=gcc-5 MOREFLAGS="-Werror" + $(MAKE) all CC=gcc-5 MOREFLAGS="-Werror $(MOREFLAGS)" gcc6test: clean gcc-6 -v - $(MAKE) all CC=gcc-6 MOREFLAGS="-Werror" + $(MAKE) all CC=gcc-6 MOREFLAGS="-Werror $(MOREFLAGS)" armtest: clean $(MAKE) -C $(TESTDIR) datagen # use native, faster - $(MAKE) -C $(TESTDIR) test CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static ZSTDRTTEST= MOREFLAGS="-Werror -static" FUZZER_FLAGS=--no-big-tests + $(MAKE) -C $(TESTDIR) test CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static ZSTDRTTEST= MOREFLAGS="-Werror -static $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" aarch64test: $(MAKE) -C $(TESTDIR) datagen # use native, faster - $(MAKE) -C $(TESTDIR) test CC=aarch64-linux-gnu-gcc QEMU_SYS=qemu-aarch64-static ZSTDRTTEST= MOREFLAGS="-Werror -static" FUZZER_FLAGS=--no-big-tests + $(MAKE) -C $(TESTDIR) test CC=aarch64-linux-gnu-gcc QEMU_SYS=qemu-aarch64-static ZSTDRTTEST= MOREFLAGS="-Werror -static $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" ppctest: clean $(MAKE) -C $(TESTDIR) datagen # use native, faster - $(MAKE) -C $(TESTDIR) test CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc-static ZSTDRTTEST= MOREFLAGS="-Werror -Wno-attributes -static" FUZZER_FLAGS=--no-big-tests + $(MAKE) -C $(TESTDIR) test CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc-static ZSTDRTTEST= MOREFLAGS="-Werror -Wno-attributes -static $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" ppc64test: clean $(MAKE) -C $(TESTDIR) datagen # use native, faster - $(MAKE) -C $(TESTDIR) test CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc64-static ZSTDRTTEST= MOREFLAGS="-m64 -static" FUZZER_FLAGS=--no-big-tests + $(MAKE) -C $(TESTDIR) test CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc64-static ZSTDRTTEST= MOREFLAGS="-m64 -static $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" .PHONY: arm-ppc-compilation arm-ppc-compilation: - $(MAKE) -C $(PRGDIR) clean zstd CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static ZSTDRTTEST= MOREFLAGS="-Werror -static" - $(MAKE) -C $(PRGDIR) clean zstd CC=aarch64-linux-gnu-gcc QEMU_SYS=qemu-aarch64-static ZSTDRTTEST= MOREFLAGS="-Werror -static" - $(MAKE) -C $(PRGDIR) clean zstd CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc-static ZSTDRTTEST= MOREFLAGS="-Werror -Wno-attributes -static" - $(MAKE) -C $(PRGDIR) clean zstd CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc64-static ZSTDRTTEST= MOREFLAGS="-m64 -static" + $(MAKE) -C $(PRGDIR) clean zstd CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static ZSTDRTTEST= MOREFLAGS="-Werror -static $(MOREFLAGS)" + $(MAKE) -C $(PRGDIR) clean zstd CC=aarch64-linux-gnu-gcc QEMU_SYS=qemu-aarch64-static ZSTDRTTEST= MOREFLAGS="-Werror -static $(MOREFLAGS)" + $(MAKE) -C $(PRGDIR) clean zstd CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc-static ZSTDRTTEST= MOREFLAGS="-Werror -Wno-attributes -static $(MOREFLAGS)" + $(MAKE) -C $(PRGDIR) clean zstd CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc64-static ZSTDRTTEST= MOREFLAGS="-m64 -static $(MOREFLAGS)" regressiontest: $(MAKE) -C $(FUZZDIR) regressiontest @@ -308,31 +317,32 @@ update_regressionResults: # run UBsan with -fsanitize-recover=pointer-overflow # this only works with recent compilers such as gcc 8+ usan: clean - $(MAKE) test CC=clang MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize-recover=pointer-overflow -fsanitize=undefined -Werror" + $(MAKE) test CC=clang MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=undefined -Werror $(MOREFLAGS)" asan: clean - $(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address -Werror" + $(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address -Werror $(MOREFLAGS)" asan-%: clean - LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=address -Werror" $(MAKE) -C $(TESTDIR) $* + LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=address -Werror $(MOREFLAGS)" $(MAKE) -C $(TESTDIR) $* msan: clean - $(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=memory -fno-omit-frame-pointer -Werror" HAVE_LZMA=0 # datagen.c fails this test for no obvious reason + $(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=memory -fno-omit-frame-pointer -Werror $(MOREFLAGS)" HAVE_LZMA=0 # datagen.c fails this test for no obvious reason -msan-%: clean - LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=memory -fno-omit-frame-pointer -Werror" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) HAVE_LZMA=0 $* +msan-%: + $(MAKE) clean + LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=memory -fno-omit-frame-pointer -Werror $(MOREFLAGS)" FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" $(MAKE) -j -C $(TESTDIR) HAVE_LZMA=0 $* asan32: clean - $(MAKE) -C $(TESTDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address" + $(MAKE) -C $(TESTDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address $(MOREFLAGS)" uasan: clean - $(MAKE) test CC=clang MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize-recover=pointer-overflow -fsanitize=address,undefined -Werror" + $(MAKE) test CC=clang MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=address,undefined -Werror $(MOREFLAGS)" uasan-%: clean - LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize-recover=pointer-overflow -fsanitize=address,undefined -Werror" $(MAKE) -C $(TESTDIR) $* + LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=address,undefined -Werror $(MOREFLAGS)" $(MAKE) -C $(TESTDIR) $* tsan-%: clean - LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=thread -Werror" $(MAKE) -C $(TESTDIR) $* FUZZER_FLAGS=--no-big-tests + LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=thread -Werror $(MOREFLAGS)" $(MAKE) -C $(TESTDIR) $* FUZZER_FLAGS="--no-big-tests $(FUZZER_FLAGS)" .PHONY: apt-install apt-install: @@ -380,28 +390,32 @@ lz4install: endif -CMAKE_PARAMS = -DZSTD_BUILD_CONTRIB:BOOL=ON -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON -DZSTD_ZLIB_SUPPORT:BOOL=ON -DZSTD_LZMA_SUPPORT:BOOL=ON -DCMAKE_BUILD_TYPE=Release - ifneq (,$(filter MSYS%,$(shell uname))) HOST_OS = MSYS -CMAKE_PARAMS = -G"MSYS Makefiles" -DCMAKE_BUILD_TYPE=Debug -DZSTD_MULTITHREAD_SUPPORT:BOOL=OFF -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON endif #------------------------------------------------------------------------ # target specific tests #------------------------------------------------------------------------ ifneq (,$(filter $(HOST_OS),MSYS POSIX)) -.PHONY: cmakebuild c89build gnu90build c99build gnu99build c11build bmix64build bmix32build bmi32build staticAnalyze -cmakebuild: - cmake --version - $(RM) -r $(BUILDIR)/cmake/build - $(MKDIR) $(BUILDIR)/cmake/build - cd $(BUILDIR)/cmake/build; cmake -DCMAKE_INSTALL_PREFIX:PATH=~/install_test_dir $(CMAKE_PARAMS) .. - $(MAKE) -C $(BUILDIR)/cmake/build -j4; - $(MAKE) -C $(BUILDIR)/cmake/build install; - $(MAKE) -C $(BUILDIR)/cmake/build uninstall; - cd $(BUILDIR)/cmake/build; ctest -V -L Medium +CMAKE ?= cmake +CMAKE_PARAMS = -DZSTD_BUILD_CONTRIB:BOOL=ON -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON -DZSTD_ZLIB_SUPPORT:BOOL=ON -DZSTD_LZMA_SUPPORT:BOOL=ON + +ifneq (,$(filter MSYS%,$(shell uname))) +CMAKE_PARAMS = -G"MSYS Makefiles" -DZSTD_MULTITHREAD_SUPPORT:BOOL=OFF -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON +endif + +.PHONY: cmakebuild +cmakebuild: + $(CMAKE) --version + $(RM) -r cmakebuild install + $(MKDIR) cmakebuild install + cd cmakebuild; $(CMAKE) -Wdev -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS="-Werror -O0" -DCMAKE_INSTALL_PREFIX=install $(CMAKE_PARAMS) ../build/cmake + $(CMAKE) --build cmakebuild --target install -- -j V=1 + cd cmakebuild; ctest -V -L Medium + +.PHONY: c89build gnu90build c99build gnu99build c11build bmix64build bmix32build bmi32build staticAnalyze c89build: clean $(CC) -v CFLAGS="-std=c89 -Werror -Wno-attributes -Wpedantic -Wno-long-long -Wno-variadic-macros -O0" $(MAKE) lib zstd diff --git a/src/dependencies/zstd-1.5.4/Package.swift b/src/dependencies/zstd-1.5.6/Package.swift similarity index 100% rename from src/dependencies/zstd-1.5.4/Package.swift rename to src/dependencies/zstd-1.5.6/Package.swift diff --git a/src/dependencies/zstd-1.5.4/README.md b/src/dependencies/zstd-1.5.6/README.md similarity index 93% rename from src/dependencies/zstd-1.5.4/README.md rename to src/dependencies/zstd-1.5.6/README.md index 6bcf757..0f7478e 100644 --- a/src/dependencies/zstd-1.5.4/README.md +++ b/src/dependencies/zstd-1.5.6/README.md @@ -5,7 +5,7 @@ targeting real-time compression scenarios at zlib-level and better compression r It's backed by a very fast entropy stage, provided by [Huff0 and FSE library](https://github.com/Cyan4973/FiniteStateEntropy). Zstandard's format is stable and documented in [RFC8878](https://datatracker.ietf.org/doc/html/rfc8878). Multiple independent implementations are already available. -This repository represents the reference implementation, provided as an open-source dual [BSD](LICENSE) and [GPLv2](COPYING) licensed **C** library, +This repository represents the reference implementation, provided as an open-source dual [BSD](LICENSE) OR [GPLv2](COPYING) licensed **C** library, and a command line utility producing and decoding `.zst`, `.gz`, `.xz` and `.lz4` files. Should your project require another programming language, a list of known ports and bindings is provided on [Zstandard homepage](https://facebook.github.io/zstd/#other-languages). @@ -13,15 +13,12 @@ a list of known ports and bindings is provided on [Zstandard homepage](https://f **Development branch status:** [![Build Status][travisDevBadge]][travisLink] -[![Build status][AppveyorDevBadge]][AppveyorLink] [![Build status][CircleDevBadge]][CircleLink] [![Build status][CirrusDevBadge]][CirrusLink] [![Fuzzing Status][OSSFuzzBadge]][OSSFuzzLink] [travisDevBadge]: https://api.travis-ci.com/facebook/zstd.svg?branch=dev "Continuous Integration test suite" [travisLink]: https://travis-ci.com/facebook/zstd -[AppveyorDevBadge]: https://ci.appveyor.com/api/projects/status/xt38wbdxjk5mrbem/branch/dev?svg=true "Windows test suite" -[AppveyorLink]: https://ci.appveyor.com/project/YannCollet/zstd-p0yf0 [CircleDevBadge]: https://circleci.com/gh/facebook/zstd/tree/dev.svg?style=shield "Short test suite" [CircleLink]: https://circleci.com/gh/facebook/zstd [CirrusDevBadge]: https://api.cirrus-ci.com/github/facebook/zstd.svg?branch=dev @@ -154,6 +151,18 @@ to create `zstd` binary, and `libzstd` dynamic and static libraries. By default, `CMAKE_BUILD_TYPE` is set to `Release`. +#### Support for Fat (Universal2) Output + +`zstd` can be built and installed with support for both Apple Silicon (M1/M2) as well as Intel by using CMake's Universal2 support. +To perform a Fat/Universal2 build and install use the following commands: + +```bash +cmake -B build-cmake-debug -S build/cmake -G Ninja -DCMAKE_OSX_ARCHITECTURES="x86_64;x86_64h;arm64" +cd build-cmake-debug +ninja +sudo ninja install +``` + ### Meson A Meson project is provided within [`build/meson`](build/meson). Follow @@ -189,6 +198,10 @@ Going into `build` directory, you will find additional possibilities: You can build the zstd binary via buck by executing: `buck build programs:zstd` from the root of the repo. The output binary will be in `buck-out/gen/programs/`. +### Bazel + +You easily can integrate zstd into your Bazel project by using the module hosted on the [Bazel Central Repository](https://registry.bazel.build/modules/zstd). + ## Testing You can run quick local smoke tests by running `make check`. @@ -204,7 +217,7 @@ Zstandard is considered safe for production environments. ## License -Zstandard is dual-licensed under [BSD](LICENSE) and [GPLv2](COPYING). +Zstandard is dual-licensed under [BSD](LICENSE) OR [GPLv2](COPYING). ## Contributing diff --git a/src/dependencies/zstd-1.5.6/SECURITY.md b/src/dependencies/zstd-1.5.6/SECURITY.md new file mode 100644 index 0000000..a5f9a7e --- /dev/null +++ b/src/dependencies/zstd-1.5.6/SECURITY.md @@ -0,0 +1,15 @@ +# Reporting and Fixing Security Issues + +Please do not open GitHub issues or pull requests - this makes the problem immediately visible to everyone, including malicious actors. Security issues in this open source project can be safely reported via the Meta Bug Bounty program: + +https://www.facebook.com/whitehat + +Meta's security team will triage your report and determine whether or not is it eligible for a bounty under our program. + +# Receiving Vulnerability Notifications + +In the case that a significant security vulnerability is reported to us or discovered by us---without being publicly known---we will, at our discretion, notify high-profile, high-exposure users of Zstandard ahead of our public disclosure of the issue and associated fix. + +If you believe your project would benefit from inclusion in this list, please reach out to one of the maintainers. + + diff --git a/src/dependencies/zstd-1.5.4/TESTING.md b/src/dependencies/zstd-1.5.6/TESTING.md similarity index 100% rename from src/dependencies/zstd-1.5.4/TESTING.md rename to src/dependencies/zstd-1.5.6/TESTING.md diff --git a/src/dependencies/zstd-1.5.4/contrib/VS2005/README.md b/src/dependencies/zstd-1.5.6/contrib/VS2005/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/VS2005/README.md rename to src/dependencies/zstd-1.5.6/contrib/VS2005/README.md diff --git a/src/dependencies/zstd-1.5.4/contrib/VS2005/fullbench/fullbench.vcproj b/src/dependencies/zstd-1.5.6/contrib/VS2005/fullbench/fullbench.vcproj similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/VS2005/fullbench/fullbench.vcproj rename to src/dependencies/zstd-1.5.6/contrib/VS2005/fullbench/fullbench.vcproj diff --git a/src/dependencies/zstd-1.5.4/contrib/VS2005/fuzzer/fuzzer.vcproj b/src/dependencies/zstd-1.5.6/contrib/VS2005/fuzzer/fuzzer.vcproj similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/VS2005/fuzzer/fuzzer.vcproj rename to src/dependencies/zstd-1.5.6/contrib/VS2005/fuzzer/fuzzer.vcproj diff --git a/src/dependencies/zstd-1.5.4/contrib/VS2005/zstd.sln b/src/dependencies/zstd-1.5.6/contrib/VS2005/zstd.sln similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/VS2005/zstd.sln rename to src/dependencies/zstd-1.5.6/contrib/VS2005/zstd.sln diff --git a/src/dependencies/zstd-1.5.4/contrib/VS2005/zstd/zstd.vcproj b/src/dependencies/zstd-1.5.6/contrib/VS2005/zstd/zstd.vcproj similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/VS2005/zstd/zstd.vcproj rename to src/dependencies/zstd-1.5.6/contrib/VS2005/zstd/zstd.vcproj diff --git a/src/dependencies/zstd-1.5.4/contrib/VS2005/zstdlib/zstdlib.vcproj b/src/dependencies/zstd-1.5.6/contrib/VS2005/zstdlib/zstdlib.vcproj similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/VS2005/zstdlib/zstdlib.vcproj rename to src/dependencies/zstd-1.5.6/contrib/VS2005/zstdlib/zstdlib.vcproj diff --git a/src/dependencies/zstd-1.5.4/contrib/cleanTabs b/src/dependencies/zstd-1.5.6/contrib/cleanTabs similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/cleanTabs rename to src/dependencies/zstd-1.5.6/contrib/cleanTabs diff --git a/src/dependencies/zstd-1.5.4/contrib/diagnose_corruption/.gitignore b/src/dependencies/zstd-1.5.6/contrib/diagnose_corruption/.gitignore similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/diagnose_corruption/.gitignore rename to src/dependencies/zstd-1.5.6/contrib/diagnose_corruption/.gitignore diff --git a/src/dependencies/zstd-1.5.4/contrib/diagnose_corruption/Makefile b/src/dependencies/zstd-1.5.6/contrib/diagnose_corruption/Makefile similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/diagnose_corruption/Makefile rename to src/dependencies/zstd-1.5.6/contrib/diagnose_corruption/Makefile diff --git a/src/dependencies/zstd-1.5.4/contrib/diagnose_corruption/check_flipped_bits.c b/src/dependencies/zstd-1.5.6/contrib/diagnose_corruption/check_flipped_bits.c similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/diagnose_corruption/check_flipped_bits.c rename to src/dependencies/zstd-1.5.6/contrib/diagnose_corruption/check_flipped_bits.c diff --git a/src/dependencies/zstd-1.5.4/contrib/docker/Dockerfile b/src/dependencies/zstd-1.5.6/contrib/docker/Dockerfile similarity index 72% rename from src/dependencies/zstd-1.5.4/contrib/docker/Dockerfile rename to src/dependencies/zstd-1.5.6/contrib/docker/Dockerfile index e06a32c..912bf19 100644 --- a/src/dependencies/zstd-1.5.4/contrib/docker/Dockerfile +++ b/src/dependencies/zstd-1.5.6/contrib/docker/Dockerfile @@ -1,13 +1,13 @@ # Dockerfile # First image to build the binary -FROM alpine as builder +FROM alpine@sha256:69665d02cb32192e52e07644d76bc6f25abeb5410edc1c7a81a10ba3f0efb90a as builder RUN apk --no-cache add make gcc libc-dev COPY . /src RUN mkdir /pkg && cd /src && make && make DESTDIR=/pkg install # Second minimal image to only keep the built binary -FROM alpine +FROM alpine@sha256:69665d02cb32192e52e07644d76bc6f25abeb5410edc1c7a81a10ba3f0efb90a # Copy the built files COPY --from=builder /pkg / diff --git a/src/dependencies/zstd-1.5.4/contrib/docker/README.md b/src/dependencies/zstd-1.5.6/contrib/docker/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/docker/README.md rename to src/dependencies/zstd-1.5.6/contrib/docker/README.md diff --git a/src/dependencies/zstd-1.5.4/contrib/externalSequenceProducer/.gitignore b/src/dependencies/zstd-1.5.6/contrib/externalSequenceProducer/.gitignore similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/externalSequenceProducer/.gitignore rename to src/dependencies/zstd-1.5.6/contrib/externalSequenceProducer/.gitignore diff --git a/src/dependencies/zstd-1.5.4/contrib/externalSequenceProducer/Makefile b/src/dependencies/zstd-1.5.6/contrib/externalSequenceProducer/Makefile similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/externalSequenceProducer/Makefile rename to src/dependencies/zstd-1.5.6/contrib/externalSequenceProducer/Makefile diff --git a/src/dependencies/zstd-1.5.4/contrib/externalSequenceProducer/README.md b/src/dependencies/zstd-1.5.6/contrib/externalSequenceProducer/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/externalSequenceProducer/README.md rename to src/dependencies/zstd-1.5.6/contrib/externalSequenceProducer/README.md diff --git a/src/dependencies/zstd-1.5.4/contrib/externalSequenceProducer/main.c b/src/dependencies/zstd-1.5.6/contrib/externalSequenceProducer/main.c similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/externalSequenceProducer/main.c rename to src/dependencies/zstd-1.5.6/contrib/externalSequenceProducer/main.c diff --git a/src/dependencies/zstd-1.5.4/contrib/externalSequenceProducer/sequence_producer.c b/src/dependencies/zstd-1.5.6/contrib/externalSequenceProducer/sequence_producer.c similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/externalSequenceProducer/sequence_producer.c rename to src/dependencies/zstd-1.5.6/contrib/externalSequenceProducer/sequence_producer.c diff --git a/src/dependencies/zstd-1.5.4/contrib/externalSequenceProducer/sequence_producer.h b/src/dependencies/zstd-1.5.6/contrib/externalSequenceProducer/sequence_producer.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/externalSequenceProducer/sequence_producer.h rename to src/dependencies/zstd-1.5.6/contrib/externalSequenceProducer/sequence_producer.h diff --git a/src/dependencies/zstd-1.5.4/contrib/freestanding_lib/freestanding.py b/src/dependencies/zstd-1.5.6/contrib/freestanding_lib/freestanding.py similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/freestanding_lib/freestanding.py rename to src/dependencies/zstd-1.5.6/contrib/freestanding_lib/freestanding.py diff --git a/src/dependencies/zstd-1.5.4/contrib/gen_html/.gitignore b/src/dependencies/zstd-1.5.6/contrib/gen_html/.gitignore similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/gen_html/.gitignore rename to src/dependencies/zstd-1.5.6/contrib/gen_html/.gitignore diff --git a/src/dependencies/zstd-1.5.4/contrib/gen_html/Makefile b/src/dependencies/zstd-1.5.6/contrib/gen_html/Makefile similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/gen_html/Makefile rename to src/dependencies/zstd-1.5.6/contrib/gen_html/Makefile diff --git a/src/dependencies/zstd-1.5.4/contrib/gen_html/README.md b/src/dependencies/zstd-1.5.6/contrib/gen_html/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/gen_html/README.md rename to src/dependencies/zstd-1.5.6/contrib/gen_html/README.md diff --git a/src/dependencies/zstd-1.5.4/contrib/gen_html/gen-zstd-manual.sh b/src/dependencies/zstd-1.5.6/contrib/gen_html/gen-zstd-manual.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/gen_html/gen-zstd-manual.sh rename to src/dependencies/zstd-1.5.6/contrib/gen_html/gen-zstd-manual.sh diff --git a/src/dependencies/zstd-1.5.4/contrib/gen_html/gen_html.cpp b/src/dependencies/zstd-1.5.6/contrib/gen_html/gen_html.cpp similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/gen_html/gen_html.cpp rename to src/dependencies/zstd-1.5.6/contrib/gen_html/gen_html.cpp diff --git a/src/dependencies/zstd-1.5.4/contrib/largeNbDicts/.gitignore b/src/dependencies/zstd-1.5.6/contrib/largeNbDicts/.gitignore similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/largeNbDicts/.gitignore rename to src/dependencies/zstd-1.5.6/contrib/largeNbDicts/.gitignore diff --git a/src/dependencies/zstd-1.5.4/contrib/largeNbDicts/Makefile b/src/dependencies/zstd-1.5.6/contrib/largeNbDicts/Makefile similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/largeNbDicts/Makefile rename to src/dependencies/zstd-1.5.6/contrib/largeNbDicts/Makefile diff --git a/src/dependencies/zstd-1.5.4/contrib/largeNbDicts/README.md b/src/dependencies/zstd-1.5.6/contrib/largeNbDicts/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/largeNbDicts/README.md rename to src/dependencies/zstd-1.5.6/contrib/largeNbDicts/README.md diff --git a/src/dependencies/zstd-1.5.4/contrib/largeNbDicts/largeNbDicts.c b/src/dependencies/zstd-1.5.6/contrib/largeNbDicts/largeNbDicts.c similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/largeNbDicts/largeNbDicts.c rename to src/dependencies/zstd-1.5.6/contrib/largeNbDicts/largeNbDicts.c diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/.gitignore b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/.gitignore similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/.gitignore rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/.gitignore diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/Makefile b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/Makefile similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/Makefile rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/Makefile diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/README.md b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/README.md rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/README.md diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/btrfs-benchmark.sh b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/btrfs-benchmark.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/btrfs-benchmark.sh rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/btrfs-benchmark.sh diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/btrfs-extract-benchmark.sh b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/btrfs-extract-benchmark.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/btrfs-extract-benchmark.sh rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/btrfs-extract-benchmark.sh diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/decompress_sources.h b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/decompress_sources.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/decompress_sources.h rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/decompress_sources.h diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/linux.mk b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/linux.mk similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/linux.mk rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/linux.mk diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/linux_zstd.h b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/linux_zstd.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/linux_zstd.h rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/linux_zstd.h diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/mem.h b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/mem.h similarity index 98% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/mem.h rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/mem.h index a723182..2e91e77 100644 --- a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/mem.h +++ b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/mem.h @@ -24,6 +24,7 @@ /*-**************************************** * Compiler specifics ******************************************/ +#undef MEM_STATIC /* may be already defined from common/compiler.h */ #define MEM_STATIC static inline /*-************************************************************** diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/squashfs-benchmark.sh b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/squashfs-benchmark.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/squashfs-benchmark.sh rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/squashfs-benchmark.sh diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/Makefile b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/Makefile similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/Makefile rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/Makefile diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/asm/unaligned.h b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/asm/unaligned.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/asm/unaligned.h rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/asm/unaligned.h diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/compiler.h b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/compiler.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/compiler.h rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/compiler.h diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/errno.h b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/errno.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/errno.h rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/errno.h diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/kernel.h b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/kernel.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/kernel.h rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/kernel.h diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/limits.h b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/limits.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/limits.h rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/limits.h diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/math64.h b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/math64.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/math64.h rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/math64.h diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/module.h b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/module.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/module.h rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/module.h diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/printk.h b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/printk.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/printk.h rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/printk.h diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/stddef.h b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/stddef.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/stddef.h rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/stddef.h diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/swab.h b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/swab.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/swab.h rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/swab.h diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/types.h b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/types.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/types.h rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/types.h diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/xxhash.h b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/xxhash.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/include/linux/xxhash.h rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/include/linux/xxhash.h diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/macro-test.sh b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/macro-test.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/macro-test.sh rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/macro-test.sh diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/static_test.c b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/static_test.c similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/static_test.c rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/static_test.c diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/test.c b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/test.c similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/test/test.c rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/test/test.c diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/zstd_common_module.c b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/zstd_common_module.c similarity index 89% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/zstd_common_module.c rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/zstd_common_module.c index 2fead39..466828e 100644 --- a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/zstd_common_module.c +++ b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/zstd_common_module.c @@ -24,9 +24,6 @@ EXPORT_SYMBOL_GPL(HUF_readStats_wksp); EXPORT_SYMBOL_GPL(ZSTD_isError); EXPORT_SYMBOL_GPL(ZSTD_getErrorName); EXPORT_SYMBOL_GPL(ZSTD_getErrorCode); -EXPORT_SYMBOL_GPL(ZSTD_customMalloc); -EXPORT_SYMBOL_GPL(ZSTD_customCalloc); -EXPORT_SYMBOL_GPL(ZSTD_customFree); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("Zstd Common"); diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/zstd_compress_module.c b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/zstd_compress_module.c similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/zstd_compress_module.c rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/zstd_compress_module.c diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/zstd_decompress_module.c b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/zstd_decompress_module.c similarity index 97% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/zstd_decompress_module.c rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/zstd_decompress_module.c index eb1c49e..7d31518 100644 --- a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/zstd_decompress_module.c +++ b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/zstd_decompress_module.c @@ -77,7 +77,7 @@ EXPORT_SYMBOL(zstd_init_dstream); size_t zstd_reset_dstream(zstd_dstream *dstream) { - return ZSTD_resetDStream(dstream); + return ZSTD_DCtx_reset(dstream, ZSTD_reset_session_only); } EXPORT_SYMBOL(zstd_reset_dstream); diff --git a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/zstd_deps.h b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/zstd_deps.h similarity index 94% rename from src/dependencies/zstd-1.5.4/contrib/linux-kernel/zstd_deps.h rename to src/dependencies/zstd-1.5.6/contrib/linux-kernel/zstd_deps.h index 9251614..f931f7d 100644 --- a/src/dependencies/zstd-1.5.4/contrib/linux-kernel/zstd_deps.h +++ b/src/dependencies/zstd-1.5.6/contrib/linux-kernel/zstd_deps.h @@ -84,7 +84,7 @@ static uint64_t ZSTD_div64(uint64_t dividend, uint32_t divisor) { #include -#define assert(x) WARN_ON((x)) +#define assert(x) WARN_ON(!(x)) #endif /* ZSTD_DEPS_ASSERT */ #endif /* ZSTD_DEPS_NEED_ASSERT */ @@ -115,11 +115,7 @@ static uint64_t ZSTD_div64(uint64_t dividend, uint32_t divisor) { #ifndef ZSTD_DEPS_STDINT #define ZSTD_DEPS_STDINT -/* - * The Linux Kernel doesn't provide intptr_t, only uintptr_t, which - * is an unsigned long. - */ -typedef long intptr_t; +/* intptr_t already provided by ZSTD_DEPS_COMMON */ #endif /* ZSTD_DEPS_STDINT */ #endif /* ZSTD_DEPS_NEED_STDINT */ diff --git a/src/dependencies/zstd-1.5.4/contrib/match_finders/README.md b/src/dependencies/zstd-1.5.6/contrib/match_finders/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/match_finders/README.md rename to src/dependencies/zstd-1.5.6/contrib/match_finders/README.md diff --git a/src/dependencies/zstd-1.5.4/contrib/match_finders/zstd_edist.c b/src/dependencies/zstd-1.5.6/contrib/match_finders/zstd_edist.c similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/match_finders/zstd_edist.c rename to src/dependencies/zstd-1.5.6/contrib/match_finders/zstd_edist.c diff --git a/src/dependencies/zstd-1.5.4/contrib/match_finders/zstd_edist.h b/src/dependencies/zstd-1.5.6/contrib/match_finders/zstd_edist.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/match_finders/zstd_edist.h rename to src/dependencies/zstd-1.5.6/contrib/match_finders/zstd_edist.h diff --git a/src/dependencies/zstd-1.5.4/contrib/premake/premake4.lua b/src/dependencies/zstd-1.5.6/contrib/premake/premake4.lua similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/premake/premake4.lua rename to src/dependencies/zstd-1.5.6/contrib/premake/premake4.lua diff --git a/src/dependencies/zstd-1.5.4/contrib/premake/zstd.lua b/src/dependencies/zstd-1.5.6/contrib/premake/zstd.lua similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/premake/zstd.lua rename to src/dependencies/zstd-1.5.6/contrib/premake/zstd.lua diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/.gitignore b/src/dependencies/zstd-1.5.6/contrib/pzstd/.gitignore similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/.gitignore rename to src/dependencies/zstd-1.5.6/contrib/pzstd/.gitignore diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/BUCK b/src/dependencies/zstd-1.5.6/contrib/pzstd/BUCK similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/BUCK rename to src/dependencies/zstd-1.5.6/contrib/pzstd/BUCK diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/ErrorHolder.h b/src/dependencies/zstd-1.5.6/contrib/pzstd/ErrorHolder.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/ErrorHolder.h rename to src/dependencies/zstd-1.5.6/contrib/pzstd/ErrorHolder.h diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/Logging.h b/src/dependencies/zstd-1.5.6/contrib/pzstd/Logging.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/Logging.h rename to src/dependencies/zstd-1.5.6/contrib/pzstd/Logging.h diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/Makefile b/src/dependencies/zstd-1.5.6/contrib/pzstd/Makefile similarity index 96% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/Makefile rename to src/dependencies/zstd-1.5.6/contrib/pzstd/Makefile index 830053c..e4b3e8a 100644 --- a/src/dependencies/zstd-1.5.4/contrib/pzstd/Makefile +++ b/src/dependencies/zstd-1.5.6/contrib/pzstd/Makefile @@ -10,7 +10,7 @@ # Standard variables for installation DESTDIR ?= PREFIX ?= /usr/local -BINDIR := $(DESTDIR)$(PREFIX)/bin +BINDIR := $(PREFIX)/bin ZSTDDIR = ../../lib PROGDIR = ../../programs @@ -37,10 +37,13 @@ CFLAGS += -Wno-deprecated-declarations PZSTD_INC = -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(PROGDIR) -I. GTEST_INC = -isystem googletest/googletest/include +# Set the minimum required by gtest +PZSTD_CXX_STD := -std=c++14 + PZSTD_CPPFLAGS = $(PZSTD_INC) PZSTD_CCXXFLAGS = PZSTD_CFLAGS = $(PZSTD_CCXXFLAGS) -PZSTD_CXXFLAGS = $(PZSTD_CCXXFLAGS) -std=c++11 +PZSTD_CXXFLAGS = $(PZSTD_CCXXFLAGS) $(PZSTD_CXX_STD) PZSTD_LDFLAGS = EXTRA_FLAGS = ALL_CFLAGS = $(EXTRA_FLAGS) $(CPPFLAGS) $(PZSTD_CPPFLAGS) $(CFLAGS) $(PZSTD_CFLAGS) @@ -106,12 +109,12 @@ check: .PHONY: install install: PZSTD_CPPFLAGS += -DNDEBUG install: pzstd$(EXT) - install -d -m 755 $(BINDIR)/ - install -m 755 pzstd$(EXT) $(BINDIR)/pzstd$(EXT) + install -d -m 755 $(DESTDIR)$(BINDIR)/ + install -m 755 pzstd$(EXT) $(DESTDIR)$(BINDIR)/pzstd$(EXT) .PHONY: uninstall uninstall: - $(RM) $(BINDIR)/pzstd$(EXT) + $(RM) $(DESTDIR)$(BINDIR)/pzstd$(EXT) # Targets for many different builds .PHONY: all diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/Options.cpp b/src/dependencies/zstd-1.5.6/contrib/pzstd/Options.cpp similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/Options.cpp rename to src/dependencies/zstd-1.5.6/contrib/pzstd/Options.cpp diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/Options.h b/src/dependencies/zstd-1.5.6/contrib/pzstd/Options.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/Options.h rename to src/dependencies/zstd-1.5.6/contrib/pzstd/Options.h diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/Pzstd.cpp b/src/dependencies/zstd-1.5.6/contrib/pzstd/Pzstd.cpp similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/Pzstd.cpp rename to src/dependencies/zstd-1.5.6/contrib/pzstd/Pzstd.cpp diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/Pzstd.h b/src/dependencies/zstd-1.5.6/contrib/pzstd/Pzstd.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/Pzstd.h rename to src/dependencies/zstd-1.5.6/contrib/pzstd/Pzstd.h diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/README.md b/src/dependencies/zstd-1.5.6/contrib/pzstd/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/README.md rename to src/dependencies/zstd-1.5.6/contrib/pzstd/README.md diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/SkippableFrame.cpp b/src/dependencies/zstd-1.5.6/contrib/pzstd/SkippableFrame.cpp similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/SkippableFrame.cpp rename to src/dependencies/zstd-1.5.6/contrib/pzstd/SkippableFrame.cpp diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/SkippableFrame.h b/src/dependencies/zstd-1.5.6/contrib/pzstd/SkippableFrame.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/SkippableFrame.h rename to src/dependencies/zstd-1.5.6/contrib/pzstd/SkippableFrame.h diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/images/Cspeed.png b/src/dependencies/zstd-1.5.6/contrib/pzstd/images/Cspeed.png similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/images/Cspeed.png rename to src/dependencies/zstd-1.5.6/contrib/pzstd/images/Cspeed.png diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/images/Dspeed.png b/src/dependencies/zstd-1.5.6/contrib/pzstd/images/Dspeed.png similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/images/Dspeed.png rename to src/dependencies/zstd-1.5.6/contrib/pzstd/images/Dspeed.png diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/main.cpp b/src/dependencies/zstd-1.5.6/contrib/pzstd/main.cpp similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/main.cpp rename to src/dependencies/zstd-1.5.6/contrib/pzstd/main.cpp diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/test/BUCK b/src/dependencies/zstd-1.5.6/contrib/pzstd/test/BUCK similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/test/BUCK rename to src/dependencies/zstd-1.5.6/contrib/pzstd/test/BUCK diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/test/OptionsTest.cpp b/src/dependencies/zstd-1.5.6/contrib/pzstd/test/OptionsTest.cpp similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/test/OptionsTest.cpp rename to src/dependencies/zstd-1.5.6/contrib/pzstd/test/OptionsTest.cpp diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/test/PzstdTest.cpp b/src/dependencies/zstd-1.5.6/contrib/pzstd/test/PzstdTest.cpp similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/test/PzstdTest.cpp rename to src/dependencies/zstd-1.5.6/contrib/pzstd/test/PzstdTest.cpp diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/test/RoundTrip.h b/src/dependencies/zstd-1.5.6/contrib/pzstd/test/RoundTrip.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/test/RoundTrip.h rename to src/dependencies/zstd-1.5.6/contrib/pzstd/test/RoundTrip.h diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/test/RoundTripTest.cpp b/src/dependencies/zstd-1.5.6/contrib/pzstd/test/RoundTripTest.cpp similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/test/RoundTripTest.cpp rename to src/dependencies/zstd-1.5.6/contrib/pzstd/test/RoundTripTest.cpp diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/BUCK b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/BUCK similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/BUCK rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/BUCK diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/Buffer.h b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/Buffer.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/Buffer.h rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/Buffer.h diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/FileSystem.h b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/FileSystem.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/FileSystem.h rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/FileSystem.h diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/Likely.h b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/Likely.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/Likely.h rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/Likely.h diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/Portability.h b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/Portability.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/Portability.h rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/Portability.h diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/Range.h b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/Range.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/Range.h rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/Range.h diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/ResourcePool.h b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/ResourcePool.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/ResourcePool.h rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/ResourcePool.h diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/ScopeGuard.h b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/ScopeGuard.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/ScopeGuard.h rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/ScopeGuard.h diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/ThreadPool.h b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/ThreadPool.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/ThreadPool.h rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/ThreadPool.h diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/WorkQueue.h b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/WorkQueue.h similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/WorkQueue.h rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/WorkQueue.h diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/test/BUCK b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/test/BUCK similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/test/BUCK rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/test/BUCK diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/test/BufferTest.cpp b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/test/BufferTest.cpp similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/test/BufferTest.cpp rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/test/BufferTest.cpp diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/test/RangeTest.cpp b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/test/RangeTest.cpp similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/test/RangeTest.cpp rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/test/RangeTest.cpp diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/test/ResourcePoolTest.cpp b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/test/ResourcePoolTest.cpp similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/test/ResourcePoolTest.cpp rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/test/ResourcePoolTest.cpp diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/test/ScopeGuardTest.cpp b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/test/ScopeGuardTest.cpp similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/test/ScopeGuardTest.cpp rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/test/ScopeGuardTest.cpp diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/test/ThreadPoolTest.cpp b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/test/ThreadPoolTest.cpp similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/test/ThreadPoolTest.cpp rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/test/ThreadPoolTest.cpp diff --git a/src/dependencies/zstd-1.5.4/contrib/pzstd/utils/test/WorkQueueTest.cpp b/src/dependencies/zstd-1.5.6/contrib/pzstd/utils/test/WorkQueueTest.cpp similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/pzstd/utils/test/WorkQueueTest.cpp rename to src/dependencies/zstd-1.5.6/contrib/pzstd/utils/test/WorkQueueTest.cpp diff --git a/src/dependencies/zstd-1.5.4/contrib/recovery/Makefile b/src/dependencies/zstd-1.5.6/contrib/recovery/Makefile similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/recovery/Makefile rename to src/dependencies/zstd-1.5.6/contrib/recovery/Makefile diff --git a/src/dependencies/zstd-1.5.4/contrib/recovery/recover_directory.c b/src/dependencies/zstd-1.5.6/contrib/recovery/recover_directory.c similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/recovery/recover_directory.c rename to src/dependencies/zstd-1.5.6/contrib/recovery/recover_directory.c diff --git a/src/dependencies/zstd-1.5.6/contrib/seekable_format/README.md b/src/dependencies/zstd-1.5.6/contrib/seekable_format/README.md new file mode 100644 index 0000000..fedf96b --- /dev/null +++ b/src/dependencies/zstd-1.5.6/contrib/seekable_format/README.md @@ -0,0 +1,42 @@ +# Zstandard Seekable Format + +The seekable format splits compressed data into a series of independent "frames", +each compressed individually, +so that decompression of a section in the middle of an archive +only requires zstd to decompress at most a frame's worth of extra data, +instead of the entire archive. + +The frames are appended, so that the decompression of the entire payload +still regenerates the original content, using any compliant zstd decoder. + +On top of that, the seekable format generates a jump table, +which makes it possible to jump directly to the position of the relevant frame +when requesting only a segment of the data. +The jump table is simply ignored by zstd decoders unaware of the seekable format. + +The format is delivered with an API to create seekable archives +and to retrieve arbitrary segments inside the archive. + +### Maximum Frame Size parameter + +When creating a seekable archive, the main parameter is the maximum frame size. + +At compression time, user can manually select the boundaries between segments, +but they don't have to: long segments will be automatically split +when larger than selected maximum frame size. + +Small frame sizes reduce decompression cost when requesting small segments, +because the decoder will nonetheless have to decompress an entire frame +to recover just a single byte from it. + +A good rule of thumb is to select a maximum frame size roughly equivalent +to the access pattern when it's known. +For example, if the application tends to request 4KB blocks, +then it's a good idea to set a maximum frame size in the vicinity of 4 KB. + +But small frame sizes also reduce compression ratio, +and increase the cost for the jump table, +so there is a balance to find. + +In general, try to avoid really tiny frame sizes (<1 KB), +which would have a large negative impact on compression ratio. diff --git a/src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/.gitignore b/src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/.gitignore similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/.gitignore rename to src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/.gitignore diff --git a/src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/Makefile b/src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/Makefile similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/Makefile rename to src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/Makefile diff --git a/src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/parallel_compression.c b/src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/parallel_compression.c similarity index 99% rename from src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/parallel_compression.c rename to src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/parallel_compression.c index 0ec9fbd..4e06fae 100644 --- a/src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/parallel_compression.c +++ b/src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/parallel_compression.c @@ -25,7 +25,7 @@ #include "pool.h" // use zstd thread pool for demo -#include "zstd_seekable.h" +#include "../zstd_seekable.h" static void* malloc_orDie(size_t size) { diff --git a/src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/parallel_processing.c b/src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/parallel_processing.c similarity index 98% rename from src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/parallel_processing.c rename to src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/parallel_processing.c index b1709db..9283710 100644 --- a/src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/parallel_processing.c +++ b/src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/parallel_processing.c @@ -19,7 +19,7 @@ #define ZSTD_STATIC_LINKING_ONLY #include // presumes zstd library is installed #include -#if defined(WIN32) || defined(_WIN32) +#if defined(_WIN32) # include # define SLEEP(x) Sleep(x) #else @@ -29,7 +29,7 @@ #include "pool.h" // use zstd thread pool for demo -#include "zstd_seekable.h" +#include "../zstd_seekable.h" #define MIN(a, b) ((a) < (b) ? (a) : (b)) diff --git a/src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/seekable_compression.c b/src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/seekable_compression.c similarity index 91% rename from src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/seekable_compression.c rename to src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/seekable_compression.c index 182b46f..c3d227d 100644 --- a/src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/seekable_compression.c +++ b/src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/seekable_compression.c @@ -13,7 +13,7 @@ #define ZSTD_STATIC_LINKING_ONLY #include // presumes zstd library is installed -#include "zstd_seekable.h" +#include "../zstd_seekable.h" static void* malloc_orDie(size_t size) { @@ -112,20 +112,23 @@ static char* createOutFilename_orDie(const char* filename) return (char*)outSpace; } -int main(int argc, const char** argv) { +#define CLEVEL_DEFAULT 5 +int main(int argc, const char** argv) +{ const char* const exeName = argv[0]; - if (argc!=3) { - printf("wrong arguments\n"); - printf("usage:\n"); - printf("%s FILE FRAME_SIZE\n", exeName); + if (argc<3 || argc>4) { + printf("wrong arguments \n"); + printf("usage: \n"); + printf("%s FILE FRAME_SIZE [LEVEL] \n", exeName); return 1; } { const char* const inFileName = argv[1]; unsigned const frameSize = (unsigned)atoi(argv[2]); + int const cLevel = (argc==4) ? atoi(argv[3]) : CLEVEL_DEFAULT; char* const outFileName = createOutFilename_orDie(inFileName); - compressFile_orDie(inFileName, outFileName, 5, frameSize); + compressFile_orDie(inFileName, outFileName, cLevel, frameSize); free(outFileName); } diff --git a/src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/seekable_decompression.c b/src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/seekable_decompression.c similarity index 99% rename from src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/seekable_decompression.c rename to src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/seekable_decompression.c index 2c4f3ba..7edbca8 100644 --- a/src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/seekable_decompression.c +++ b/src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/seekable_decompression.c @@ -16,7 +16,7 @@ #include // presumes zstd library is installed #include -#include "zstd_seekable.h" +#include "../zstd_seekable.h" #define MIN(a, b) ((a) < (b) ? (a) : (b)) diff --git a/src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/seekable_decompression_mem.c b/src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/seekable_decompression_mem.c similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/seekable_format/examples/seekable_decompression_mem.c rename to src/dependencies/zstd-1.5.6/contrib/seekable_format/examples/seekable_decompression_mem.c diff --git a/src/dependencies/zstd-1.5.4/contrib/seekable_format/tests/.gitignore b/src/dependencies/zstd-1.5.6/contrib/seekable_format/tests/.gitignore similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/seekable_format/tests/.gitignore rename to src/dependencies/zstd-1.5.6/contrib/seekable_format/tests/.gitignore diff --git a/src/dependencies/zstd-1.5.4/contrib/seekable_format/tests/Makefile b/src/dependencies/zstd-1.5.6/contrib/seekable_format/tests/Makefile similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/seekable_format/tests/Makefile rename to src/dependencies/zstd-1.5.6/contrib/seekable_format/tests/Makefile diff --git a/src/dependencies/zstd-1.5.4/contrib/seekable_format/tests/seekable_tests.c b/src/dependencies/zstd-1.5.6/contrib/seekable_format/tests/seekable_tests.c similarity index 59% rename from src/dependencies/zstd-1.5.4/contrib/seekable_format/tests/seekable_tests.c rename to src/dependencies/zstd-1.5.6/contrib/seekable_format/tests/seekable_tests.c index 1bb2d0e..f89bdc9 100644 --- a/src/dependencies/zstd-1.5.4/contrib/seekable_format/tests/seekable_tests.c +++ b/src/dependencies/zstd-1.5.6/contrib/seekable_format/tests/seekable_tests.c @@ -3,8 +3,55 @@ #include // malloc #include #include +#include -#include "zstd_seekable.h" +#include "../zstd_seekable.h" + + +/* ZSTD_seekable_customFile implementation that reads/seeks a buffer while keeping track of total bytes read */ +typedef struct { + const void *ptr; + size_t size; + size_t pos; + size_t totalRead; +} buffWrapperWithTotal_t; + +static int readBuffWithTotal(void* opaque, void* buffer, size_t n) +{ + buffWrapperWithTotal_t* const buff = (buffWrapperWithTotal_t*)opaque; + assert(buff != NULL); + if (buff->pos + n > buff->size) return -1; + memcpy(buffer, (const char*)buff->ptr + buff->pos, n); + buff->pos += n; + buff->totalRead += n; + return 0; +} + +static int seekBuffWithTotal(void* opaque, long long offset, int origin) +{ + buffWrapperWithTotal_t* const buff = (buffWrapperWithTotal_t*) opaque; + unsigned long long newOffset; + assert(buff != NULL); + switch (origin) { + case SEEK_SET: + assert(offset >= 0); + newOffset = (unsigned long long)offset; + break; + case SEEK_CUR: + newOffset = (unsigned long long)((long long)buff->pos + offset); + break; + case SEEK_END: + newOffset = (unsigned long long)((long long)buff->size + offset); + break; + default: + assert(0); /* not possible */ + } + if (newOffset > buff->size) { + return -1; + } + buff->pos = newOffset; + return 0; +} /* Basic unit tests for zstd seekable format */ int main(int argc, const char** argv) @@ -220,6 +267,92 @@ int main(int argc, const char** argv) } printf("Success!\n"); + + printf("Test %u - multiple decompress calls: ", testNb++); + { char const inBuffer[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt"; + size_t const inSize = sizeof(inBuffer); + + size_t const seekCapacity = 5000; + void* const seekBuffer = malloc(seekCapacity); + assert(seekBuffer != NULL); + size_t seekSize; + + size_t const outCapacity = inSize; + char* const outBuffer = malloc(outCapacity); + assert(outBuffer != NULL); + + ZSTD_seekable_CStream* const zscs = ZSTD_seekable_createCStream(); + assert(zscs != NULL); + + /* compress test data with a small frame size to ensure multiple frames in the output */ + unsigned const maxFrameSize = 40; + { size_t const initStatus = ZSTD_seekable_initCStream(zscs, 9, 0 /* checksumFlag */, maxFrameSize); + assert(!ZSTD_isError(initStatus)); + } + + { ZSTD_outBuffer outb = { .dst=seekBuffer, .pos=0, .size=seekCapacity }; + ZSTD_inBuffer inb = { .src=inBuffer, .pos=0, .size=inSize }; + + while (inb.pos < inb.size) { + size_t const cStatus = ZSTD_seekable_compressStream(zscs, &outb, &inb); + assert(!ZSTD_isError(cStatus)); + } + + size_t const endStatus = ZSTD_seekable_endStream(zscs, &outb); + assert(!ZSTD_isError(endStatus)); + seekSize = outb.pos; + } + + ZSTD_seekable* const stream = ZSTD_seekable_create(); + assert(stream != NULL); + buffWrapperWithTotal_t buffWrapper = {seekBuffer, seekSize, 0, 0}; + { ZSTD_seekable_customFile srcFile = {&buffWrapper, &readBuffWithTotal, &seekBuffWithTotal}; + size_t const initStatus = ZSTD_seekable_initAdvanced(stream, srcFile); + assert(!ZSTD_isError(initStatus)); } + + /* Perform a series of small reads and seeks (repeatedly read 1 byte and skip 1 byte) + and check that we didn't reread input data unnecessarily */ + size_t pos; + for (pos = 0; pos < inSize; pos += 2) { + size_t const decStatus = ZSTD_seekable_decompress(stream, outBuffer, 1, pos); + if (decStatus != 1 || outBuffer[0] != inBuffer[pos]) { + goto _test_error; + } + } + if (buffWrapper.totalRead > seekSize) { + /* We read more than the compressed size, meaning there were some rereads. + This is unneeded because we only seeked forward. */ + printf("Too much data read: %zu read, with compressed size %zu\n", buffWrapper.totalRead, seekSize); + goto _test_error; + } + + /* Perform some reads and seeks to ensure correctness */ + struct { + size_t offset; + size_t size; + } const tests[] = { /* Assume the frame size is 40 */ + {20, 40}, /* read partial data from two frames */ + {60, 10}, /* continue reading from the same offset */ + {50, 20}, /* seek backward within the same frame */ + {10, 10}, /* seek backward to a different frame */ + {25, 10}, /* seek forward within the same frame */ + {60, 10}, /* seek forward to a different frame */ + }; + size_t idx; + for (idx = 0; idx < sizeof(tests) / sizeof(tests[0]); idx++) { + size_t const decStatus = ZSTD_seekable_decompress(stream, outBuffer, tests[idx].size, tests[idx].offset); + if (decStatus != tests[idx].size || memcmp(outBuffer, inBuffer + tests[idx].offset, tests[idx].size) != 0) { + goto _test_error; + } + } + + free(seekBuffer); + free(outBuffer); + ZSTD_seekable_freeCStream(zscs); + ZSTD_seekable_free(stream); + } + printf("Success!\n"); + /* TODO: Add more tests */ printf("Finished tests\n"); return 0; diff --git a/src/dependencies/zstd-1.5.4/contrib/seekable_format/zstd_seekable.h b/src/dependencies/zstd-1.5.6/contrib/seekable_format/zstd_seekable.h similarity index 92% rename from src/dependencies/zstd-1.5.4/contrib/seekable_format/zstd_seekable.h rename to src/dependencies/zstd-1.5.6/contrib/seekable_format/zstd_seekable.h index d2807cf..a0e5e35 100644 --- a/src/dependencies/zstd-1.5.4/contrib/seekable_format/zstd_seekable.h +++ b/src/dependencies/zstd-1.5.6/contrib/seekable_format/zstd_seekable.h @@ -15,8 +15,8 @@ extern "C" { #define ZSTD_SEEKABLE_MAXFRAMES 0x8000000U -/* Limit the maximum size to avoid any potential issues storing the compressed size */ -#define ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE 0x80000000U +/* Limit maximum size to avoid potential issues storing the compressed size */ +#define ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE 0x40000000U /*-**************************************************************************** * Seekable Format @@ -48,10 +48,19 @@ typedef struct ZSTD_seekTable_s ZSTD_seekTable; * * Use ZSTD_seekable_initCStream() to initialize a ZSTD_seekable_CStream object * for a new compression operation. -* `maxFrameSize` indicates the size at which to automatically start a new -* seekable frame. `maxFrameSize == 0` implies the default maximum size. -* `checksumFlag` indicates whether or not the seek table should include frame -* checksums on the uncompressed data for verification. +* - `maxFrameSize` indicates the size at which to automatically start a new +* seekable frame. +* `maxFrameSize == 0` implies the default maximum size. +* Smaller frame sizes allow faster decompression of small segments, +* since retrieving a single byte requires decompression of +* the full frame where the byte belongs. +* In general, size the frames to roughly correspond to +* the access granularity (when it's known). +* But small sizes also reduce compression ratio. +* Avoid really tiny frame sizes (< 1 KB), +* that would hurt compression ratio considerably. +* - `checksumFlag` indicates whether or not the seek table should include frame +* checksums on the uncompressed data for verification. * @return : a size hint for input to provide for compression, or an error code * checkable with ZSTD_isError() * diff --git a/src/dependencies/zstd-1.5.4/contrib/seekable_format/zstd_seekable_compression_format.md b/src/dependencies/zstd-1.5.6/contrib/seekable_format/zstd_seekable_compression_format.md similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/seekable_format/zstd_seekable_compression_format.md rename to src/dependencies/zstd-1.5.6/contrib/seekable_format/zstd_seekable_compression_format.md diff --git a/src/dependencies/zstd-1.5.4/contrib/seekable_format/zstdseek_compress.c b/src/dependencies/zstd-1.5.6/contrib/seekable_format/zstdseek_compress.c similarity index 98% rename from src/dependencies/zstd-1.5.4/contrib/seekable_format/zstdseek_compress.c rename to src/dependencies/zstd-1.5.6/contrib/seekable_format/zstdseek_compress.c index 113f6f9..4997807 100644 --- a/src/dependencies/zstd-1.5.4/contrib/seekable_format/zstdseek_compress.c +++ b/src/dependencies/zstd-1.5.6/contrib/seekable_format/zstdseek_compress.c @@ -230,6 +230,8 @@ size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* const BYTE* const inBase = (const BYTE*) input->src + input->pos; size_t inLen = input->size - input->pos; + assert(zcs->maxFrameSize < INT_MAX); + ZSTD_CCtx_setParameter(zcs->cstream, ZSTD_c_srcSizeHint, (int)zcs->maxFrameSize); inLen = MIN(inLen, (size_t)(zcs->maxFrameSize - zcs->frameDSize)); /* if we haven't finished flushing the last frame, don't start writing a new one */ diff --git a/src/dependencies/zstd-1.5.4/contrib/seekable_format/zstdseek_decompress.c b/src/dependencies/zstd-1.5.6/contrib/seekable_format/zstdseek_decompress.c similarity index 99% rename from src/dependencies/zstd-1.5.4/contrib/seekable_format/zstdseek_decompress.c rename to src/dependencies/zstd-1.5.6/contrib/seekable_format/zstdseek_decompress.c index fbb2d4f..4fefc5f 100644 --- a/src/dependencies/zstd-1.5.4/contrib/seekable_format/zstdseek_decompress.c +++ b/src/dependencies/zstd-1.5.6/contrib/seekable_format/zstdseek_decompress.c @@ -493,7 +493,7 @@ size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, unsign size_t srcBytesRead = 0; do { /* check if we can continue from a previous decompress job */ - if (targetFrame != zs->curFrame || offset != zs->decompressedOffset) { + if (targetFrame != zs->curFrame || offset < zs->decompressedOffset) { zs->decompressedOffset = zs->seekTable.entries[targetFrame].dOffset; zs->curFrame = targetFrame; diff --git a/src/dependencies/zstd-1.5.4/contrib/seqBench/Makefile b/src/dependencies/zstd-1.5.6/contrib/seqBench/Makefile similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/seqBench/Makefile rename to src/dependencies/zstd-1.5.6/contrib/seqBench/Makefile diff --git a/src/dependencies/zstd-1.5.4/contrib/seqBench/seqBench.c b/src/dependencies/zstd-1.5.6/contrib/seqBench/seqBench.c similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/seqBench/seqBench.c rename to src/dependencies/zstd-1.5.6/contrib/seqBench/seqBench.c diff --git a/src/dependencies/zstd-1.5.4/contrib/snap/snapcraft.yaml b/src/dependencies/zstd-1.5.6/contrib/snap/snapcraft.yaml similarity index 100% rename from src/dependencies/zstd-1.5.4/contrib/snap/snapcraft.yaml rename to src/dependencies/zstd-1.5.6/contrib/snap/snapcraft.yaml diff --git a/src/dependencies/zstd-1.5.4/doc/README.md b/src/dependencies/zstd-1.5.6/doc/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/doc/README.md rename to src/dependencies/zstd-1.5.6/doc/README.md diff --git a/src/dependencies/zstd-1.5.4/doc/decompressor_errata.md b/src/dependencies/zstd-1.5.6/doc/decompressor_errata.md similarity index 57% rename from src/dependencies/zstd-1.5.4/doc/decompressor_errata.md rename to src/dependencies/zstd-1.5.6/doc/decompressor_errata.md index b162e7f..b570f73 100644 --- a/src/dependencies/zstd-1.5.4/doc/decompressor_errata.md +++ b/src/dependencies/zstd-1.5.6/doc/decompressor_errata.md @@ -6,12 +6,53 @@ Each entry will contain: 1. The last affected decompressor versions. 2. The decompressor components affected. 2. Whether the compressed frame could ever be produced by the reference compressor. -3. An example frame. +3. An example frame (hexadecimal string when it can be short enough, link to golden file otherwise) 4. A description of the bug. The document is in reverse chronological order, with the bugs that affect the most recent zstd decompressor versions listed first. +No sequence using the 2-bytes format +------------------------------------------------ + +**Last affected version**: v1.5.5 + +**Affected decompressor component(s)**: Library & CLI + +**Produced by the reference compressor**: No + +**Example Frame**: see zstd/tests/golden-decompression/zeroSeq_2B.zst + +The zstd decoder incorrectly expects FSE tables when there are 0 sequences present in the block +if the value 0 is encoded using the 2-bytes format. +Instead, it should immediately end the sequence section, and move on to next block. + +This situation was never generated by the reference compressor, +because representing 0 sequences with the 2-bytes format is inefficient +(the 1-byte format is always used in this case). + + +Compressed block with a size of exactly 128 KB +------------------------------------------------ + +**Last affected version**: v1.5.2 + +**Affected decompressor component(s)**: Library & CLI + +**Produced by the reference compressor**: No + +**Example Frame**: see zstd/tests/golden-decompression/block-128k.zst + +The zstd decoder incorrectly rejected blocks of type `Compressed_Block` when their size was exactly 128 KB. +Note that `128 KB - 1` was accepted, and `128 KB + 1` is forbidden by the spec. + +This type of block was never generated by the reference compressor. + +These blocks used to be disallowed by the spec up until spec version 0.3.2 when the restriction was lifted by [PR#1689](https://github.com/facebook/zstd/pull/1689). + +> A Compressed_Block has the extra restriction that Block_Size is always strictly less than the decompressed size. If this condition cannot be respected, the block must be sent uncompressed instead (Raw_Block). + + Compressed block with 0 literals and 0 sequences ------------------------------------------------ @@ -31,6 +72,7 @@ Additionally, these blocks were disallowed by the spec up until spec version 0.3 > A Compressed_Block has the extra restriction that Block_Size is always strictly less than the decompressed size. If this condition cannot be respected, the block must be sent uncompressed instead (Raw_Block). + First block is RLE block ------------------------ @@ -52,6 +94,7 @@ block. https://github.com/facebook/zstd/blob/8814aa5bfa74f05a86e55e9d508da177a893ceeb/lib/compress/zstd_compress.c#L3527-L3535 + Tiny FSE Table & Block ---------------------- @@ -82,3 +125,24 @@ The total `Block_Content` is `5` bytes, and `Last_Table_Offset` is `2`. See the compressor workaround code: https://github.com/facebook/zstd/blob/8814aa5bfa74f05a86e55e9d508da177a893ceeb/lib/compress/zstd_compress.c#L2667-L2682 + +Magicless format +---------------------- + +**Last affected version**: v1.5.5 + +**Affected decompressor component(s)**: Library + +**Produced by the reference compressor**: Yes (example: https://gist.github.com/embg/9940726094f4cf2cef162cffe9319232) + +**Example Frame**: `27 b5 2f fd 00 03 19 00 00 66 6f 6f 3f ba c4 59` + +v1.5.6 fixes several bugs in which the magicless-format decoder rejects valid frames. +These include but are not limited to: +* Valid frames that happen to begin with a legacy magic number (little-endian) +* Valid frames that happen to begin with a skippable magic number (little-endian) + +If you are affected by this issue and cannot update to v1.5.6 or later, there is a +workaround to recover affected data. Simply prepend the ZSTD magic number +`0xFD2FB528` (little-endian) to your data and decompress using the standard-format +decoder. diff --git a/src/dependencies/zstd-1.5.6/doc/decompressor_permissive.md b/src/dependencies/zstd-1.5.6/doc/decompressor_permissive.md new file mode 100644 index 0000000..bd77165 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/doc/decompressor_permissive.md @@ -0,0 +1,60 @@ +Decompressor Permissiveness to Invalid Data +=========================================== + +This document describes the behavior of the reference decompressor in cases +where it accepts formally invalid data instead of reporting an error. + +While the reference decompressor *must* decode any compliant frame following +the specification, its ability to detect erroneous data is on a best effort +basis: the decoder may accept input data that would be formally invalid, +when it causes no risk to the decoder, and which detection would cost too much +complexity or speed regression. + +In practice, the vast majority of invalid data are detected, if only because +many corruption events are dangerous for the decoder process (such as +requesting an out-of-bound memory access) and many more are easy to check. + +This document lists a few known cases where invalid data was formerly accepted +by the decoder, and what has changed since. + + +Offset == 0 +----------- + +**Last affected version**: v1.5.5 + +**Produced by the reference compressor**: No + +**Example Frame**: `28b5 2ffd 0000 4500 0008 0002 002f 430b ae` + +If a sequence is decoded with `literals_length = 0` and `offset_value = 3` +while `Repeated_Offset_1 = 1`, the computed offset will be `0`, which is +invalid. + +The reference decompressor up to v1.5.5 processes this case as if the computed +offset was `1`, including inserting `1` into the repeated offset list. +This prevents the output buffer from remaining uninitialized, thus denying a +potential attack vector from an untrusted source. +However, in the rare case where this scenario would be the outcome of a +transmission or storage error, the decoder relies on the checksum to detect +the error. + +In newer versions, this case is always detected and reported as a corruption error. + + +Non-zeroes reserved bits +------------------------ + +**Last affected version**: v1.5.5 + +**Produced by the reference compressor**: No + +The Sequences section of each block has a header, and one of its elements is a +byte, which describes the compression mode of each symbol. +This byte contains 2 reserved bits which must be set to zero. + +The reference decompressor up to v1.5.5 just ignores these 2 bits. +This behavior has no consequence for the rest of the frame decoding process. + +In newer versions, the 2 reserved bits are actively checked for value zero, +and the decoder reports a corruption error if they are not. diff --git a/src/dependencies/zstd-1.5.4/doc/educational_decoder/.gitignore b/src/dependencies/zstd-1.5.6/doc/educational_decoder/.gitignore similarity index 100% rename from src/dependencies/zstd-1.5.4/doc/educational_decoder/.gitignore rename to src/dependencies/zstd-1.5.6/doc/educational_decoder/.gitignore diff --git a/src/dependencies/zstd-1.5.4/doc/educational_decoder/Makefile b/src/dependencies/zstd-1.5.6/doc/educational_decoder/Makefile similarity index 100% rename from src/dependencies/zstd-1.5.4/doc/educational_decoder/Makefile rename to src/dependencies/zstd-1.5.6/doc/educational_decoder/Makefile diff --git a/src/dependencies/zstd-1.5.4/doc/educational_decoder/README.md b/src/dependencies/zstd-1.5.6/doc/educational_decoder/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/doc/educational_decoder/README.md rename to src/dependencies/zstd-1.5.6/doc/educational_decoder/README.md diff --git a/src/dependencies/zstd-1.5.4/doc/educational_decoder/harness.c b/src/dependencies/zstd-1.5.6/doc/educational_decoder/harness.c similarity index 100% rename from src/dependencies/zstd-1.5.4/doc/educational_decoder/harness.c rename to src/dependencies/zstd-1.5.6/doc/educational_decoder/harness.c diff --git a/src/dependencies/zstd-1.5.4/doc/educational_decoder/zstd_decompress.c b/src/dependencies/zstd-1.5.6/doc/educational_decoder/zstd_decompress.c similarity index 99% rename from src/dependencies/zstd-1.5.4/doc/educational_decoder/zstd_decompress.c rename to src/dependencies/zstd-1.5.6/doc/educational_decoder/zstd_decompress.c index 9ade765..839e085 100644 --- a/src/dependencies/zstd-1.5.4/doc/educational_decoder/zstd_decompress.c +++ b/src/dependencies/zstd-1.5.6/doc/educational_decoder/zstd_decompress.c @@ -997,7 +997,8 @@ static void decompress_sequences(frame_context_t *const ctx, const size_t num_sequences); static sequence_command_t decode_sequence(sequence_states_t *const state, const u8 *const src, - i64 *const offset); + i64 *const offset, + int lastSequence); static void decode_seq_table(FSE_dtable *const table, istream_t *const in, const seq_part_t type, const seq_mode_t mode); @@ -1017,12 +1018,7 @@ static size_t decode_sequences(frame_context_t *const ctx, istream_t *in, // This is a variable size field using between 1 and 3 bytes. Let's call its // first byte byte0." u8 header = IO_read_bits(in, 8); - if (header == 0) { - // "There are no sequences. The sequence section stops there. - // Regenerated content is defined entirely by literals section." - *sequences = NULL; - return 0; - } else if (header < 128) { + if (header < 128) { // "Number_of_Sequences = byte0 . Uses 1 byte." num_sequences = header; } else if (header < 255) { @@ -1033,6 +1029,12 @@ static size_t decode_sequences(frame_context_t *const ctx, istream_t *in, num_sequences = IO_read_bits(in, 16) + 0x7F00; } + if (num_sequences == 0) { + // "There are no sequences. The sequence section stops there." + *sequences = NULL; + return 0; + } + *sequences = malloc(num_sequences * sizeof(sequence_command_t)); if (!*sequences) { BAD_ALLOC(); @@ -1114,7 +1116,7 @@ static void decompress_sequences(frame_context_t *const ctx, istream_t *in, for (size_t i = 0; i < num_sequences; i++) { // Decode sequences one by one - sequences[i] = decode_sequence(&states, src, &bit_offset); + sequences[i] = decode_sequence(&states, src, &bit_offset, i==num_sequences-1); } if (bit_offset != 0) { @@ -1125,7 +1127,8 @@ static void decompress_sequences(frame_context_t *const ctx, istream_t *in, // Decode a single sequence and update the state static sequence_command_t decode_sequence(sequence_states_t *const states, const u8 *const src, - i64 *const offset) { + i64 *const offset, + int lastSequence) { // "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." @@ -1160,7 +1163,7 @@ static sequence_command_t decode_sequence(sequence_states_t *const states, // Literals_Length_State is updated, followed by Match_Length_State, and // then Offset_State." // If the stream is complete don't read bits to update state - if (*offset != 0) { + if (!lastSequence) { FSE_update_state(&states->ll_table, &states->ll_state, src, offset); FSE_update_state(&states->ml_table, &states->ml_state, src, offset); FSE_update_state(&states->of_table, &states->of_state, src, offset); @@ -1210,7 +1213,7 @@ static void decode_seq_table(FSE_dtable *const table, istream_t *const in, break; } case seq_repeat: - // "Repeat_Mode : re-use distribution table from previous compressed + // "Repeat_Mode : reuse distribution table from previous compressed // block." // Nothing to do here, table will be unchanged if (!table->symbols) { @@ -1399,7 +1402,7 @@ size_t ZSTD_get_decompressed_size(const void *src, const size_t src_len) { /******* END OUTPUT SIZE COUNTING *********************************************/ /******* DICTIONARY PARSING ***************************************************/ -dictionary_t* create_dictionary() { +dictionary_t* create_dictionary(void) { dictionary_t* const dict = calloc(1, sizeof(dictionary_t)); if (!dict) { BAD_ALLOC(); diff --git a/src/dependencies/zstd-1.5.4/doc/educational_decoder/zstd_decompress.h b/src/dependencies/zstd-1.5.6/doc/educational_decoder/zstd_decompress.h similarity index 100% rename from src/dependencies/zstd-1.5.4/doc/educational_decoder/zstd_decompress.h rename to src/dependencies/zstd-1.5.6/doc/educational_decoder/zstd_decompress.h diff --git a/src/dependencies/zstd-1.5.4/doc/images/CSpeed2.png b/src/dependencies/zstd-1.5.6/doc/images/CSpeed2.png similarity index 100% rename from src/dependencies/zstd-1.5.4/doc/images/CSpeed2.png rename to src/dependencies/zstd-1.5.6/doc/images/CSpeed2.png diff --git a/src/dependencies/zstd-1.5.4/doc/images/DCspeed5.png b/src/dependencies/zstd-1.5.6/doc/images/DCspeed5.png similarity index 100% rename from src/dependencies/zstd-1.5.4/doc/images/DCspeed5.png rename to src/dependencies/zstd-1.5.6/doc/images/DCspeed5.png diff --git a/src/dependencies/zstd-1.5.4/doc/images/DSpeed3.png b/src/dependencies/zstd-1.5.6/doc/images/DSpeed3.png similarity index 100% rename from src/dependencies/zstd-1.5.4/doc/images/DSpeed3.png rename to src/dependencies/zstd-1.5.6/doc/images/DSpeed3.png diff --git a/src/dependencies/zstd-1.5.4/doc/images/cdict_v136.png b/src/dependencies/zstd-1.5.6/doc/images/cdict_v136.png similarity index 100% rename from src/dependencies/zstd-1.5.4/doc/images/cdict_v136.png rename to src/dependencies/zstd-1.5.6/doc/images/cdict_v136.png diff --git a/src/dependencies/zstd-1.5.4/doc/images/dict-cr.png b/src/dependencies/zstd-1.5.6/doc/images/dict-cr.png similarity index 100% rename from src/dependencies/zstd-1.5.4/doc/images/dict-cr.png rename to src/dependencies/zstd-1.5.6/doc/images/dict-cr.png diff --git a/src/dependencies/zstd-1.5.4/doc/images/dict-cs.png b/src/dependencies/zstd-1.5.6/doc/images/dict-cs.png similarity index 100% rename from src/dependencies/zstd-1.5.4/doc/images/dict-cs.png rename to src/dependencies/zstd-1.5.6/doc/images/dict-cs.png diff --git a/src/dependencies/zstd-1.5.4/doc/images/dict-ds.png b/src/dependencies/zstd-1.5.6/doc/images/dict-ds.png similarity index 100% rename from src/dependencies/zstd-1.5.4/doc/images/dict-ds.png rename to src/dependencies/zstd-1.5.6/doc/images/dict-ds.png diff --git a/src/dependencies/zstd-1.5.4/doc/images/zstd_cdict_v1_3_5.png b/src/dependencies/zstd-1.5.6/doc/images/zstd_cdict_v1_3_5.png similarity index 100% rename from src/dependencies/zstd-1.5.4/doc/images/zstd_cdict_v1_3_5.png rename to src/dependencies/zstd-1.5.6/doc/images/zstd_cdict_v1_3_5.png diff --git a/src/dependencies/zstd-1.5.4/doc/images/zstd_logo86.png b/src/dependencies/zstd-1.5.6/doc/images/zstd_logo86.png similarity index 100% rename from src/dependencies/zstd-1.5.4/doc/images/zstd_logo86.png rename to src/dependencies/zstd-1.5.6/doc/images/zstd_logo86.png diff --git a/src/dependencies/zstd-1.5.4/doc/zstd_compression_format.md b/src/dependencies/zstd-1.5.6/doc/zstd_compression_format.md similarity index 95% rename from src/dependencies/zstd-1.5.4/doc/zstd_compression_format.md rename to src/dependencies/zstd-1.5.6/doc/zstd_compression_format.md index e40677a..7955dae 100644 --- a/src/dependencies/zstd-1.5.4/doc/zstd_compression_format.md +++ b/src/dependencies/zstd-1.5.6/doc/zstd_compression_format.md @@ -16,7 +16,7 @@ Distribution of this document is unlimited. ### Version -0.3.7 (2020-12-09) +0.4.0 (2023-06-05) Introduction @@ -470,6 +470,7 @@ This field uses 2 lowest bits of first byte, describing 4 different block types repeated `Regenerated_Size` times. - `Compressed_Literals_Block` - This is a standard Huffman-compressed block, starting with a Huffman tree description. + In this mode, there are at least 2 different literals represented in the Huffman tree description. See details below. - `Treeless_Literals_Block` - This is a Huffman-compressed block, using Huffman tree _from previous Huffman-compressed literals block_. @@ -533,15 +534,20 @@ __`Size_Format` for `Compressed_Literals_Block` and `Treeless_Literals_Block`__ Both `Compressed_Size` and `Regenerated_Size` fields follow __little-endian__ convention. Note: `Compressed_Size` __includes__ the size of the Huffman Tree description _when_ it is present. +Note 2: `Compressed_Size` can never be `==0`. +Even in single-stream scenario, assuming an empty content, it must be `>=1`, +since it contains at least the final end bit flag. +In 4-streams scenario, a valid `Compressed_Size` is necessarily `>= 10` +(6 bytes for the jump table, + 4x1 bytes for the 4 streams). -4 streams is superior to 1 stream in decompression speed, +4 streams is faster than 1 stream in decompression speed, by exploiting instruction level parallelism. But it's also more expensive, costing on average ~7.3 bytes more than the 1 stream mode, mostly from the jump table. In general, use the 4 streams mode when there are more literals to decode, to favor higher decompression speeds. -Beyond 1KB, the 4 streams mode is compulsory anyway. +Note that beyond >1KB of literals, the 4 streams mode is compulsory. Note that a minimum of 6 bytes is required for the 4 streams mode. That's a technical minimum, but it's not recommended to employ the 4 streams mode @@ -566,6 +572,7 @@ or from a dictionary. ### `Huffman_Tree_Description` This section is only present when `Literals_Block_Type` type is `Compressed_Literals_Block` (`2`). +The tree describes the weights of all literals symbols that can be present in the literals block, at least 2 and up to 256. The format of the Huffman tree description can be found at [Huffman Tree description](#huffman-tree-description). The size of `Huffman_Tree_Description` is determined during decoding process, it must be used to determine where streams begin. @@ -575,10 +582,10 @@ it must be used to determine where streams begin. ### Jump Table The Jump Table is only present when there are 4 Huffman-coded streams. -Reminder : Huffman compressed data consists of either 1 or 4 Huffman-coded streams. +Reminder : Huffman compressed data consists of either 1 or 4 streams. If only one stream is present, it is a single bitstream occupying the entire -remaining portion of the literals block, encoded as described within +remaining portion of the literals block, encoded as described in [Huffman-Coded Streams](#huffman-coded-streams). If there are four streams, `Literals_Section_Header` only provided @@ -589,17 +596,18 @@ except for the last stream which may be up to 3 bytes smaller, to reach a total decompressed size as specified in `Regenerated_Size`. The compressed size of each stream is provided explicitly in the Jump Table. -Jump Table is 6 bytes long, and consist of three 2-byte __little-endian__ fields, +Jump Table is 6 bytes long, and consists of three 2-byte __little-endian__ fields, describing the compressed sizes of the first three streams. -`Stream4_Size` is computed from total `Total_Streams_Size` minus sizes of other streams. +`Stream4_Size` is computed from `Total_Streams_Size` minus sizes of other streams: `Stream4_Size = Total_Streams_Size - 6 - Stream1_Size - Stream2_Size - Stream3_Size`. -Note: if `Stream1_Size + Stream2_Size + Stream3_Size > Total_Streams_Size`, +`Stream4_Size` is necessarily `>= 1`. Therefore, +if `Total_Streams_Size < Stream1_Size + Stream2_Size + Stream3_Size + 6 + 1`, data is considered corrupted. Each of these 4 bitstreams is then decoded independently as a Huffman-Coded stream, -as described at [Huffman-Coded Streams](#huffman-coded-streams) +as described in [Huffman-Coded Streams](#huffman-coded-streams) Sequences Section @@ -642,13 +650,15 @@ __`Number_of_Sequences`__ This is a variable size field using between 1 and 3 bytes. Let's call its first byte `byte0`. -- `if (byte0 == 0)` : there are no sequences. - The sequence section stops there. - Decompressed content is defined entirely as Literals Section content. - The FSE tables used in `Repeat_Mode` aren't updated. - `if (byte0 < 128)` : `Number_of_Sequences = byte0` . Uses 1 byte. -- `if (byte0 < 255)` : `Number_of_Sequences = ((byte0-128) << 8) + byte1` . Uses 2 bytes. -- `if (byte0 == 255)`: `Number_of_Sequences = byte1 + (byte2<<8) + 0x7F00` . Uses 3 bytes. +- `if (byte0 < 255)` : `Number_of_Sequences = ((byte0 - 0x80) << 8) + byte1`. Uses 2 bytes. + Note that the 2 bytes format fully overlaps the 1 byte format. +- `if (byte0 == 255)`: `Number_of_Sequences = byte1 + (byte2<<8) + 0x7F00`. Uses 3 bytes. + +`if (Number_of_Sequences == 0)` : there are no sequences. + The sequence section stops immediately, + FSE tables used in `Repeat_Mode` aren't updated. + Block's decompressed content is defined solely by the Literals Section content. __Symbol compression modes__ @@ -919,7 +929,10 @@ There is an exception though, when current sequence's `literals_length = 0`. In this case, repeated offsets are shifted by one, so an `offset_value` of 1 means `Repeated_Offset2`, an `offset_value` of 2 means `Repeated_Offset3`, -and an `offset_value` of 3 means `Repeated_Offset1 - 1_byte`. +and an `offset_value` of 3 means `Repeated_Offset1 - 1`. + +In the final case, if `Repeated_Offset1 - 1` evaluates to 0, then the +data is considered corrupted. For the first block, the starting offset history is populated with following values : `Repeated_Offset1`=1, `Repeated_Offset2`=4, `Repeated_Offset3`=8, @@ -1073,7 +1086,8 @@ It depends on : Presuming an `Accuracy_Log` of 8, and presuming 100 probabilities points have already been distributed, the decoder may read any value from `0` to `256 - 100 + 1 == 157` (inclusive). - Therefore, it must read `log2sup(157) == 8` bits. + Therefore, it may read up to `log2sup(157) == 8` bits, where `log2sup(N)` + is the smallest integer `T` that satisfies `(1 << T) > N`. - Value decoded : small values use 1 less bit : __example__ : @@ -1113,6 +1127,9 @@ When last symbol reaches cumulated total of `1 << Accuracy_Log`, decoding is complete. If the last symbol makes cumulated total go above `1 << Accuracy_Log`, distribution is considered corrupted. +If this process results in a non-zero probability for a value outside of the +valid range of values that the FSE table is defined for, even if that value is +not used, then the data is considered corrupted. Then the decoder can tell how many bytes were used in this process, and how many symbols are present. @@ -1176,9 +1193,9 @@ Baseline is assigned starting from the higher states using fewer bits, increasing at each state, then resuming at the first state, each state takes its allocated width from Baseline. -| state value | 1 | 39 | 77 | 84 | 122 | | state order | 0 | 1 | 2 | 3 | 4 | | ---------------- | ----- | ----- | ------ | ---- | ------ | +| state value | 1 | 39 | 77 | 84 | 122 | | width | 32 | 32 | 32 | 16 | 16 | | `Number_of_Bits` | 5 | 5 | 5 | 4 | 4 | | range number | 2 | 4 | 6 | 0 | 1 | @@ -1197,7 +1214,7 @@ Huffman Coding -------------- Zstandard Huffman-coded streams are read backwards, similar to the FSE bitstreams. -Therefore, to find the start of the bitstream, it is therefore to +Therefore, to find the start of the bitstream, it is required to know the offset of the last byte of the Huffman-coded stream. After writing the last bit containing information, the compressor @@ -1239,9 +1256,17 @@ Transformation from `Weight` to `Number_of_Bits` follows this formula : ``` Number_of_Bits = Weight ? (Max_Number_of_Bits + 1 - Weight) : 0 ``` -The last symbol's `Weight` is deduced from previously decoded ones, -by completing to the nearest power of 2. -This power of 2 gives `Max_Number_of_Bits`, the depth of the current tree. +When a literal value is not present, it receives a `Weight` of 0. +The least frequent symbol receives a `Weight` of 1. +If no literal has a `Weight` of 1, then the data is considered corrupted. +If there are not at least two literals with non-zero `Weight`, then the data +is considered corrupted. +The most frequent symbol receives a `Weight` anywhere between 1 and 11 (max). +The last symbol's `Weight` is deduced from previously retrieved Weights, +by completing to the nearest power of 2. It's necessarily non 0. +If it's not possible to reach a clean power of 2 with a single `Weight` value, +the Huffman Tree Description is considered invalid. +This final power of 2 gives `Max_Number_of_Bits`, the depth of the current tree. `Max_Number_of_Bits` must be <= 11, otherwise the representation is considered corrupted. @@ -1254,7 +1279,7 @@ Let's presume the following Huffman tree must be described : The tree depth is 4, since its longest elements uses 4 bits (longest elements are the one with smallest frequency). -Value `5` will not be listed, as it can be determined from values for 0-4, +Literal value `5` will not be listed, as it can be determined from previous values 0-4, nor will values above `5` as they are all 0. Values from `0` to `4` will be listed using `Weight` instead of `Number_of_Bits`. Weight formula is : @@ -1274,7 +1299,7 @@ The `Weight` of `5` can be determined by advancing to the next power of 2. The sum of `2^(Weight-1)` (excluding 0's) is : `8 + 4 + 2 + 0 + 1 = 15`. Nearest larger power of 2 value is 16. -Therefore, `Max_Number_of_Bits = 4` and `Weight[5] = 16-15 = 1`. +Therefore, `Max_Number_of_Bits = 4` and `Weight[5] = log_2(16 - 15) + 1 = 1`. #### Huffman Tree header @@ -1336,6 +1361,9 @@ If updating state after decoding a symbol would require more bits than remain in the stream, it is assumed that extra bits are 0. Then, symbols for each of the final states are decoded and the process is complete. +If this process would produce more weights than the maximum number of decoded +weights (255), then the data is considered corrupted. + #### Conversion from weights to Huffman prefix codes All present symbols shall now have a `Weight` value. @@ -1683,6 +1711,9 @@ or at least provide a meaningful error code explaining for which reason it canno Version changes --------------- +- 0.4.0 : fixed imprecise behavior for nbSeq==0, detected by Igor Pavlov +- 0.3.9 : clarifications for Huffman-compressed literal sizes. +- 0.3.8 : clarifications for Huffman Blocks and Huffman Tree descriptions. - 0.3.7 : clarifications for Repeat_Offsets, matching RFC8878 - 0.3.6 : clarifications for Dictionary_ID - 0.3.5 : clarifications for Block_Maximum_Size diff --git a/src/dependencies/zstd-1.5.4/doc/zstd_manual.html b/src/dependencies/zstd-1.5.6/doc/zstd_manual.html similarity index 92% rename from src/dependencies/zstd-1.5.4/doc/zstd_manual.html rename to src/dependencies/zstd-1.5.6/doc/zstd_manual.html index c33f0e2..bc4a240 100644 --- a/src/dependencies/zstd-1.5.4/doc/zstd_manual.html +++ b/src/dependencies/zstd-1.5.6/doc/zstd_manual.html @@ -1,10 +1,10 @@ -zstd 1.5.4 Manual +zstd 1.5.6 Manual -

zstd 1.5.4 Manual

+

zstd 1.5.6 Manual


Contents

    @@ -22,15 +22,15 @@
  1. Dictionary helper functions
  2. Advanced dictionary and prefix API (Requires v1.4.0+)
  3. experimental API (static linking only)
  4. -
  5. Frame size functions
  6. +
  7. Frame header and size functions
  8. Memory management
  9. Advanced compression functions
  10. Advanced decompression functions
  11. Advanced streaming functions
  12. -
  13. Buffer-less and synchronous inner streaming functions
  14. +
  15. Buffer-less and synchronous inner streaming functions (DEPRECATED)
  16. Buffer-less streaming compression (synchronous mode)
  17. Buffer-less streaming decompression (synchronous mode)
  18. -
  19. Block level API
  20. +
  21. Block level API (DEPRECATED)

Introduction

@@ -80,7 +80,8 @@
                 const void* src, size_t srcSize,
                       int compressionLevel);
 

Compresses `src` content as a single zstd compressed frame into already allocated `dst`. - Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`. + NOTE: Providing `dstCapacity >= ZSTD_compressBound(srcSize)` guarantees that zstd will have + enough space to successfully compress the data. @return : compressed size written into `dst` (<= `dstCapacity), or an error code if it fails (which can be tested using ZSTD_isError()).


@@ -155,7 +156,7 @@ unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize); * for example to size a static array on stack. * Will produce constant value 0 if srcSize too large. */ -#define ZSTD_MAX_INPUT_SIZE ((sizeof(size_t)==8) ? 0xFF00FF00FF00FF00LLU : 0xFF00FF00U) +#define ZSTD_MAX_INPUT_SIZE ((sizeof(size_t)==8) ? 0xFF00FF00FF00FF00ULL : 0xFF00FF00U) #define ZSTD_COMPRESSBOUND(srcSize) (((size_t)(srcSize) >= ZSTD_MAX_INPUT_SIZE) ? 0 : (srcSize) + ((srcSize)>>8) + (((srcSize) < (128<<10)) ? (((128<<10) - (srcSize)) >> 11) /* margin, from 64 to 0 */ : 0)) /* this formula ensures that bound(A) + bound(B) <= bound(A+B) as long as A and B >= 128 KB */ size_t ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case single-pass scenario */ /* ZSTD_isError() : @@ -173,7 +174,7 @@ int ZSTD_defaultCLevel(void); /*!< default compression lev

Compression context

  When compressing many times,
   it is recommended to allocate a context just once,
-  and re-use it for each successive compression operation.
+  and reuse it for each successive compression operation.
   This will make workload friendlier for system's memory.
   Note : re-using context is just a speed / resource optimization.
          It doesn't change the compression ratio, which remains identical.
@@ -189,9 +190,9 @@ size_t     ZSTD_freeCCtx(ZSTD_CCtx* cctx);  /* accept NULL pointer */
                    const void* src, size_t srcSize,
                          int compressionLevel);
 

Same as ZSTD_compress(), using an explicit ZSTD_CCtx. - Important : in order to behave similarly to `ZSTD_compress()`, - this function compresses at requested compression level, - __ignoring any other parameter__ . + Important : in order to mirror `ZSTD_compress()` behavior, + this function compresses at the requested compression level, + __ignoring any other advanced parameter__ . If any advanced parameter was set using the advanced API, they will all be reset. Only `compressionLevel` remains. @@ -199,7 +200,7 @@ size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx); /* accept NULL pointer */

Decompression context

  When decompressing many times,
   it is recommended to allocate a context only once,
-  and re-use it for each successive compression operation.
+  and reuse it for each successive compression operation.
   This will make workload friendlier for system's memory.
   Use one context per thread for parallel execution. 
 
typedef struct ZSTD_DCtx_s ZSTD_DCtx;
@@ -211,7 +212,7 @@ size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);  /* accept NULL pointer */
                      const void* src, size_t srcSize);
 

Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx. - Compatible with sticky parameters. + Compatible with sticky parameters (see below).


@@ -295,6 +296,19 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);
/* accept NULL pointer */ * The higher the value of selected strategy, the more complex it is, * resulting in stronger and slower compression. * Special: value 0 means "use default strategy". */ + + ZSTD_c_targetCBlockSize=130, /* v1.5.6+ + * Attempts to fit compressed block size into approximatively targetCBlockSize. + * Bound by ZSTD_TARGETCBLOCKSIZE_MIN and ZSTD_TARGETCBLOCKSIZE_MAX. + * Note that it's not a guarantee, just a convergence target (default:0). + * No target when targetCBlockSize == 0. + * This is helpful in low bandwidth streaming environments to improve end-to-end latency, + * when a client can make use of partial documents (a prominent example being Chrome). + * Note: this parameter is stable since v1.5.6. + * It was present as an experimental parameter in earlier versions, + * but it's not recommended using it with earlier library versions + * due to massive performance regressions. + */ /* LDM mode parameters */ ZSTD_c_enableLongDistanceMatching=160, /* Enable long distance matching. * This parameter is designed to improve compression ratio @@ -374,7 +388,6 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); /* accept NULL pointer */ * ZSTD_c_forceMaxWindow * ZSTD_c_forceAttachDict * ZSTD_c_literalCompressionMode - * ZSTD_c_targetCBlockSize * ZSTD_c_srcSizeHint * ZSTD_c_enableDedicatedDictSearch * ZSTD_c_stableInBuffer @@ -395,7 +408,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); /* accept NULL pointer */ ZSTD_c_experimentalParam3=1000, ZSTD_c_experimentalParam4=1001, ZSTD_c_experimentalParam5=1002, - ZSTD_c_experimentalParam6=1003, + /* was ZSTD_c_experimentalParam6=1003; is now ZSTD_c_targetCBlockSize */ ZSTD_c_experimentalParam7=1004, ZSTD_c_experimentalParam8=1005, ZSTD_c_experimentalParam9=1006, @@ -482,11 +495,13 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); /* accept NULL pointer */ void* dst, size_t dstCapacity, const void* src, size_t srcSize);

Behave the same as ZSTD_compressCCtx(), but compression parameters are set using the advanced API. + (note that this entry point doesn't even expose a compression level parameter). ZSTD_compress2() always starts a new frame. Should cctx hold data from a previously unfinished frame, everything about it is forgotten. - Compression parameters are pushed into CCtx before starting compression, using ZSTD_CCtx_set*() - The function is always blocking, returns when compression is completed. - Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`. + NOTE: Providing `dstCapacity >= ZSTD_compressBound(srcSize)` guarantees that zstd will have + enough space to successfully compress the data, though it is possible it fails for other reasons. @return : compressed size written into `dst` (<= `dstCapacity), or an error code if it fails (which can be tested using ZSTD_isError()). @@ -511,6 +526,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); /* accept NULL pointer */ * ZSTD_d_forceIgnoreChecksum * ZSTD_d_refMultipleDDicts * ZSTD_d_disableHuffmanAssembly + * ZSTD_d_maxBlockSize * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them. * note : never ever use experimentalParam? names directly */ @@ -518,7 +534,8 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); /* accept NULL pointer */ ZSTD_d_experimentalParam2=1001, ZSTD_d_experimentalParam3=1002, ZSTD_d_experimentalParam4=1003, - ZSTD_d_experimentalParam5=1004 + ZSTD_d_experimentalParam5=1004, + ZSTD_d_experimentalParam6=1005 } ZSTD_dParameter;


@@ -566,14 +583,14 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); /* accept NULL pointer */ A ZSTD_CStream object is required to track streaming operation. Use ZSTD_createCStream() and ZSTD_freeCStream() to create/release resources. ZSTD_CStream objects can be reused multiple times on consecutive compression operations. - It is recommended to re-use ZSTD_CStream since it will play nicer with system's memory, by re-using already allocated memory. + It is recommended to reuse ZSTD_CStream since it will play nicer with system's memory, by re-using already allocated memory. For parallel execution, use one separate ZSTD_CStream per thread. note : since v1.3.0, ZSTD_CStream and ZSTD_CCtx are the same thing. Parameters are sticky : when starting a new compression on the same context, - it will re-use the same sticky parameters as previous compression session. + it will reuse the same sticky parameters as previous compression session. When in doubt, it's recommended to fully initialize the context before usage. Use ZSTD_CCtx_reset() to reset the context and ZSTD_CCtx_setParameter(), ZSTD_CCtx_setPledgedSrcSize(), or ZSTD_CCtx_loadDictionary() and friends to @@ -664,6 +681,11 @@ size_t ZSTD_freeCStream(ZSTD_CStream* zcs); /* accept NULL pointer */ only ZSTD_e_end or ZSTD_e_flush operations are allowed. Before starting a new compression job, or changing compression parameters, it is required to fully flush internal buffers. + - note: if an operation ends with an error, it may leave @cctx in an undefined state. + Therefore, it's UB to invoke ZSTD_compressStream2() of ZSTD_compressStream() on such a state. + In order to be re-employed after an error, a state must be reset, + which can be done explicitly (ZSTD_CCtx_reset()), + or is sometimes implied by methods starting a new compression job (ZSTD_initCStream(), ZSTD_compressCCtx())


@@ -696,7 +718,7 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);

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.
+  ZSTD_DStream objects can be reused multiple times.
 
   Use ZSTD_initDStream() to start a new decompression operation.
  @return : recommended first input size
@@ -749,6 +771,12 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds);  /* accept NULL pointer */
  @return : 0 when a frame is completely decoded and fully flushed,
            or an error code, which can be tested using ZSTD_isError(),
            or any other value > 0, which means there is some decoding or flushing to do to complete current frame.
+
+ Note: when an operation returns with an error code, the @zds state may be left in undefined state.
+       It's UB to invoke `ZSTD_decompressStream()` on such a state.
+       In order to re-use such a state, it must be first reset,
+       which can be done explicitly (`ZSTD_DCtx_reset()`),
+       or is implied for operations starting some new decompression job (`ZSTD_initDStream`, `ZSTD_decompressDCtx()`, `ZSTD_decompress_usingDict()`)
  
 


@@ -866,9 +894,11 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds);
/* accept NULL pointer */

Advanced dictionary and prefix API (Requires v1.4.0+)

  This API allows dictionaries to be used with ZSTD_compress2(),
- ZSTD_compressStream2(), and ZSTD_decompressDCtx(). Dictionaries are sticky, and
- only reset with the context is reset with ZSTD_reset_parameters or
- ZSTD_reset_session_and_parameters. Prefixes are single-use.
+ ZSTD_compressStream2(), and ZSTD_decompressDCtx().
+ Dictionaries are sticky, they remain valid when same context is reused,
+ they only reset when the context is reset
+ with ZSTD_reset_parameters or ZSTD_reset_session_and_parameters.
+ In contrast, Prefixes are single-use.
 
size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
@@ -888,7 +918,11 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds);  /* accept NULL pointer */
            Use experimental ZSTD_CCtx_loadDictionary_byReference() to reference content instead.
            In such a case, dictionary buffer must outlive its users.
   Note 4 : Use ZSTD_CCtx_loadDictionary_advanced()
-           to precisely select how dictionary content must be interpreted. 
+           to precisely select how dictionary content must be interpreted.
+  Note 5 : This method does not benefit from LDM (long distance mode).
+           If you want to employ LDM on some large dictionary content,
+           prefer employing ZSTD_CCtx_refPrefix() described below.
+ 
 


size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
@@ -912,6 +946,7 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds);  /* accept NULL pointer */
   Decompression will need same prefix to properly regenerate data.
   Compressing with a prefix is similar in outcome as performing a diff and compressing it,
   but performs much faster, especially during decompression (compression speed is tunable with compression level).
+  This method is compatible with LDM (long distance mode).
  @result : 0, or an error code (which can be tested with ZSTD_isError()).
   Special: Adding any prefix (including NULL) invalidates any previous prefix or dictionary
   Note 1 : Prefix buffer is referenced. It **must** outlive compression.
@@ -1146,7 +1181,7 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
   ZSTD_ps_disable = 2       /* Do not use the feature */
 } ZSTD_paramSwitch_e;
 

-

Frame size functions


+

Frame header and size functions


 
 
ZSTDLIB_STATIC_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize);
 

`src` should point to the start of a series of ZSTD encoded and/or skippable frames @@ -1192,6 +1227,31 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict); or an error code (if srcSize is too small)


+
typedef enum { ZSTD_frame, ZSTD_skippableFrame } ZSTD_frameType_e;
+

+
typedef struct {
+    unsigned long long frameContentSize; /* if == ZSTD_CONTENTSIZE_UNKNOWN, it means this field is not available. 0 means "empty" */
+    unsigned long long windowSize;       /* can be very large, up to <= frameContentSize */
+    unsigned blockSizeMax;
+    ZSTD_frameType_e frameType;          /* if == ZSTD_skippableFrame, frameContentSize is the size of skippable content */
+    unsigned headerSize;
+    unsigned dictID;
+    unsigned checksumFlag;
+    unsigned _reserved1;
+    unsigned _reserved2;
+} ZSTD_frameHeader;
+

+
ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize);   /**< doesn't consume input */
+/*! ZSTD_getFrameHeader_advanced() :
+ *  same as ZSTD_getFrameHeader(),
+ *  with added capability to select a format (like ZSTD_f_zstd1_magicless) */
+ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format);
+

decode Frame Header, or requires larger `srcSize`. + @return : 0, `zfhPtr` is correctly filled, + >0, `srcSize` is too small, value is wanted `srcSize` amount, + or an error code, which can be tested using ZSTD_isError() +


+
ZSTDLIB_STATIC_API size_t ZSTD_decompressionMargin(const void* src, size_t srcSize);
 

Zstd supports in-place decompression, where the input and output buffers overlap. In this case, the output buffer must be at least (Margin + Output_Size) bytes large, @@ -1352,58 +1412,61 @@ ZSTD_compressSequences( ZSTD_CCtx* cctx, void* dst, size_t dstSize,

Memory management


 
-
ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize(int compressionLevel);
+
ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize(int maxCompressionLevel);
 ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams);
 ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params);
 ZSTDLIB_STATIC_API size_t ZSTD_estimateDCtxSize(void);
 

These functions make it possible to estimate memory usage of a future {D,C}Ctx, before its creation. + This is useful in combination with ZSTD_initStatic(), + which makes it possible to employ a static buffer for ZSTD_CCtx* state. ZSTD_estimateCCtxSize() will provide a memory budget large enough - for any compression level up to selected one. - Note : Unlike ZSTD_estimateCStreamSize*(), this estimate - does not include space for a window buffer. - Therefore, the estimation is only guaranteed for single-shot compressions, not streaming. + to compress data of any size using one-shot compression ZSTD_compressCCtx() or ZSTD_compress2() + associated with any compression level up to max specified one. The estimate will assume the input may be arbitrarily large, which is the worst case. + Note that the size estimation is specific for one-shot compression, + it is not valid for streaming (see ZSTD_estimateCStreamSize*()) + nor other potential ways of using a ZSTD_CCtx* state. + When srcSize can be bound by a known and rather "small" value, - this fact can be used to provide a tighter estimation - because the CCtx compression context will need less memory. - This tighter estimation can be provided by more advanced functions + this knowledge can be used to provide a tighter budget estimation + because the ZSTD_CCtx* state will need less memory for small inputs. + This tighter estimation can be provided by employing more advanced functions ZSTD_estimateCCtxSize_usingCParams(), which can be used in tandem with ZSTD_getCParams(), and ZSTD_estimateCCtxSize_usingCCtxParams(), which can be used in tandem with ZSTD_CCtxParams_setParameter(). Both can be used to estimate memory using custom compression parameters and arbitrary srcSize limits. Note : only single-threaded compression is supported. ZSTD_estimateCCtxSize_usingCCtxParams() will return an error code if ZSTD_c_nbWorkers is >= 1. - - Note 2 : ZSTD_estimateCCtxSize* functions are not compatible with the Block-Level Sequence Producer API at this time. - Size estimates assume that no external sequence producer is registered.


-
ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize(int compressionLevel);
+
ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize(int maxCompressionLevel);
 ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams);
 ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params);
-ZSTDLIB_STATIC_API size_t ZSTD_estimateDStreamSize(size_t windowSize);
+ZSTDLIB_STATIC_API size_t ZSTD_estimateDStreamSize(size_t maxWindowSize);
 ZSTDLIB_STATIC_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize);
-

ZSTD_estimateCStreamSize() will provide a budget large enough for any compression level up to selected one. - It will also consider src size to be arbitrarily "large", which is worst case. +

ZSTD_estimateCStreamSize() will provide a memory budget large enough for streaming compression + using any compression level up to the max specified one. + It will also consider src size to be arbitrarily "large", which is a worst case scenario. If srcSize is known to always be small, ZSTD_estimateCStreamSize_usingCParams() can provide a tighter estimation. ZSTD_estimateCStreamSize_usingCParams() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. ZSTD_estimateCStreamSize_usingCCtxParams() can be used in tandem with ZSTD_CCtxParams_setParameter(). Only single-threaded compression is supported. This function will return an error code if ZSTD_c_nbWorkers is >= 1. Note : CStream size estimation is only correct for single-threaded compression. - ZSTD_DStream memory budget depends on window Size. + ZSTD_estimateCStreamSize_usingCCtxParams() will return an error code if ZSTD_c_nbWorkers is >= 1. + Note 2 : ZSTD_estimateCStreamSize* functions are not compatible with the Block-Level Sequence Producer API at this time. + Size estimates assume that no external sequence producer is registered. + + ZSTD_DStream memory budget depends on frame's window Size. This information can be passed manually, using ZSTD_estimateDStreamSize, or deducted from a valid frame Header, using ZSTD_estimateDStreamSize_fromFrame(); + Any frame requesting a window size larger than max specified one will be rejected. Note : if streaming is init with function ZSTD_init?Stream_usingDict(), an internal ?Dict will be created, which additional size is not estimated here. In this case, get total size by adding ZSTD_estimate?DictSize - Note 2 : only single-threaded compression is supported. - ZSTD_estimateCStreamSize_usingCCtxParams() will return an error code if ZSTD_c_nbWorkers is >= 1. - Note 3 : ZSTD_estimateCStreamSize* functions are not compatible with the Block-Level Sequence Producer API at this time. - Size estimates assume that no external sequence producer is registered.


@@ -1505,10 +1568,24 @@ ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPo


ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setCParams(ZSTD_CCtx* cctx, ZSTD_compressionParameters cparams);
-

Set all parameters provided within @cparams into the working @cctx. +

Set all parameters provided within @p cparams into the working @p cctx. Note : if modifying parameters during compression (MT mode only), note that changes to the .windowLog parameter will be ignored. - @return 0 on success, or an error code (can be checked with ZSTD_isError()) + @return 0 on success, or an error code (can be checked with ZSTD_isError()). + On failure, no parameters are updated. + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setFParams(ZSTD_CCtx* cctx, ZSTD_frameParameters fparams);
+

Set all parameters provided within @p fparams into the working @p cctx. + @return 0 on success, or an error code (can be checked with ZSTD_isError()). + +


+ +
ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setParams(ZSTD_CCtx* cctx, ZSTD_parameters params);
+

Set all parameters provided within @p params into the working @p cctx. + @return 0 on success, or an error code (can be checked with ZSTD_isError()). +


ZSTD_DEPRECATED("use ZSTD_compress2")
@@ -1754,12 +1831,9 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
         const void* dict, size_t dictSize,
               ZSTD_parameters params,
               unsigned long long pledgedSrcSize);
-

This function is DEPRECATED, and is approximately equivalent to: +

This function is DEPRECATED, and is equivalent to: ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); - // Pseudocode: Set each zstd parameter and leave the rest as-is. - for ((param, value) : params) { - ZSTD_CCtx_setParameter(zcs, param, value); - } + ZSTD_CCtx_setParams(zcs, params); ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize); ZSTD_CCtx_loadDictionary(zcs, dict, dictSize); @@ -1788,12 +1862,9 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, ZSTD_frameParameters fParams, unsigned long long pledgedSrcSize); -

This function is DEPRECATED, and is approximately equivalent to: +

This function is DEPRECATED, and is equivalent to: ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); - // Pseudocode: Set each zstd frame parameter and leave the rest as-is. - for ((fParam, value) : fParams) { - ZSTD_CCtx_setParameter(zcs, fParam, value); - } + ZSTD_CCtx_setFParams(zcs, fParams); ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize); ZSTD_CCtx_refCDict(zcs, cdict); @@ -1815,7 +1886,7 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize); explicitly specified. start a new frame, using same parameters from previous frame. - This is typically useful to skip dictionary loading stage, since it will re-use it in-place. + This is typically useful to skip dictionary loading stage, since it will reuse it in-place. Note that zcs must be init at least once before using ZSTD_resetCStream(). If pledgedSrcSize is not known at reset time, use macro ZSTD_CONTENTSIZE_UNKNOWN. If pledgedSrcSize > 0, its value must be correct, as it will be written in header, and controlled at the end. @@ -1876,21 +1947,69 @@ ZSTDLIB_STATIC_API size_t ZSTD_resetDStream(ZSTD_DStream* zds);

ZSTD_DCtx_reset(zds, ZSTD_reset_session_only); - re-use decompression parameters from previous init; saves dictionary loading + reuse decompression parameters from previous init; saves dictionary loading


-

Buffer-less and synchronous inner streaming functions

-  This is an advanced API, giving full control over buffer management, for users which need direct control over memory.
-  But it's also a complex one, with several restrictions, documented below.
-  Prefer normal streaming API for an easier experience.
+
ZSTDLIB_STATIC_API void
+ZSTD_registerSequenceProducer(
+  ZSTD_CCtx* cctx,
+  void* sequenceProducerState,
+  ZSTD_sequenceProducer_F sequenceProducer
+);
+

Instruct zstd to use a block-level external sequence producer function. + + The sequenceProducerState must be initialized by the caller, and the caller is + responsible for managing its lifetime. This parameter is sticky across + compressions. It will remain set until the user explicitly resets compression + parameters. + + Sequence producer registration is considered to be an "advanced parameter", + part of the "advanced API". This means it will only have an effect on compression + APIs which respect advanced parameters, such as compress2() and compressStream2(). + Older compression APIs such as compressCCtx(), which predate the introduction of + "advanced parameters", will ignore any external sequence producer setting. + + The sequence producer can be "cleared" by registering a NULL function pointer. This + removes all limitations described above in the "LIMITATIONS" section of the API docs. + + The user is strongly encouraged to read the full API documentation (above) before + calling this function. +


+ +
ZSTDLIB_STATIC_API void
+ZSTD_CCtxParams_registerSequenceProducer(
+  ZSTD_CCtx_params* params,
+  void* sequenceProducerState,
+  ZSTD_sequenceProducer_F sequenceProducer
+);
+

Same as ZSTD_registerSequenceProducer(), but operates on ZSTD_CCtx_params. + This is used for accurate size estimation with ZSTD_estimateCCtxSize_usingCCtxParams(), + which is needed when creating a ZSTD_CCtx with ZSTD_initStaticCCtx(). + + If you are using the external sequence producer API in a scenario where ZSTD_initStaticCCtx() + is required, then this function is for you. Otherwise, you probably don't need it. + + See tests/zstreamtest.c for example usage. +


+ +

Buffer-less and synchronous inner streaming functions (DEPRECATED)

+  This API is deprecated, and will be removed in a future version.
+  It allows streaming (de)compression with user allocated buffers.
+  However, it is hard to use, and not as well tested as the rest of
+  our API.
+
+  Please use the normal streaming API instead: ZSTD_compressStream2,
+  and ZSTD_decompressStream.
+  If there is functionality that you need, but it doesn't provide,
+  please open an issue on our GitHub.
  
 

Buffer-less streaming compression (synchronous mode)

   A ZSTD_CCtx object is required to track streaming operations.
   Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource.
-  ZSTD_CCtx object can be re-used multiple times within successive compression operations.
+  ZSTD_CCtx object can be reused multiple times within successive compression operations.
 
   Start by initializing a context.
   Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression.
@@ -1911,11 +2030,14 @@ ZSTDLIB_STATIC_API size_t ZSTD_resetDStream(ZSTD_DStream* zds);
   It's possible to use srcSize==0, in which case, it will write a final empty block to end the frame.
   Without last block mark, frames are considered unfinished (hence corrupted) by compliant decoders.
 
-  `ZSTD_CCtx` object can be re-used (ZSTD_compressBegin()) to compress again.
+  `ZSTD_CCtx` object can be reused (ZSTD_compressBegin()) to compress again.
 
-

Buffer-less streaming compression functions

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

Buffer-less streaming compression functions

ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.")
+ZSTDLIB_STATIC_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
+ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.")
 ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
+ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.")
 ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */
 

size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**<  note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */
@@ -1925,7 +2047,7 @@ ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const Z
 

Buffer-less streaming decompression (synchronous mode)

   A ZSTD_DCtx object is required to track streaming operations.
   Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
-  A ZSTD_DCtx object can be re-used multiple times.
+  A ZSTD_DCtx object can be reused multiple times.
 
   First typical operation is to retrieve frame parameters, using ZSTD_getFrameHeader().
   Frame header is extracted from the beginning of compressed frame, so providing only the frame's beginning is enough.
@@ -1993,36 +2115,25 @@ ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const Z
   For skippable frames ZSTD_decompressContinue() always returns 0 : it only skips the content.
 
-

Buffer-less streaming decompression functions

typedef enum { ZSTD_frame, ZSTD_skippableFrame } ZSTD_frameType_e;
-typedef struct {
-    unsigned long long frameContentSize; /* if == ZSTD_CONTENTSIZE_UNKNOWN, it means this field is not available. 0 means "empty" */
-    unsigned long long windowSize;       /* can be very large, up to <= frameContentSize */
-    unsigned blockSizeMax;
-    ZSTD_frameType_e frameType;          /* if == ZSTD_skippableFrame, frameContentSize is the size of skippable content */
-    unsigned headerSize;
-    unsigned dictID;
-    unsigned checksumFlag;
-    unsigned _reserved1;
-    unsigned _reserved2;
-} ZSTD_frameHeader;
-

-
ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize);   /**< doesn't consume input */
-/*! ZSTD_getFrameHeader_advanced() :
- *  same as ZSTD_getFrameHeader(),
- *  with added capability to select a format (like ZSTD_f_zstd1_magicless) */
-ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format);
-ZSTDLIB_STATIC_API size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize);  /**< when frame content size is not known, pass in frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN */
-

decode Frame Header, or requires larger `srcSize`. - @return : 0, `zfhPtr` is correctly filled, - >0, `srcSize` is too small, value is wanted `srcSize` amount, - or an error code, which can be tested using ZSTD_isError() -


- +

Buffer-less streaming decompression functions


+
ZSTDLIB_STATIC_API size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize);  /**< when frame content size is not known, pass in frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN */
+

typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
 

-

Block level API


+

Block level API (DEPRECATED)


 
-

Frame metadata cost is typically ~12 bytes, which can be non-negligible for very small blocks (< 100 bytes). +

You can get the frame header down to 2 bytes by setting: + - ZSTD_c_format = ZSTD_f_zstd1_magicless + - ZSTD_c_contentSizeFlag = 0 + - ZSTD_c_checksumFlag = 0 + - ZSTD_c_dictIDFlag = 0 + + This API is not as well tested as our normal API, so we recommend not using it. + We will be removing it in a future version. If the normal API doesn't provide + the functionality you need, please open a GitHub issue. + + Block functions produce and decode raw zstd blocks, without frame metadata. + Frame metadata cost is typically ~12 bytes, which can be non-negligible for very small blocks (< 100 bytes). But users will have to take in charge needed metadata to regenerate data, such as compressed and content sizes. A few rules to respect : @@ -2046,36 +2157,14 @@ ZSTDLIB_STATIC_API size_t ZSTD_decodingBufferSize_min(unsigned long long windowS Use ZSTD_insertBlock() for such a case.


-

Raw zstd block functions

ZSTDLIB_STATIC_API size_t ZSTD_getBlockSize   (const ZSTD_CCtx* cctx);
+

Raw zstd block functions

ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.")
+ZSTDLIB_STATIC_API size_t ZSTD_getBlockSize   (const ZSTD_CCtx* cctx);
+ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.")
 ZSTDLIB_STATIC_API size_t ZSTD_compressBlock  (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.")
 ZSTDLIB_STATIC_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.")
 ZSTDLIB_STATIC_API size_t ZSTD_insertBlock    (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize);  /**< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */
 

-
ZSTDLIB_STATIC_API void
-ZSTD_registerSequenceProducer(
-  ZSTD_CCtx* cctx,
-  void* sequenceProducerState,
-  ZSTD_sequenceProducer_F* sequenceProducer
-);
-

Instruct zstd to use a block-level external sequence producer function. - - The sequenceProducerState must be initialized by the caller, and the caller is - responsible for managing its lifetime. This parameter is sticky across - compressions. It will remain set until the user explicitly resets compression - parameters. - - Sequence producer registration is considered to be an "advanced parameter", - part of the "advanced API". This means it will only have an effect on compression - APIs which respect advanced parameters, such as compress2() and compressStream2(). - Older compression APIs such as compressCCtx(), which predate the introduction of - "advanced parameters", will ignore any external sequence producer setting. - - The sequence producer can be "cleared" by registering a NULL function pointer. This - removes all limitations described above in the "LIMITATIONS" section of the API docs. - - The user is strongly encouraged to read the full API documentation (above) before - calling this function. -


- diff --git a/src/dependencies/zstd-1.5.4/examples/.gitignore b/src/dependencies/zstd-1.5.6/examples/.gitignore similarity index 100% rename from src/dependencies/zstd-1.5.4/examples/.gitignore rename to src/dependencies/zstd-1.5.6/examples/.gitignore diff --git a/src/dependencies/zstd-1.5.4/examples/Makefile b/src/dependencies/zstd-1.5.6/examples/Makefile similarity index 100% rename from src/dependencies/zstd-1.5.4/examples/Makefile rename to src/dependencies/zstd-1.5.6/examples/Makefile diff --git a/src/dependencies/zstd-1.5.4/examples/README.md b/src/dependencies/zstd-1.5.6/examples/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/examples/README.md rename to src/dependencies/zstd-1.5.6/examples/README.md diff --git a/src/dependencies/zstd-1.5.4/examples/common.h b/src/dependencies/zstd-1.5.6/examples/common.h similarity index 100% rename from src/dependencies/zstd-1.5.4/examples/common.h rename to src/dependencies/zstd-1.5.6/examples/common.h diff --git a/src/dependencies/zstd-1.5.4/examples/dictionary_compression.c b/src/dependencies/zstd-1.5.6/examples/dictionary_compression.c similarity index 100% rename from src/dependencies/zstd-1.5.4/examples/dictionary_compression.c rename to src/dependencies/zstd-1.5.6/examples/dictionary_compression.c diff --git a/src/dependencies/zstd-1.5.4/examples/dictionary_decompression.c b/src/dependencies/zstd-1.5.6/examples/dictionary_decompression.c similarity index 100% rename from src/dependencies/zstd-1.5.4/examples/dictionary_decompression.c rename to src/dependencies/zstd-1.5.6/examples/dictionary_decompression.c diff --git a/src/dependencies/zstd-1.5.4/examples/multiple_simple_compression.c b/src/dependencies/zstd-1.5.6/examples/multiple_simple_compression.c similarity index 100% rename from src/dependencies/zstd-1.5.4/examples/multiple_simple_compression.c rename to src/dependencies/zstd-1.5.6/examples/multiple_simple_compression.c diff --git a/src/dependencies/zstd-1.5.4/examples/multiple_streaming_compression.c b/src/dependencies/zstd-1.5.6/examples/multiple_streaming_compression.c similarity index 100% rename from src/dependencies/zstd-1.5.4/examples/multiple_streaming_compression.c rename to src/dependencies/zstd-1.5.6/examples/multiple_streaming_compression.c diff --git a/src/dependencies/zstd-1.5.4/examples/simple_compression.c b/src/dependencies/zstd-1.5.6/examples/simple_compression.c similarity index 100% rename from src/dependencies/zstd-1.5.4/examples/simple_compression.c rename to src/dependencies/zstd-1.5.6/examples/simple_compression.c diff --git a/src/dependencies/zstd-1.5.4/examples/simple_decompression.c b/src/dependencies/zstd-1.5.6/examples/simple_decompression.c similarity index 100% rename from src/dependencies/zstd-1.5.4/examples/simple_decompression.c rename to src/dependencies/zstd-1.5.6/examples/simple_decompression.c diff --git a/src/dependencies/zstd-1.5.4/examples/streaming_compression.c b/src/dependencies/zstd-1.5.6/examples/streaming_compression.c similarity index 93% rename from src/dependencies/zstd-1.5.4/examples/streaming_compression.c rename to src/dependencies/zstd-1.5.6/examples/streaming_compression.c index ed0a3a6..063aa82 100644 --- a/src/dependencies/zstd-1.5.4/examples/streaming_compression.c +++ b/src/dependencies/zstd-1.5.6/examples/streaming_compression.c @@ -42,7 +42,13 @@ static void compressFile_orDie(const char* fname, const char* outName, int cLeve */ CHECK_ZSTD( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, cLevel) ); CHECK_ZSTD( ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1) ); - ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, nbThreads); + if (nbThreads > 1) { + size_t const r = ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, nbThreads); + if (ZSTD_isError(r)) { + fprintf (stderr, "Note: the linked libzstd library doesn't support multithreading. " + "Reverting to single-thread mode. \n"); + } + } /* This loop read from the input file, compresses that entire chunk, * and writes all output produced to the output file. @@ -117,7 +123,7 @@ int main(int argc, const char** argv) } int cLevel = 1; - int nbThreads = 4; + int nbThreads = 1; if (argc >= 3) { cLevel = atoi (argv[2]); diff --git a/src/dependencies/zstd-1.5.4/examples/streaming_compression_thread_pool.c b/src/dependencies/zstd-1.5.6/examples/streaming_compression_thread_pool.c similarity index 100% rename from src/dependencies/zstd-1.5.4/examples/streaming_compression_thread_pool.c rename to src/dependencies/zstd-1.5.6/examples/streaming_compression_thread_pool.c diff --git a/src/dependencies/zstd-1.5.4/examples/streaming_decompression.c b/src/dependencies/zstd-1.5.6/examples/streaming_decompression.c similarity index 100% rename from src/dependencies/zstd-1.5.4/examples/streaming_decompression.c rename to src/dependencies/zstd-1.5.6/examples/streaming_decompression.c diff --git a/src/dependencies/zstd-1.5.4/examples/streaming_memory_usage.c b/src/dependencies/zstd-1.5.6/examples/streaming_memory_usage.c similarity index 100% rename from src/dependencies/zstd-1.5.4/examples/streaming_memory_usage.c rename to src/dependencies/zstd-1.5.6/examples/streaming_memory_usage.c diff --git a/src/dependencies/zstd-1.5.4/lib/.gitignore b/src/dependencies/zstd-1.5.6/lib/.gitignore similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/.gitignore rename to src/dependencies/zstd-1.5.6/lib/.gitignore diff --git a/src/dependencies/zstd-1.5.4/lib/BUCK b/src/dependencies/zstd-1.5.6/lib/BUCK similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/BUCK rename to src/dependencies/zstd-1.5.6/lib/BUCK diff --git a/src/dependencies/zstd-1.5.4/lib/Makefile b/src/dependencies/zstd-1.5.6/lib/Makefile similarity index 83% rename from src/dependencies/zstd-1.5.4/lib/Makefile rename to src/dependencies/zstd-1.5.6/lib/Makefile index a4cf61a..8bfdade 100644 --- a/src/dependencies/zstd-1.5.4/lib/Makefile +++ b/src/dependencies/zstd-1.5.6/lib/Makefile @@ -8,6 +8,9 @@ # You may select, at your option, one of the above-listed licenses. # ################################################################ +# default target (when running `make` with no argument) +lib-release: + # Modules ZSTD_LIB_COMPRESSION ?= 1 ZSTD_LIB_DECOMPRESSION ?= 1 @@ -54,12 +57,11 @@ VERSION := $(ZSTD_VERSION) # Note: by default, the static library is built single-threaded and dynamic library is built # multi-threaded. It is possible to force multi or single threaded builds by appending # -mt or -nomt to the build target (like lib-mt for multi-threaded, lib-nomt for single-threaded). -.PHONY: default -default: lib-release + CPPFLAGS_DYNLIB += -DZSTD_MULTITHREAD # dynamic library build defaults to multi-threaded LDFLAGS_DYNLIB += -pthread -CPPFLAGS_STATLIB += # static library build defaults to single-threaded +CPPFLAGS_STATICLIB += # static library build defaults to single-threaded ifeq ($(findstring GCC,$(CCVER)),GCC) @@ -91,7 +93,7 @@ all: lib .PHONY: libzstd.a # must be run every time -libzstd.a: CPPFLAGS += $(CPPFLAGS_STATLIB) +libzstd.a: CPPFLAGS += $(CPPFLAGS_STATICLIB) SET_CACHE_DIRECTORY = \ +$(MAKE) --no-print-directory $@ \ @@ -109,19 +111,19 @@ libzstd.a: else # BUILD_DIR is defined -ZSTD_STATLIB_DIR := $(BUILD_DIR)/static -ZSTD_STATLIB := $(ZSTD_STATLIB_DIR)/libzstd.a -ZSTD_STATLIB_OBJ := $(addprefix $(ZSTD_STATLIB_DIR)/,$(ZSTD_LOCAL_OBJ)) -$(ZSTD_STATLIB): ARFLAGS = rcs -$(ZSTD_STATLIB): | $(ZSTD_STATLIB_DIR) -$(ZSTD_STATLIB): $(ZSTD_STATLIB_OBJ) +ZSTD_STATICLIB_DIR := $(BUILD_DIR)/static +ZSTD_STATICLIB := $(ZSTD_STATICLIB_DIR)/libzstd.a +ZSTD_STATICLIB_OBJ := $(addprefix $(ZSTD_STATICLIB_DIR)/,$(ZSTD_LOCAL_OBJ)) +$(ZSTD_STATICLIB): ARFLAGS = rcs +$(ZSTD_STATICLIB): | $(ZSTD_STATICLIB_DIR) +$(ZSTD_STATICLIB): $(ZSTD_STATICLIB_OBJ) # Check for multithread flag at target execution time $(if $(filter -DZSTD_MULTITHREAD,$(CPPFLAGS)),\ @echo compiling multi-threaded static library $(LIBVER),\ @echo compiling single-threaded static library $(LIBVER)) $(AR) $(ARFLAGS) $@ $^ -libzstd.a: $(ZSTD_STATLIB) +libzstd.a: $(ZSTD_STATICLIB) cp -f $< $@ endif @@ -182,14 +184,14 @@ lib : libzstd.a libzstd # make does not consider implicit pattern rule for .PHONY target %-mt : CPPFLAGS_DYNLIB := -DZSTD_MULTITHREAD -%-mt : CPPFLAGS_STATLIB := -DZSTD_MULTITHREAD +%-mt : CPPFLAGS_STATICLIB := -DZSTD_MULTITHREAD %-mt : LDFLAGS_DYNLIB := -pthread %-mt : % @echo multi-threaded build completed %-nomt : CPPFLAGS_DYNLIB := %-nomt : LDFLAGS_DYNLIB := -%-nomt : CPPFLAGS_STATLIB := +%-nomt : CPPFLAGS_STATICLIB := %-nomt : % @echo single-threaded build completed @@ -200,42 +202,52 @@ lib : libzstd.a libzstd # Generate .h dependencies automatically -DEPFLAGS = -MT $@ -MMD -MP -MF +# -MMD: compiler generates dependency information as a side-effect of compilation, without system headers +# -MP: adds phony target for each dependency other than main file. +DEPFLAGS = -MMD -MP -$(ZSTD_DYNLIB_DIR)/%.o : %.c $(ZSTD_DYNLIB_DIR)/%.d | $(ZSTD_DYNLIB_DIR) +# ensure that ZSTD_DYNLIB_DIR exists prior to generating %.o +$(ZSTD_DYNLIB_DIR)/%.o : %.c | $(ZSTD_DYNLIB_DIR) @echo CC $@ - $(COMPILE.c) $(DEPFLAGS) $(ZSTD_DYNLIB_DIR)/$*.d $(OUTPUT_OPTION) $< + $(COMPILE.c) $(DEPFLAGS) $(OUTPUT_OPTION) $< -$(ZSTD_STATLIB_DIR)/%.o : %.c $(ZSTD_STATLIB_DIR)/%.d | $(ZSTD_STATLIB_DIR) +$(ZSTD_STATICLIB_DIR)/%.o : %.c | $(ZSTD_STATICLIB_DIR) @echo CC $@ - $(COMPILE.c) $(DEPFLAGS) $(ZSTD_STATLIB_DIR)/$*.d $(OUTPUT_OPTION) $< + $(COMPILE.c) $(DEPFLAGS) $(OUTPUT_OPTION) $< $(ZSTD_DYNLIB_DIR)/%.o : %.S | $(ZSTD_DYNLIB_DIR) @echo AS $@ $(COMPILE.S) $(OUTPUT_OPTION) $< -$(ZSTD_STATLIB_DIR)/%.o : %.S | $(ZSTD_STATLIB_DIR) +$(ZSTD_STATICLIB_DIR)/%.o : %.S | $(ZSTD_STATICLIB_DIR) @echo AS $@ $(COMPILE.S) $(OUTPUT_OPTION) $< -MKDIR ?= mkdir -$(BUILD_DIR) $(ZSTD_DYNLIB_DIR) $(ZSTD_STATLIB_DIR): - $(MKDIR) -p $@ +MKDIR ?= mkdir -p +$(BUILD_DIR) $(ZSTD_DYNLIB_DIR) $(ZSTD_STATICLIB_DIR): + $(MKDIR) $@ -DEPFILES := $(ZSTD_DYNLIB_OBJ:.o=.d) $(ZSTD_STATLIB_OBJ:.o=.d) +DEPFILES := $(ZSTD_DYNLIB_OBJ:.o=.d) $(ZSTD_STATICLIB_OBJ:.o=.d) $(DEPFILES): -include $(wildcard $(DEPFILES)) +# The leading '-' means: do not fail is include fails (ex: directory does not exist yet) +-include $(wildcard $(DEPFILES)) -# Special case : building library in single-thread mode _and_ without zstdmt_compress.c -ZSTDMT_FILES = compress/zstdmt_compress.c -ZSTD_NOMT_FILES = $(filter-out $(ZSTDMT_FILES),$(ZSTD_FILES)) +# Special case : build library in single-thread mode _and_ without zstdmt_compress.c +# Note : we still need threading.c and pool.c for the dictionary builder, +# but they will correctly behave single-threaded. +ZSTDMT_FILES = zstdmt_compress.c +ZSTD_NOMT_FILES = $(filter-out $(ZSTDMT_FILES),$(notdir $(ZSTD_FILES))) libzstd-nomt: CFLAGS += -fPIC -fvisibility=hidden libzstd-nomt: LDFLAGS += -shared libzstd-nomt: $(ZSTD_NOMT_FILES) @echo compiling single-thread dynamic library $(LIBVER) @echo files : $(ZSTD_NOMT_FILES) + @if echo "$(ZSTD_NOMT_FILES)" | tr ' ' '\n' | $(GREP) -q zstdmt; then \ + echo "Error: Found zstdmt in list."; \ + exit 1; \ + fi $(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@ .PHONY: clean @@ -249,7 +261,7 @@ clean: #----------------------------------------------------------------------------- # make install is validated only for below listed environments #----------------------------------------------------------------------------- -ifneq (,$(filter $(UNAME),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku AIX)) +ifneq (,$(filter $(UNAME),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku AIX MSYS_NT CYGWIN_NT)) lib: libzstd.pc diff --git a/src/dependencies/zstd-1.5.4/lib/README.md b/src/dependencies/zstd-1.5.6/lib/README.md similarity index 93% rename from src/dependencies/zstd-1.5.4/lib/README.md rename to src/dependencies/zstd-1.5.6/lib/README.md index c3b5d18..a560f06 100644 --- a/src/dependencies/zstd-1.5.4/lib/README.md +++ b/src/dependencies/zstd-1.5.6/lib/README.md @@ -88,7 +88,7 @@ The file structure is designed to make this selection manually achievable for an For example, advanced API for version `v0.4` is exposed in `lib/legacy/zstd_v04.h` . - While invoking `make libzstd`, it's possible to define build macros - `ZSTD_LIB_COMPRESSION, ZSTD_LIB_DECOMPRESSION`, `ZSTD_LIB_DICTBUILDER`, + `ZSTD_LIB_COMPRESSION`, `ZSTD_LIB_DECOMPRESSION`, `ZSTD_LIB_DICTBUILDER`, and `ZSTD_LIB_DEPRECATED` as `0` to forgo compilation of the corresponding features. This will also disable compilation of all dependencies (e.g. `ZSTD_LIB_COMPRESSION=0` will also disable @@ -119,6 +119,15 @@ The file structure is designed to make this selection manually achievable for an binary is achieved by using `HUF_FORCE_DECOMPRESS_X1` and `ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT` (implied by `ZSTD_LIB_MINIFY`). + On the compressor side, Zstd's compression levels map to several internal + strategies. In environments where the higher compression levels aren't used, + it is possible to exclude all but the fastest strategy with + `ZSTD_LIB_EXCLUDE_COMPRESSORS_DFAST_AND_UP=1`. (Note that this will change + the behavior of the default compression level.) Or if you want to retain the + default compressor as well, you can set + `ZSTD_LIB_EXCLUDE_COMPRESSORS_GREEDY_AND_UP=1`, at the cost of an additional + ~20KB or so. + For squeezing the last ounce of size out, you can also define `ZSTD_NO_INLINE`, which disables inlining, and `ZSTD_STRIP_ERROR_STRINGS`, which removes the error messages that are otherwise returned by @@ -169,6 +178,10 @@ The file structure is designed to make this selection manually achievable for an `ZSTDERRORLIB_VSIBILITY`, and `ZDICTLIB_VISIBILITY` if unset, for backwards compatibility with the old macro names. +- The C compiler macro `HUF_DISABLE_FAST_DECODE` disables the newer Huffman fast C + and assembly decoding loops. You may want to use this macro if these loops are + slower on your platform. + #### Windows : using MinGW+MSYS to create DLL DLL can be created using MinGW+MSYS with the `make libzstd` command. diff --git a/src/dependencies/zstd-1.5.6/lib/common/allocations.h b/src/dependencies/zstd-1.5.6/lib/common/allocations.h new file mode 100644 index 0000000..5e89955 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/lib/common/allocations.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* This file provides custom allocation primitives + */ + +#define ZSTD_DEPS_NEED_MALLOC +#include "zstd_deps.h" /* ZSTD_malloc, ZSTD_calloc, ZSTD_free, ZSTD_memset */ + +#include "compiler.h" /* MEM_STATIC */ +#define ZSTD_STATIC_LINKING_ONLY +#include "../zstd.h" /* ZSTD_customMem */ + +#ifndef ZSTD_ALLOCATIONS_H +#define ZSTD_ALLOCATIONS_H + +/* custom memory allocation functions */ + +MEM_STATIC void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem) +{ + if (customMem.customAlloc) + return customMem.customAlloc(customMem.opaque, size); + return ZSTD_malloc(size); +} + +MEM_STATIC void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem) +{ + if (customMem.customAlloc) { + /* calloc implemented as malloc+memset; + * not as efficient as calloc, but next best guess for custom malloc */ + void* const ptr = customMem.customAlloc(customMem.opaque, size); + ZSTD_memset(ptr, 0, size); + return ptr; + } + return ZSTD_calloc(1, size); +} + +MEM_STATIC void ZSTD_customFree(void* ptr, ZSTD_customMem customMem) +{ + if (ptr!=NULL) { + if (customMem.customFree) + customMem.customFree(customMem.opaque, ptr); + else + ZSTD_free(ptr); + } +} + +#endif /* ZSTD_ALLOCATIONS_H */ diff --git a/src/dependencies/zstd-1.5.4/lib/common/bits.h b/src/dependencies/zstd-1.5.6/lib/common/bits.h similarity index 82% rename from src/dependencies/zstd-1.5.4/lib/common/bits.h rename to src/dependencies/zstd-1.5.6/lib/common/bits.h index 7939f3d..def56c4 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/bits.h +++ b/src/dependencies/zstd-1.5.6/lib/common/bits.h @@ -17,7 +17,7 @@ MEM_STATIC unsigned ZSTD_countTrailingZeros32_fallback(U32 val) { assert(val != 0); { - static const int DeBruijnBytePos[32] = {0, 1, 28, 2, 29, 14, 24, 3, + static const U32 DeBruijnBytePos[32] = {0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9}; @@ -30,7 +30,7 @@ MEM_STATIC unsigned ZSTD_countTrailingZeros32(U32 val) assert(val != 0); # if defined(_MSC_VER) # if STATIC_BMI2 == 1 - return _tzcnt_u32(val); + return (unsigned)_tzcnt_u32(val); # else if (val != 0) { unsigned long r; @@ -69,7 +69,7 @@ MEM_STATIC unsigned ZSTD_countLeadingZeros32(U32 val) assert(val != 0); # if defined(_MSC_VER) # if STATIC_BMI2 == 1 - return _lzcnt_u32(val); + return (unsigned)_lzcnt_u32(val); # else if (val != 0) { unsigned long r; @@ -92,7 +92,7 @@ MEM_STATIC unsigned ZSTD_countTrailingZeros64(U64 val) assert(val != 0); # if defined(_MSC_VER) && defined(_WIN64) # if STATIC_BMI2 == 1 - return _tzcnt_u64(val); + return (unsigned)_tzcnt_u64(val); # else if (val != 0) { unsigned long r; @@ -123,7 +123,7 @@ MEM_STATIC unsigned ZSTD_countLeadingZeros64(U64 val) assert(val != 0); # if defined(_MSC_VER) && defined(_WIN64) # if STATIC_BMI2 == 1 - return _lzcnt_u64(val); + return (unsigned)_lzcnt_u64(val); # else if (val != 0) { unsigned long r; @@ -172,4 +172,29 @@ MEM_STATIC unsigned ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCo return 31 - ZSTD_countLeadingZeros32(val); } +/* ZSTD_rotateRight_*(): + * Rotates a bitfield to the right by "count" bits. + * https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts + */ +MEM_STATIC +U64 ZSTD_rotateRight_U64(U64 const value, U32 count) { + assert(count < 64); + count &= 0x3F; /* for fickle pattern recognition */ + return (value >> count) | (U64)(value << ((0U - count) & 0x3F)); +} + +MEM_STATIC +U32 ZSTD_rotateRight_U32(U32 const value, U32 count) { + assert(count < 32); + count &= 0x1F; /* for fickle pattern recognition */ + return (value >> count) | (U32)(value << ((0U - count) & 0x1F)); +} + +MEM_STATIC +U16 ZSTD_rotateRight_U16(U16 const value, U32 count) { + assert(count < 16); + count &= 0x0F; /* for fickle pattern recognition */ + return (value >> count) | (U16)(value << ((0U - count) & 0x0F)); +} + #endif /* ZSTD_BITS_H */ diff --git a/src/dependencies/zstd-1.5.4/lib/common/bitstream.h b/src/dependencies/zstd-1.5.6/lib/common/bitstream.h similarity index 84% rename from src/dependencies/zstd-1.5.4/lib/common/bitstream.h rename to src/dependencies/zstd-1.5.6/lib/common/bitstream.h index db1b4cf..6760449 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/bitstream.h +++ b/src/dependencies/zstd-1.5.6/lib/common/bitstream.h @@ -90,19 +90,20 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC); /*-******************************************** * bitStream decoding API (read backward) **********************************************/ +typedef size_t BitContainerType; typedef struct { - size_t bitContainer; + BitContainerType bitContainer; unsigned bitsConsumed; const char* ptr; const char* start; const char* limitPtr; } BIT_DStream_t; -typedef enum { BIT_DStream_unfinished = 0, - BIT_DStream_endOfBuffer = 1, - BIT_DStream_completed = 2, - BIT_DStream_overflow = 3 } BIT_DStream_status; /* result of BIT_reloadDStream() */ - /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */ +typedef enum { BIT_DStream_unfinished = 0, /* fully refilled */ + BIT_DStream_endOfBuffer = 1, /* still some bits left in bitstream */ + BIT_DStream_completed = 2, /* bitstream entirely consumed, bit-exact */ + BIT_DStream_overflow = 3 /* user requested more bits than present in bitstream */ + } BIT_DStream_status; /* result of BIT_reloadDStream() */ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize); MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits); @@ -112,7 +113,7 @@ MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD); /* Start by invoking BIT_initDStream(). * A chunk of the bitStream is then stored into a local register. -* Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t). +* Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (BitContainerType). * You can then retrieve bitFields stored into the local register, **in reverse order**. * Local register is explicitly reloaded from memory by the BIT_reloadDStream() method. * A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished. @@ -162,7 +163,7 @@ MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, return 0; } -MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits) +FORCE_INLINE_TEMPLATE size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits) { #if defined(STATIC_BMI2) && STATIC_BMI2 == 1 && !defined(ZSTD_NO_INTRINSICS) return _bzhi_u64(bitContainer, nbBits); @@ -267,22 +268,22 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si bitD->bitContainer = *(const BYTE*)(bitD->start); switch(srcSize) { - case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16); + case 7: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16); ZSTD_FALLTHROUGH; - case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24); + case 6: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24); ZSTD_FALLTHROUGH; - case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32); + case 5: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32); ZSTD_FALLTHROUGH; - case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24; + case 4: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[3]) << 24; ZSTD_FALLTHROUGH; - case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16; + case 3: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[2]) << 16; ZSTD_FALLTHROUGH; - case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8; + case 2: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[1]) << 8; ZSTD_FALLTHROUGH; default: break; @@ -297,12 +298,12 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si return srcSize; } -MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getUpperBits(size_t bitContainer, U32 const start) +FORCE_INLINE_TEMPLATE size_t BIT_getUpperBits(BitContainerType bitContainer, U32 const start) { return bitContainer >> start; } -MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits) +FORCE_INLINE_TEMPLATE size_t BIT_getMiddleBits(BitContainerType bitContainer, U32 const start, U32 const nbBits) { U32 const regMask = sizeof(bitContainer)*8 - 1; /* if start > regMask, bitstream is corrupted, and result is undefined */ @@ -325,7 +326,7 @@ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 c * On 32-bits, maxNbBits==24. * On 64-bits, maxNbBits==56. * @return : value extracted */ -MEM_STATIC FORCE_INLINE_ATTR size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits) +FORCE_INLINE_TEMPLATE size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits) { /* arbitrate between double-shift and shift+mask */ #if 1 @@ -348,7 +349,7 @@ MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits) return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask); } -MEM_STATIC FORCE_INLINE_ATTR void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits) +FORCE_INLINE_TEMPLATE void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits) { bitD->bitsConsumed += nbBits; } @@ -357,7 +358,7 @@ MEM_STATIC FORCE_INLINE_ATTR void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits) * Read (consume) next n bits from local register and update. * Pay attention to not read more than nbBits contained into local register. * @return : extracted value. */ -MEM_STATIC FORCE_INLINE_ATTR size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits) +FORCE_INLINE_TEMPLATE size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits) { size_t const value = BIT_lookBits(bitD, nbBits); BIT_skipBits(bitD, nbBits); @@ -374,6 +375,21 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits) return value; } +/*! BIT_reloadDStream_internal() : + * Simple variant of BIT_reloadDStream(), with two conditions: + * 1. bitstream is valid : bitsConsumed <= sizeof(bitD->bitContainer)*8 + * 2. look window is valid after shifted down : bitD->ptr >= bitD->start + */ +MEM_STATIC BIT_DStream_status BIT_reloadDStream_internal(BIT_DStream_t* bitD) +{ + assert(bitD->bitsConsumed <= sizeof(bitD->bitContainer)*8); + bitD->ptr -= bitD->bitsConsumed >> 3; + assert(bitD->ptr >= bitD->start); + bitD->bitsConsumed &= 7; + bitD->bitContainer = MEM_readLEST(bitD->ptr); + return BIT_DStream_unfinished; +} + /*! BIT_reloadDStreamFast() : * Similar to BIT_reloadDStream(), but with two differences: * 1. bitsConsumed <= sizeof(bitD->bitContainer)*8 must hold! @@ -384,31 +400,35 @@ MEM_STATIC BIT_DStream_status BIT_reloadDStreamFast(BIT_DStream_t* bitD) { if (UNLIKELY(bitD->ptr < bitD->limitPtr)) return BIT_DStream_overflow; - assert(bitD->bitsConsumed <= sizeof(bitD->bitContainer)*8); - bitD->ptr -= bitD->bitsConsumed >> 3; - bitD->bitsConsumed &= 7; - bitD->bitContainer = MEM_readLEST(bitD->ptr); - return BIT_DStream_unfinished; + return BIT_reloadDStream_internal(bitD); } /*! BIT_reloadDStream() : * Refill `bitD` from buffer previously set in BIT_initDStream() . - * This function is safe, it guarantees it will not read beyond src buffer. + * This function is safe, it guarantees it will not never beyond src buffer. * @return : status of `BIT_DStream_t` internal register. * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */ -MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD) +FORCE_INLINE_TEMPLATE BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD) { - if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */ + /* note : once in overflow mode, a bitstream remains in this mode until it's reset */ + if (UNLIKELY(bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8))) { + static const BitContainerType zeroFilled = 0; + bitD->ptr = (const char*)&zeroFilled; /* aliasing is allowed for char */ + /* overflow detected, erroneous scenario or end of stream: no update */ return BIT_DStream_overflow; + } + + assert(bitD->ptr >= bitD->start); if (bitD->ptr >= bitD->limitPtr) { - return BIT_reloadDStreamFast(bitD); + return BIT_reloadDStream_internal(bitD); } if (bitD->ptr == bitD->start) { + /* reached end of bitStream => no update */ if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer; return BIT_DStream_completed; } - /* start < ptr < limitPtr */ + /* start < ptr < limitPtr => cautious update */ { U32 nbBytes = bitD->bitsConsumed >> 3; BIT_DStream_status result = BIT_DStream_unfinished; if (bitD->ptr - nbBytes < bitD->start) { diff --git a/src/dependencies/zstd-1.5.4/lib/common/compiler.h b/src/dependencies/zstd-1.5.6/lib/common/compiler.h similarity index 73% rename from src/dependencies/zstd-1.5.4/lib/common/compiler.h rename to src/dependencies/zstd-1.5.6/lib/common/compiler.h index d4f2f28..31880ec 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/compiler.h +++ b/src/dependencies/zstd-1.5.6/lib/common/compiler.h @@ -11,6 +11,8 @@ #ifndef ZSTD_COMPILER_H #define ZSTD_COMPILER_H +#include + #include "portability_macros.h" /*-******************************************************* @@ -51,12 +53,19 @@ # define WIN_CDECL #endif +/* UNUSED_ATTR tells the compiler it is okay if the function is unused. */ +#if defined(__GNUC__) +# define UNUSED_ATTR __attribute__((unused)) +#else +# define UNUSED_ATTR +#endif + /** * FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant * parameters. They must be inlined for the compiler to eliminate the constant * branches. */ -#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR +#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR UNUSED_ATTR /** * HINT_INLINE is used to help the compiler generate better code. It is *not* * used for "templates", so it can be tweaked based on the compilers @@ -71,14 +80,28 @@ #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5 # define HINT_INLINE static INLINE_KEYWORD #else -# define HINT_INLINE static INLINE_KEYWORD FORCE_INLINE_ATTR +# define HINT_INLINE FORCE_INLINE_TEMPLATE #endif -/* UNUSED_ATTR tells the compiler it is okay if the function is unused. */ +/* "soft" inline : + * The compiler is free to select if it's a good idea to inline or not. + * The main objective is to silence compiler warnings + * when a defined function in included but not used. + * + * Note : this macro is prefixed `MEM_` because it used to be provided by `mem.h` unit. + * Updating the prefix is probably preferable, but requires a fairly large codemod, + * since this name is used everywhere. + */ +#ifndef MEM_STATIC /* already defined in Linux Kernel mem.h */ #if defined(__GNUC__) -# define UNUSED_ATTR __attribute__((unused)) +# define MEM_STATIC static __inline UNUSED_ATTR +#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define MEM_STATIC static inline +#elif defined(_MSC_VER) +# define MEM_STATIC static __inline #else -# define UNUSED_ATTR +# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ +#endif #endif /* force no inlining */ @@ -109,10 +132,10 @@ /* prefetch * can be disabled, by declaring NO_PREFETCH build macro */ #if defined(NO_PREFETCH) -# define PREFETCH_L1(ptr) (void)(ptr) /* disabled */ -# define PREFETCH_L2(ptr) (void)(ptr) /* disabled */ +# define PREFETCH_L1(ptr) do { (void)(ptr); } while (0) /* disabled */ +# define PREFETCH_L2(ptr) do { (void)(ptr); } while (0) /* disabled */ #else -# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */ +# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) && !defined(_M_ARM64EC) /* _mm_prefetch() is not defined outside of x86/x64 */ # include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ # define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0) # define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1) @@ -120,24 +143,25 @@ # define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */) # define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */) # elif defined(__aarch64__) -# define PREFETCH_L1(ptr) __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr))) -# define PREFETCH_L2(ptr) __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr))) +# define PREFETCH_L1(ptr) do { __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr))); } while (0) +# define PREFETCH_L2(ptr) do { __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr))); } while (0) # else -# define PREFETCH_L1(ptr) (void)(ptr) /* disabled */ -# define PREFETCH_L2(ptr) (void)(ptr) /* disabled */ +# define PREFETCH_L1(ptr) do { (void)(ptr); } while (0) /* disabled */ +# define PREFETCH_L2(ptr) do { (void)(ptr); } while (0) /* disabled */ # endif #endif /* NO_PREFETCH */ #define CACHELINE_SIZE 64 -#define PREFETCH_AREA(p, s) { \ - const char* const _ptr = (const char*)(p); \ - size_t const _size = (size_t)(s); \ - size_t _pos; \ - for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \ - PREFETCH_L2(_ptr + _pos); \ - } \ -} +#define PREFETCH_AREA(p, s) \ + do { \ + const char* const _ptr = (const char*)(p); \ + size_t const _size = (size_t)(s); \ + size_t _pos; \ + for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \ + PREFETCH_L2(_ptr + _pos); \ + } \ + } while (0) /* vectorization * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax, @@ -166,9 +190,9 @@ #endif #if __has_builtin(__builtin_unreachable) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))) -# define ZSTD_UNREACHABLE { assert(0), __builtin_unreachable(); } +# define ZSTD_UNREACHABLE do { assert(0), __builtin_unreachable(); } while (0) #else -# define ZSTD_UNREACHABLE { assert(0); } +# define ZSTD_UNREACHABLE do { assert(0); } while (0) #endif /* disable warnings */ @@ -281,6 +305,74 @@ * Sanitizer *****************************************************************/ +/** + * Zstd relies on pointer overflow in its decompressor. + * We add this attribute to functions that rely on pointer overflow. + */ +#ifndef ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +# if __has_attribute(no_sanitize) +# if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 8 + /* gcc < 8 only has signed-integer-overlow which triggers on pointer overflow */ +# define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR __attribute__((no_sanitize("signed-integer-overflow"))) +# else + /* older versions of clang [3.7, 5.0) will warn that pointer-overflow is ignored. */ +# define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR __attribute__((no_sanitize("pointer-overflow"))) +# endif +# else +# define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +# endif +#endif + +/** + * Helper function to perform a wrapped pointer difference without trigging + * UBSAN. + * + * @returns lhs - rhs with wrapping + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +ptrdiff_t ZSTD_wrappedPtrDiff(unsigned char const* lhs, unsigned char const* rhs) +{ + return lhs - rhs; +} + +/** + * Helper function to perform a wrapped pointer add without triggering UBSAN. + * + * @return ptr + add with wrapping + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +unsigned char const* ZSTD_wrappedPtrAdd(unsigned char const* ptr, ptrdiff_t add) +{ + return ptr + add; +} + +/** + * Helper function to perform a wrapped pointer subtraction without triggering + * UBSAN. + * + * @return ptr - sub with wrapping + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +unsigned char const* ZSTD_wrappedPtrSub(unsigned char const* ptr, ptrdiff_t sub) +{ + return ptr - sub; +} + +/** + * Helper function to add to a pointer that works around C's undefined behavior + * of adding 0 to NULL. + * + * @returns `ptr + add` except it defines `NULL + 0 == NULL`. + */ +MEM_STATIC +unsigned char* ZSTD_maybeNullPtrAdd(unsigned char* ptr, ptrdiff_t add) +{ + return add > 0 ? ptr + add : ptr; +} + /* Issue #3240 reports an ASAN failure on an llvm-mingw build. Out of an * abundance of caution, disable our custom poisoning on mingw. */ #ifdef __MINGW32__ @@ -311,6 +403,10 @@ void __msan_poison(const volatile void *a, size_t size); /* Returns the offset of the first (at least partially) poisoned byte in the memory range, or -1 if the whole range is good. */ intptr_t __msan_test_shadow(const volatile void *x, size_t size); + +/* Print shadow and origin for the memory range to stderr in a human-readable + format. */ +void __msan_print_shadow(const volatile void *x, size_t size); #endif #if ZSTD_ADDRESS_SANITIZER && !defined(ZSTD_ASAN_DONT_POISON_WORKSPACE) diff --git a/src/dependencies/zstd-1.5.4/lib/common/cpu.h b/src/dependencies/zstd-1.5.6/lib/common/cpu.h similarity index 82% rename from src/dependencies/zstd-1.5.4/lib/common/cpu.h rename to src/dependencies/zstd-1.5.6/lib/common/cpu.h index 8bc34a3..0e684d9 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/cpu.h +++ b/src/dependencies/zstd-1.5.6/lib/common/cpu.h @@ -35,6 +35,7 @@ MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) { U32 f7b = 0; U32 f7c = 0; #if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) +#if !defined(__clang__) int reg[4]; __cpuid((int*)reg, 0); { @@ -50,6 +51,41 @@ MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) { f7c = (U32)reg[2]; } } +#else + /* Clang compiler has a bug (fixed in https://reviews.llvm.org/D101338) in + * which the `__cpuid` intrinsic does not save and restore `rbx` as it needs + * to due to being a reserved register. So in that case, do the `cpuid` + * ourselves. Clang supports inline assembly anyway. + */ + U32 n; + __asm__( + "pushq %%rbx\n\t" + "cpuid\n\t" + "popq %%rbx\n\t" + : "=a"(n) + : "a"(0) + : "rcx", "rdx"); + if (n >= 1) { + U32 f1a; + __asm__( + "pushq %%rbx\n\t" + "cpuid\n\t" + "popq %%rbx\n\t" + : "=a"(f1a), "=c"(f1c), "=d"(f1d) + : "a"(1) + :); + } + if (n >= 7) { + __asm__( + "pushq %%rbx\n\t" + "cpuid\n\t" + "movq %%rbx, %%rax\n\t" + "popq %%rbx" + : "=a"(f7b), "=c"(f7c) + : "a"(7), "c"(0) + : "rdx"); + } +#endif #elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__) /* The following block like the normal cpuid branch below, but gcc * reserves ebx for use of its pic register so we must specially diff --git a/src/dependencies/zstd-1.5.4/lib/common/debug.c b/src/dependencies/zstd-1.5.6/lib/common/debug.c similarity index 77% rename from src/dependencies/zstd-1.5.4/lib/common/debug.c rename to src/dependencies/zstd-1.5.6/lib/common/debug.c index ebf7bfc..9d0b7d2 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/debug.c +++ b/src/dependencies/zstd-1.5.6/lib/common/debug.c @@ -21,4 +21,10 @@ #include "debug.h" +#if !defined(ZSTD_LINUX_KERNEL) || (DEBUGLEVEL>=2) +/* We only use this when DEBUGLEVEL>=2, but we get -Werror=pedantic errors if a + * translation unit is empty. So remove this from Linux kernel builds, but + * otherwise just leave it in. + */ int g_debuglevel = DEBUGLEVEL; +#endif diff --git a/src/dependencies/zstd-1.5.4/lib/common/debug.h b/src/dependencies/zstd-1.5.6/lib/common/debug.h similarity index 78% rename from src/dependencies/zstd-1.5.4/lib/common/debug.h rename to src/dependencies/zstd-1.5.6/lib/common/debug.h index 0e9817e..a16b69e 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/debug.h +++ b/src/dependencies/zstd-1.5.6/lib/common/debug.h @@ -85,18 +85,27 @@ extern int g_debuglevel; /* the variable is only declared, It's useful when enabling very verbose levels on selective conditions (such as position in src) */ -# define RAWLOG(l, ...) { \ - if (l<=g_debuglevel) { \ - ZSTD_DEBUG_PRINT(__VA_ARGS__); \ - } } -# define DEBUGLOG(l, ...) { \ - if (l<=g_debuglevel) { \ - ZSTD_DEBUG_PRINT(__FILE__ ": " __VA_ARGS__); \ - ZSTD_DEBUG_PRINT(" \n"); \ - } } +# define RAWLOG(l, ...) \ + do { \ + if (l<=g_debuglevel) { \ + ZSTD_DEBUG_PRINT(__VA_ARGS__); \ + } \ + } while (0) + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) +#define LINE_AS_STRING TOSTRING(__LINE__) + +# define DEBUGLOG(l, ...) \ + do { \ + if (l<=g_debuglevel) { \ + ZSTD_DEBUG_PRINT(__FILE__ ":" LINE_AS_STRING ": " __VA_ARGS__); \ + ZSTD_DEBUG_PRINT(" \n"); \ + } \ + } while (0) #else -# define RAWLOG(l, ...) {} /* disabled */ -# define DEBUGLOG(l, ...) {} /* disabled */ +# define RAWLOG(l, ...) do { } while (0) /* disabled */ +# define DEBUGLOG(l, ...) do { } while (0) /* disabled */ #endif diff --git a/src/dependencies/zstd-1.5.4/lib/common/entropy_common.c b/src/dependencies/zstd-1.5.6/lib/common/entropy_common.c similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/common/entropy_common.c rename to src/dependencies/zstd-1.5.6/lib/common/entropy_common.c diff --git a/src/dependencies/zstd-1.5.4/lib/common/error_private.c b/src/dependencies/zstd-1.5.6/lib/common/error_private.c similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/common/error_private.c rename to src/dependencies/zstd-1.5.6/lib/common/error_private.c diff --git a/src/dependencies/zstd-1.5.4/lib/common/error_private.h b/src/dependencies/zstd-1.5.6/lib/common/error_private.h similarity index 55% rename from src/dependencies/zstd-1.5.4/lib/common/error_private.h rename to src/dependencies/zstd-1.5.6/lib/common/error_private.h index 325daad..0156010 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/error_private.h +++ b/src/dependencies/zstd-1.5.6/lib/common/error_private.h @@ -60,8 +60,13 @@ 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); } /* check and forward error code */ -#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e -#define CHECK_F(f) { CHECK_V_F(_var_err__, f); } +#define CHECK_V_F(e, f) \ + size_t const e = f; \ + do { \ + if (ERR_isError(e)) \ + return e; \ + } while (0) +#define CHECK_F(f) do { CHECK_V_F(_var_err__, f); } while (0) /*-**************************************** @@ -95,10 +100,12 @@ void _force_has_format_string(const char *format, ...) { * We want to force this function invocation to be syntactically correct, but * we don't want to force runtime evaluation of its arguments. */ -#define _FORCE_HAS_FORMAT_STRING(...) \ - if (0) { \ - _force_has_format_string(__VA_ARGS__); \ - } +#define _FORCE_HAS_FORMAT_STRING(...) \ + do { \ + if (0) { \ + _force_has_format_string(__VA_ARGS__); \ + } \ + } while (0) #define ERR_QUOTE(str) #str @@ -109,48 +116,50 @@ void _force_has_format_string(const char *format, ...) { * In order to do that (particularly, printing the conditional that failed), * this can't just wrap RETURN_ERROR(). */ -#define RETURN_ERROR_IF(cond, err, ...) \ - if (cond) { \ - RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \ - __FILE__, __LINE__, ERR_QUOTE(cond), ERR_QUOTE(ERROR(err))); \ - _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ - RAWLOG(3, ": " __VA_ARGS__); \ - RAWLOG(3, "\n"); \ - return ERROR(err); \ - } +#define RETURN_ERROR_IF(cond, err, ...) \ + do { \ + if (cond) { \ + RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \ + __FILE__, __LINE__, ERR_QUOTE(cond), ERR_QUOTE(ERROR(err))); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + RAWLOG(3, ": " __VA_ARGS__); \ + RAWLOG(3, "\n"); \ + return ERROR(err); \ + } \ + } while (0) /** * Unconditionally return the specified error. * * In debug modes, prints additional information. */ -#define RETURN_ERROR(err, ...) \ - do { \ - RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \ - __FILE__, __LINE__, ERR_QUOTE(ERROR(err))); \ - _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ - RAWLOG(3, ": " __VA_ARGS__); \ - RAWLOG(3, "\n"); \ - return ERROR(err); \ - } while(0); +#define RETURN_ERROR(err, ...) \ + do { \ + RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \ + __FILE__, __LINE__, ERR_QUOTE(ERROR(err))); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + RAWLOG(3, ": " __VA_ARGS__); \ + RAWLOG(3, "\n"); \ + return ERROR(err); \ + } while(0) /** * If the provided expression evaluates to an error code, returns that error code. * * In debug modes, prints additional information. */ -#define FORWARD_IF_ERROR(err, ...) \ - do { \ - size_t const err_code = (err); \ - if (ERR_isError(err_code)) { \ - RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \ - __FILE__, __LINE__, ERR_QUOTE(err), ERR_getErrorName(err_code)); \ - _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ - RAWLOG(3, ": " __VA_ARGS__); \ - RAWLOG(3, "\n"); \ - return err_code; \ - } \ - } while(0); +#define FORWARD_IF_ERROR(err, ...) \ + do { \ + size_t const err_code = (err); \ + if (ERR_isError(err_code)) { \ + RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \ + __FILE__, __LINE__, ERR_QUOTE(err), ERR_getErrorName(err_code)); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + RAWLOG(3, ": " __VA_ARGS__); \ + RAWLOG(3, "\n"); \ + return err_code; \ + } \ + } while(0) #if defined (__cplusplus) } diff --git a/src/dependencies/zstd-1.5.4/lib/common/fse.h b/src/dependencies/zstd-1.5.6/lib/common/fse.h similarity index 99% rename from src/dependencies/zstd-1.5.4/lib/common/fse.h rename to src/dependencies/zstd-1.5.6/lib/common/fse.h index 02a1f0b..2ae128e 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/fse.h +++ b/src/dependencies/zstd-1.5.6/lib/common/fse.h @@ -229,6 +229,7 @@ If there is an error, the function will return an error code, which can be teste #endif /* FSE_H */ + #if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY) #define FSE_H_FSE_STATIC_LINKING_ONLY @@ -464,13 +465,13 @@ MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, un FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; const U16* const stateTable = (const U16*)(statePtr->stateTable); U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16); - BIT_addBits(bitC, statePtr->value, nbBitsOut); + BIT_addBits(bitC, (size_t)statePtr->value, nbBitsOut); statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; } MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr) { - BIT_addBits(bitC, statePtr->value, statePtr->stateLog); + BIT_addBits(bitC, (size_t)statePtr->value, statePtr->stateLog); BIT_flushBits(bitC); } diff --git a/src/dependencies/zstd-1.5.4/lib/common/fse_decompress.c b/src/dependencies/zstd-1.5.6/lib/common/fse_decompress.c similarity index 92% rename from src/dependencies/zstd-1.5.4/lib/common/fse_decompress.c rename to src/dependencies/zstd-1.5.6/lib/common/fse_decompress.c index 1e1c9f9..0dcc464 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/fse_decompress.c +++ b/src/dependencies/zstd-1.5.6/lib/common/fse_decompress.c @@ -22,8 +22,7 @@ #define FSE_STATIC_LINKING_ONLY #include "fse.h" #include "error_private.h" -#define ZSTD_DEPS_NEED_MALLOC -#include "zstd_deps.h" +#include "zstd_deps.h" /* ZSTD_memcpy */ #include "bits.h" /* ZSTD_highbit32 */ @@ -84,7 +83,7 @@ static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCo symbolNext[s] = 1; } else { if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0; - symbolNext[s] = normalizedCounter[s]; + symbolNext[s] = (U16)normalizedCounter[s]; } } } ZSTD_memcpy(dt, &DTableH, sizeof(DTableH)); } @@ -99,8 +98,7 @@ static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCo * all symbols have counts <= 8. We ensure we have 8 bytes at the end of * our buffer to handle the over-write. */ - { - U64 const add = 0x0101010101010101ull; + { U64 const add = 0x0101010101010101ull; size_t pos = 0; U64 sv = 0; U32 s; @@ -111,9 +109,8 @@ static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCo for (i = 8; i < n; i += 8) { MEM_write64(spread + pos + i, sv); } - pos += n; - } - } + pos += (size_t)n; + } } /* Now we spread those positions across the table. * The benefit of doing it in two stages is that we avoid the * variable size inner loop, which caused lots of branch misses. @@ -232,12 +229,12 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_usingDTable_generic( break; } } - return op-ostart; + assert(op >= ostart); + return (size_t)(op-ostart); } typedef struct { short ncount[FSE_MAX_SYMBOL_VALUE + 1]; - FSE_DTable dtable[1]; /* Dynamically sized */ } FSE_DecompressWksp; @@ -252,13 +249,18 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body( unsigned tableLog; unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; FSE_DecompressWksp* const wksp = (FSE_DecompressWksp*)workSpace; + size_t const dtablePos = sizeof(FSE_DecompressWksp) / sizeof(FSE_DTable); + FSE_DTable* const dtable = (FSE_DTable*)workSpace + dtablePos; - DEBUG_STATIC_ASSERT((FSE_MAX_SYMBOL_VALUE + 1) % 2 == 0); + FSE_STATIC_ASSERT((FSE_MAX_SYMBOL_VALUE + 1) % 2 == 0); if (wkspSize < sizeof(*wksp)) return ERROR(GENERIC); + /* correct offset to dtable depends on this property */ + FSE_STATIC_ASSERT(sizeof(FSE_DecompressWksp) % sizeof(FSE_DTable) == 0); + /* normal FSE decoding mode */ - { - size_t const NCountLength = FSE_readNCount_bmi2(wksp->ncount, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2); + { size_t const NCountLength = + FSE_readNCount_bmi2(wksp->ncount, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2); if (FSE_isError(NCountLength)) return NCountLength; if (tableLog > maxLog) return ERROR(tableLog_tooLarge); assert(NCountLength <= cSrcSize); @@ -271,16 +273,16 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body( workSpace = (BYTE*)workSpace + sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog); wkspSize -= sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog); - CHECK_F( FSE_buildDTable_internal(wksp->dtable, wksp->ncount, maxSymbolValue, tableLog, workSpace, wkspSize) ); + CHECK_F( FSE_buildDTable_internal(dtable, wksp->ncount, maxSymbolValue, tableLog, workSpace, wkspSize) ); { - const void* ptr = wksp->dtable; + const void* ptr = dtable; const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr; const U32 fastMode = DTableH->fastMode; /* select fast mode (static) */ - if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, wksp->dtable, 1); - return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, wksp->dtable, 0); + if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 1); + return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 0); } } diff --git a/src/dependencies/zstd-1.5.4/lib/common/huf.h b/src/dependencies/zstd-1.5.6/lib/common/huf.h similarity index 96% rename from src/dependencies/zstd-1.5.4/lib/common/huf.h rename to src/dependencies/zstd-1.5.6/lib/common/huf.h index 73d1ee5..99bf85d 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/huf.h +++ b/src/dependencies/zstd-1.5.6/lib/common/huf.h @@ -197,9 +197,22 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void /** HUF_getNbBitsFromCTable() : * Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX - * Note 1 : is not inlined, as HUF_CElt definition is private */ + * Note 1 : If symbolValue > HUF_readCTableHeader(symbolTable).maxSymbolValue, returns 0 + * Note 2 : is not inlined, as HUF_CElt definition is private + */ U32 HUF_getNbBitsFromCTable(const HUF_CElt* symbolTable, U32 symbolValue); +typedef struct { + BYTE tableLog; + BYTE maxSymbolValue; + BYTE unused[sizeof(size_t) - 2]; +} HUF_CTableHeader; + +/** HUF_readCTableHeader() : + * @returns The header from the CTable specifying the tableLog and the maxSymbolValue. + */ +HUF_CTableHeader HUF_readCTableHeader(HUF_CElt const* ctable); + /* * HUF_decompress() does the following: * 1. select the decompression algorithm (X1, X2) based on pre-computed heuristics diff --git a/src/dependencies/zstd-1.5.4/lib/common/mem.h b/src/dependencies/zstd-1.5.6/lib/common/mem.h similarity index 96% rename from src/dependencies/zstd-1.5.4/lib/common/mem.h rename to src/dependencies/zstd-1.5.6/lib/common/mem.h index 98dd47a..096f4be 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/mem.h +++ b/src/dependencies/zstd-1.5.6/lib/common/mem.h @@ -31,15 +31,6 @@ extern "C" { # include /* _byteswap_ulong */ # include /* _byteswap_* */ #endif -#if defined(__GNUC__) -# define MEM_STATIC static __inline __attribute__((unused)) -#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) -# define MEM_STATIC static inline -#elif defined(_MSC_VER) -# define MEM_STATIC static __inline -#else -# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ -#endif /*-************************************************************** * Basic Types diff --git a/src/dependencies/zstd-1.5.4/lib/common/pool.c b/src/dependencies/zstd-1.5.6/lib/common/pool.c similarity index 99% rename from src/dependencies/zstd-1.5.4/lib/common/pool.c rename to src/dependencies/zstd-1.5.6/lib/common/pool.c index f3d9d08..3adcefc 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/pool.c +++ b/src/dependencies/zstd-1.5.6/lib/common/pool.c @@ -10,9 +10,9 @@ /* ====== Dependencies ======= */ +#include "../common/allocations.h" /* ZSTD_customCalloc, ZSTD_customFree */ #include "zstd_deps.h" /* size_t */ #include "debug.h" /* assert */ -#include "zstd_internal.h" /* ZSTD_customCalloc, ZSTD_customFree */ #include "pool.h" /* ====== Compiler specifics ====== */ @@ -223,7 +223,7 @@ static int POOL_resize_internal(POOL_ctx* ctx, size_t numThreads) { ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_customCalloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem); if (!threadPool) return 1; /* replace existing thread pool */ - ZSTD_memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(*threadPool)); + ZSTD_memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(ZSTD_pthread_t)); ZSTD_customFree(ctx->threads, ctx->customMem); ctx->threads = threadPool; /* Initialize additional threads */ diff --git a/src/dependencies/zstd-1.5.4/lib/common/pool.h b/src/dependencies/zstd-1.5.6/lib/common/pool.h similarity index 97% rename from src/dependencies/zstd-1.5.4/lib/common/pool.h rename to src/dependencies/zstd-1.5.6/lib/common/pool.h index eb22ff5..cca4de7 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/pool.h +++ b/src/dependencies/zstd-1.5.6/lib/common/pool.h @@ -47,7 +47,7 @@ void POOL_joinJobs(POOL_ctx* ctx); /*! POOL_resize() : * Expands or shrinks pool's number of threads. * This is more efficient than releasing + creating a new context, - * since it tries to preserve and re-use existing threads. + * since it tries to preserve and reuse existing threads. * `numThreads` must be at least 1. * @return : 0 when resize was successful, * !0 (typically 1) if there is an error. diff --git a/src/dependencies/zstd-1.5.4/lib/common/portability_macros.h b/src/dependencies/zstd-1.5.6/lib/common/portability_macros.h similarity index 98% rename from src/dependencies/zstd-1.5.4/lib/common/portability_macros.h rename to src/dependencies/zstd-1.5.6/lib/common/portability_macros.h index 8fd6ea8..e50314a 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/portability_macros.h +++ b/src/dependencies/zstd-1.5.6/lib/common/portability_macros.h @@ -68,6 +68,8 @@ /* Mark the internal assembly functions as hidden */ #ifdef __ELF__ # define ZSTD_HIDE_ASM_FUNCTION(func) .hidden func +#elif defined(__APPLE__) +# define ZSTD_HIDE_ASM_FUNCTION(func) .private_extern func #else # define ZSTD_HIDE_ASM_FUNCTION(func) #endif diff --git a/src/dependencies/zstd-1.5.4/lib/common/threading.c b/src/dependencies/zstd-1.5.6/lib/common/threading.c similarity index 94% rename from src/dependencies/zstd-1.5.4/lib/common/threading.c rename to src/dependencies/zstd-1.5.6/lib/common/threading.c index f234110..25bb8b9 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/threading.c +++ b/src/dependencies/zstd-1.5.6/lib/common/threading.c @@ -47,7 +47,7 @@ static unsigned __stdcall worker(void *arg) void* (*start_routine)(void*); void* thread_arg; - /* Inialized thread_arg and start_routine and signal main thread that we don't need it + /* Initialized thread_arg and start_routine and signal main thread that we don't need it * to wait any longer. */ { @@ -73,10 +73,12 @@ int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused, ZSTD_thread_params_t thread_param; (void)unused; + if (thread==NULL) return -1; + *thread = NULL; + thread_param.start_routine = start_routine; thread_param.arg = arg; thread_param.initialized = 0; - *thread = NULL; /* Setup thread initialization synchronization */ if(ZSTD_pthread_cond_init(&thread_param.initialized_cond, NULL)) { @@ -91,7 +93,7 @@ int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused, /* Spawn thread */ *thread = (HANDLE)_beginthreadex(NULL, 0, worker, &thread_param, 0, NULL); - if (!thread) { + if (*thread==NULL) { ZSTD_pthread_mutex_destroy(&thread_param.initialized_mutex); ZSTD_pthread_cond_destroy(&thread_param.initialized_cond); return errno; @@ -137,6 +139,7 @@ int ZSTD_pthread_join(ZSTD_pthread_t thread) int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr) { + assert(mutex != NULL); *mutex = (pthread_mutex_t*)ZSTD_malloc(sizeof(pthread_mutex_t)); if (!*mutex) return 1; @@ -145,6 +148,7 @@ int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t con int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex) { + assert(mutex != NULL); if (!*mutex) return 0; { @@ -156,6 +160,7 @@ int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex) int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr) { + assert(cond != NULL); *cond = (pthread_cond_t*)ZSTD_malloc(sizeof(pthread_cond_t)); if (!*cond) return 1; @@ -164,6 +169,7 @@ int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond) { + assert(cond != NULL); if (!*cond) return 0; { diff --git a/src/dependencies/zstd-1.5.4/lib/common/threading.h b/src/dependencies/zstd-1.5.6/lib/common/threading.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/common/threading.h rename to src/dependencies/zstd-1.5.6/lib/common/threading.h diff --git a/src/dependencies/zstd-1.5.4/lib/common/xxhash.c b/src/dependencies/zstd-1.5.6/lib/common/xxhash.c similarity index 50% rename from src/dependencies/zstd-1.5.4/lib/common/xxhash.c rename to src/dependencies/zstd-1.5.6/lib/common/xxhash.c index fd237c9..052cd52 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/xxhash.c +++ b/src/dependencies/zstd-1.5.6/lib/common/xxhash.c @@ -1,24 +1,18 @@ /* - * xxHash - Fast Hash algorithm - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * You can contact the author at : - * - xxHash homepage: https://cyan4973.github.io/xxHash/ - * - xxHash source repository : https://github.com/Cyan4973/xxHash + * xxHash - Extremely Fast Hash algorithm + * Copyright (c) Yann Collet - Meta Platforms, Inc * * This source code is licensed under both the BSD-style license (found in the * LICENSE file in the root directory of this source tree) and the GPLv2 (found * in the COPYING file in the root directory of this source tree). * You may select, at your option, one of the above-listed licenses. -*/ - - + */ /* * xxhash.c instantiates functions defined in xxhash.h */ -#define XXH_STATIC_LINKING_ONLY /* access advanced declarations */ -#define XXH_IMPLEMENTATION /* access definitions */ +#define XXH_STATIC_LINKING_ONLY /* access advanced declarations */ +#define XXH_IMPLEMENTATION /* access definitions */ #include "xxhash.h" diff --git a/src/dependencies/zstd-1.5.4/lib/common/xxhash.h b/src/dependencies/zstd-1.5.6/lib/common/xxhash.h similarity index 64% rename from src/dependencies/zstd-1.5.4/lib/common/xxhash.h rename to src/dependencies/zstd-1.5.6/lib/common/xxhash.h index b8b7329..e59e442 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/xxhash.h +++ b/src/dependencies/zstd-1.5.6/lib/common/xxhash.h @@ -1,17 +1,15 @@ /* - * xxHash - Fast Hash algorithm - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * You can contact the author at : - * - xxHash homepage: https://cyan4973.github.io/xxHash/ - * - xxHash source repository : https://github.com/Cyan4973/xxHash + * xxHash - Extremely Fast Hash algorithm + * Header File + * Copyright (c) Yann Collet - Meta Platforms, Inc * * This source code is licensed under both the BSD-style license (found in the * LICENSE file in the root directory of this source tree) and the GPLv2 (found * in the COPYING file in the root directory of this source tree). * You may select, at your option, one of the above-listed licenses. -*/ + */ +/* Local adaptations for Zstandard */ #ifndef XXH_NO_XXH3 # define XXH_NO_XXH3 @@ -24,46 +22,210 @@ /*! * @mainpage xxHash * + * xxHash is an extremely fast non-cryptographic hash algorithm, working at RAM speed + * limits. + * + * It is proposed in four flavors, in three families: + * 1. @ref XXH32_family + * - Classic 32-bit hash function. Simple, compact, and runs on almost all + * 32-bit and 64-bit systems. + * 2. @ref XXH64_family + * - Classic 64-bit adaptation of XXH32. Just as simple, and runs well on most + * 64-bit systems (but _not_ 32-bit systems). + * 3. @ref XXH3_family + * - Modern 64-bit and 128-bit hash function family which features improved + * strength and performance across the board, especially on smaller data. + * It benefits greatly from SIMD and 64-bit without requiring it. + * + * Benchmarks + * --- + * The reference system uses an Intel i7-9700K CPU, and runs Ubuntu x64 20.04. + * The open source benchmark program is compiled with clang v10.0 using -O3 flag. + * + * | Hash Name | ISA ext | Width | Large Data Speed | Small Data Velocity | + * | -------------------- | ------- | ----: | ---------------: | ------------------: | + * | XXH3_64bits() | @b AVX2 | 64 | 59.4 GB/s | 133.1 | + * | MeowHash | AES-NI | 128 | 58.2 GB/s | 52.5 | + * | XXH3_128bits() | @b AVX2 | 128 | 57.9 GB/s | 118.1 | + * | CLHash | PCLMUL | 64 | 37.1 GB/s | 58.1 | + * | XXH3_64bits() | @b SSE2 | 64 | 31.5 GB/s | 133.1 | + * | XXH3_128bits() | @b SSE2 | 128 | 29.6 GB/s | 118.1 | + * | RAM sequential read | | N/A | 28.0 GB/s | N/A | + * | ahash | AES-NI | 64 | 22.5 GB/s | 107.2 | + * | City64 | | 64 | 22.0 GB/s | 76.6 | + * | T1ha2 | | 64 | 22.0 GB/s | 99.0 | + * | City128 | | 128 | 21.7 GB/s | 57.7 | + * | FarmHash | AES-NI | 64 | 21.3 GB/s | 71.9 | + * | XXH64() | | 64 | 19.4 GB/s | 71.0 | + * | SpookyHash | | 64 | 19.3 GB/s | 53.2 | + * | Mum | | 64 | 18.0 GB/s | 67.0 | + * | CRC32C | SSE4.2 | 32 | 13.0 GB/s | 57.9 | + * | XXH32() | | 32 | 9.7 GB/s | 71.9 | + * | City32 | | 32 | 9.1 GB/s | 66.0 | + * | Blake3* | @b AVX2 | 256 | 4.4 GB/s | 8.1 | + * | Murmur3 | | 32 | 3.9 GB/s | 56.1 | + * | SipHash* | | 64 | 3.0 GB/s | 43.2 | + * | Blake3* | @b SSE2 | 256 | 2.4 GB/s | 8.1 | + * | HighwayHash | | 64 | 1.4 GB/s | 6.0 | + * | FNV64 | | 64 | 1.2 GB/s | 62.7 | + * | Blake2* | | 256 | 1.1 GB/s | 5.1 | + * | SHA1* | | 160 | 0.8 GB/s | 5.6 | + * | MD5* | | 128 | 0.6 GB/s | 7.8 | + * @note + * - Hashes which require a specific ISA extension are noted. SSE2 is also noted, + * even though it is mandatory on x64. + * - Hashes with an asterisk are cryptographic. Note that MD5 is non-cryptographic + * by modern standards. + * - Small data velocity is a rough average of algorithm's efficiency for small + * data. For more accurate information, see the wiki. + * - More benchmarks and strength tests are found on the wiki: + * https://github.com/Cyan4973/xxHash/wiki + * + * Usage + * ------ + * All xxHash variants use a similar API. Changing the algorithm is a trivial + * substitution. + * + * @pre + * For functions which take an input and length parameter, the following + * requirements are assumed: + * - The range from [`input`, `input + length`) is valid, readable memory. + * - The only exception is if the `length` is `0`, `input` may be `NULL`. + * - For C++, the objects must have the *TriviallyCopyable* property, as the + * functions access bytes directly as if it was an array of `unsigned char`. + * + * @anchor single_shot_example + * **Single Shot** + * + * These functions are stateless functions which hash a contiguous block of memory, + * immediately returning the result. They are the easiest and usually the fastest + * option. + * + * XXH32(), XXH64(), XXH3_64bits(), XXH3_128bits() + * + * @code{.c} + * #include + * #include "xxhash.h" + * + * // Example for a function which hashes a null terminated string with XXH32(). + * XXH32_hash_t hash_string(const char* string, XXH32_hash_t seed) + * { + * // NULL pointers are only valid if the length is zero + * size_t length = (string == NULL) ? 0 : strlen(string); + * return XXH32(string, length, seed); + * } + * @endcode + * + * + * @anchor streaming_example + * **Streaming** + * + * These groups of functions allow incremental hashing of unknown size, even + * more than what would fit in a size_t. + * + * XXH32_reset(), XXH64_reset(), XXH3_64bits_reset(), XXH3_128bits_reset() + * + * @code{.c} + * #include + * #include + * #include "xxhash.h" + * // Example for a function which hashes a FILE incrementally with XXH3_64bits(). + * XXH64_hash_t hashFile(FILE* f) + * { + * // Allocate a state struct. Do not just use malloc() or new. + * XXH3_state_t* state = XXH3_createState(); + * assert(state != NULL && "Out of memory!"); + * // Reset the state to start a new hashing session. + * XXH3_64bits_reset(state); + * char buffer[4096]; + * size_t count; + * // Read the file in chunks + * while ((count = fread(buffer, 1, sizeof(buffer), f)) != 0) { + * // Run update() as many times as necessary to process the data + * XXH3_64bits_update(state, buffer, count); + * } + * // Retrieve the finalized hash. This will not change the state. + * XXH64_hash_t result = XXH3_64bits_digest(state); + * // Free the state. Do not use free(). + * XXH3_freeState(state); + * return result; + * } + * @endcode + * + * Streaming functions generate the xxHash value from an incremental input. + * This method is slower than single-call functions, due to state management. + * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. + * + * An XXH state must first be allocated using `XXH*_createState()`. + * + * Start a new hash by initializing the state with a seed using `XXH*_reset()`. + * + * Then, feed the hash state by calling `XXH*_update()` as many times as necessary. + * + * The function returns an error code, with 0 meaning OK, and any other value + * meaning there is an error. + * + * Finally, a hash value can be produced anytime, by using `XXH*_digest()`. + * This function returns the nn-bits hash as an int or long long. + * + * It's still possible to continue inserting input into the hash state after a + * digest, and generate new hash values later on by invoking `XXH*_digest()`. + * + * When done, release the state using `XXH*_freeState()`. + * + * + * @anchor canonical_representation_example + * **Canonical Representation** + * + * The default return values from XXH functions are unsigned 32, 64 and 128 bit + * integers. + * This the simplest and fastest format for further post-processing. + * + * However, this leaves open the question of what is the order on the byte level, + * since little and big endian conventions will store the same number differently. + * + * The canonical representation settles this issue by mandating big-endian + * convention, the same convention as human-readable numbers (large digits first). + * + * When writing hash values to storage, sending them over a network, or printing + * them, it's highly recommended to use the canonical representation to ensure + * portability across a wider range of systems, present and future. + * + * The following functions allow transformation of hash values to and from + * canonical format. + * + * XXH32_canonicalFromHash(), XXH32_hashFromCanonical(), + * XXH64_canonicalFromHash(), XXH64_hashFromCanonical(), + * XXH128_canonicalFromHash(), XXH128_hashFromCanonical(), + * + * @code{.c} + * #include + * #include "xxhash.h" + * + * // Example for a function which prints XXH32_hash_t in human readable format + * void printXxh32(XXH32_hash_t hash) + * { + * XXH32_canonical_t cano; + * XXH32_canonicalFromHash(&cano, hash); + * size_t i; + * for(i = 0; i < sizeof(cano.digest); ++i) { + * printf("%02x", cano.digest[i]); + * } + * printf("\n"); + * } + * + * // Example for a function which converts XXH32_canonical_t to XXH32_hash_t + * XXH32_hash_t convertCanonicalToXxh32(XXH32_canonical_t cano) + * { + * XXH32_hash_t hash = XXH32_hashFromCanonical(&cano); + * return hash; + * } + * @endcode + * + * * @file xxhash.h * xxHash prototypes and implementation */ -/* TODO: update */ -/* Notice extracted from xxHash homepage: - -xxHash is an extremely fast hash algorithm, running at RAM speed limits. -It also successfully passes all tests from the SMHasher suite. - -Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) - -Name Speed Q.Score Author -xxHash 5.4 GB/s 10 -CrapWow 3.2 GB/s 2 Andrew -MurmurHash 3a 2.7 GB/s 10 Austin Appleby -SpookyHash 2.0 GB/s 10 Bob Jenkins -SBox 1.4 GB/s 9 Bret Mulvey -Lookup3 1.2 GB/s 9 Bob Jenkins -SuperFastHash 1.2 GB/s 1 Paul Hsieh -CityHash64 1.05 GB/s 10 Pike & Alakuijala -FNV 0.55 GB/s 5 Fowler, Noll, Vo -CRC32 0.43 GB/s 9 -MD5-32 0.33 GB/s 10 Ronald L. Rivest -SHA1-32 0.28 GB/s 10 - -Q.Score is a measure of quality of the hash function. -It depends on successfully passing SMHasher test set. -10 is a perfect score. - -Note: SMHasher's CRC32 implementation is not the fastest one. -Other speed-oriented implementations can be faster, -especially in combination with PCLMUL instruction: -https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html?showComment=1552696407071#c3490092340461170735 - -A 64-bit version, named XXH64, is available since r35. -It offers much better speed, but for 64-bit applications only. -Name Speed on 64 bits Speed on 32 bits -XXH64 13.8 GB/s 1.9 GB/s -XXH32 6.8 GB/s 6.0 GB/s -*/ #if defined (__cplusplus) extern "C" { @@ -73,21 +235,80 @@ extern "C" { * INLINE mode ******************************/ /*! - * XXH_INLINE_ALL (and XXH_PRIVATE_API) + * @defgroup public Public API + * Contains details on the public xxHash functions. + * @{ + */ +#ifdef XXH_DOXYGEN +/*! + * @brief Gives access to internal state declaration, required for static allocation. + * + * Incompatible with dynamic linking, due to risks of ABI changes. + * + * Usage: + * @code{.c} + * #define XXH_STATIC_LINKING_ONLY + * #include "xxhash.h" + * @endcode + */ +# define XXH_STATIC_LINKING_ONLY +/* Do not undef XXH_STATIC_LINKING_ONLY for Doxygen */ + +/*! + * @brief Gives access to internal definitions. + * + * Usage: + * @code{.c} + * #define XXH_STATIC_LINKING_ONLY + * #define XXH_IMPLEMENTATION + * #include "xxhash.h" + * @endcode + */ +# define XXH_IMPLEMENTATION +/* Do not undef XXH_IMPLEMENTATION for Doxygen */ + +/*! + * @brief Exposes the implementation and marks all functions as `inline`. + * * Use these build macros to inline xxhash into the target unit. * Inlining improves performance on small inputs, especially when the length is * expressed as a compile-time constant: * - * https://fastcompression.blogspot.com/2018/03/xxhash-for-small-keys-impressive-power.html + * https://fastcompression.blogspot.com/2018/03/xxhash-for-small-keys-impressive-power.html * * It also keeps xxHash symbols private to the unit, so they are not exported. * * Usage: + * @code{.c} * #define XXH_INLINE_ALL * #include "xxhash.h" - * + * @endcode * Do not compile and link xxhash.o as a separate object, as it is not useful. */ +# define XXH_INLINE_ALL +# undef XXH_INLINE_ALL +/*! + * @brief Exposes the implementation without marking functions as inline. + */ +# define XXH_PRIVATE_API +# undef XXH_PRIVATE_API +/*! + * @brief Emulate a namespace by transparently prefixing all symbols. + * + * If you want to include _and expose_ xxHash functions from within your own + * library, but also want to avoid symbol collisions with other libraries which + * may also include xxHash, you can use @ref XXH_NAMESPACE to automatically prefix + * any public symbol from xxhash library with the value of @ref XXH_NAMESPACE + * (therefore, avoid empty or numeric values). + * + * Note that no change is required within the calling program as long as it + * includes `xxhash.h`: Regular symbol names will be automatically translated + * by this header. + */ +# define XXH_NAMESPACE /* YOUR NAME HERE */ +# undef XXH_NAMESPACE +#endif + #if (defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)) \ && !defined(XXH_INLINE_ALL_31684351384) /* this section should be traversed only once */ @@ -202,21 +423,13 @@ extern "C" { # undef XXHASH_H_STATIC_13879238742 #endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */ - - /* **************************************************************** * Stable API *****************************************************************/ #ifndef XXHASH_H_5627135585666179 #define XXHASH_H_5627135585666179 1 - -/*! - * @defgroup public Public API - * Contains details on the public xxHash functions. - * @{ - */ -/* specific declaration modes for Windows */ +/*! @brief Marks a global symbol. */ #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) # if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) # ifdef XXH_EXPORT @@ -229,24 +442,6 @@ extern "C" { # endif #endif -#ifdef XXH_DOXYGEN -/*! - * @brief Emulate a namespace by transparently prefixing all symbols. - * - * If you want to include _and expose_ xxHash functions from within your own - * library, but also want to avoid symbol collisions with other libraries which - * may also include xxHash, you can use XXH_NAMESPACE to automatically prefix - * any public symbol from xxhash library with the value of XXH_NAMESPACE - * (therefore, avoid empty or numeric values). - * - * Note that no change is required within the calling program as long as it - * includes `xxhash.h`: Regular symbol names will be automatically translated - * by this header. - */ -# define XXH_NAMESPACE /* YOUR NAME HERE */ -# undef XXH_NAMESPACE -#endif - #ifdef XXH_NAMESPACE # define XXH_CAT(A,B) A##B # define XXH_NAME2(A,B) XXH_CAT(A,B) @@ -306,12 +501,40 @@ extern "C" { #endif +/* ************************************* +* Compiler specifics +***************************************/ + +/* specific declaration modes for Windows */ +#if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) +# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# ifdef XXH_EXPORT +# define XXH_PUBLIC_API __declspec(dllexport) +# elif XXH_IMPORT +# define XXH_PUBLIC_API __declspec(dllimport) +# endif +# else +# define XXH_PUBLIC_API /* do nothing */ +# endif +#endif + +#if defined (__GNUC__) +# define XXH_CONSTF __attribute__((const)) +# define XXH_PUREF __attribute__((pure)) +# define XXH_MALLOCF __attribute__((malloc)) +#else +# define XXH_CONSTF /* disable */ +# define XXH_PUREF +# define XXH_MALLOCF +#endif + /* ************************************* * Version ***************************************/ #define XXH_VERSION_MAJOR 0 #define XXH_VERSION_MINOR 8 -#define XXH_VERSION_RELEASE 1 +#define XXH_VERSION_RELEASE 2 +/*! @brief Version number, encoded as two digits each */ #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) /*! @@ -320,16 +543,22 @@ extern "C" { * This is mostly useful when xxHash is compiled as a shared library, * since the returned value comes from the library, as opposed to header file. * - * @return `XXH_VERSION_NUMBER` of the invoked library. + * @return @ref XXH_VERSION_NUMBER of the invoked library. */ -XXH_PUBLIC_API unsigned XXH_versionNumber (void); +XXH_PUBLIC_API XXH_CONSTF unsigned XXH_versionNumber (void); /* **************************** * Common basic types ******************************/ #include /* size_t */ -typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; +/*! + * @brief Exit code for the streaming API. + */ +typedef enum { + XXH_OK = 0, /*!< OK */ + XXH_ERROR /*!< Error */ +} XXH_errorcode; /*-********************************************************************** @@ -346,44 +575,44 @@ typedef uint32_t XXH32_hash_t; #elif !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include +# ifdef _AIX +# include +# else +# include +# endif typedef uint32_t XXH32_hash_t; #else # include # if UINT_MAX == 0xFFFFFFFFUL typedef unsigned int XXH32_hash_t; +# elif ULONG_MAX == 0xFFFFFFFFUL + typedef unsigned long XXH32_hash_t; # else -# if ULONG_MAX == 0xFFFFFFFFUL - typedef unsigned long XXH32_hash_t; -# else -# error "unsupported platform: need a 32-bit type" -# endif +# error "unsupported platform: need a 32-bit type" # endif #endif /*! * @} * - * @defgroup xxh32_family XXH32 family + * @defgroup XXH32_family XXH32 family * @ingroup public * Contains functions used in the classic 32-bit xxHash algorithm. * * @note * XXH32 is useful for older platforms, with no or poor 64-bit performance. - * Note that @ref xxh3_family provides competitive speed - * for both 32-bit and 64-bit systems, and offers true 64/128 bit hash results. + * Note that the @ref XXH3_family provides competitive speed for both 32-bit + * and 64-bit systems, and offers true 64/128 bit hash results. * - * @see @ref xxh64_family, @ref xxh3_family : Other xxHash families - * @see @ref xxh32_impl for implementation details + * @see @ref XXH64_family, @ref XXH3_family : Other xxHash families + * @see @ref XXH32_impl for implementation details * @{ */ /*! * @brief Calculates the 32-bit hash of @p input using xxHash32. * - * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark): 5.4 GB/s - * * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. * @param seed The 32-bit seed to alter the hash's output predictably. @@ -393,66 +622,13 @@ typedef uint32_t XXH32_hash_t; * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return The calculated 32-bit hash value. + * @return The calculated 32-bit xxHash32 value. * - * @see - * XXH64(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128(): - * Direct equivalents for the other variants of xxHash. - * @see - * XXH32_createState(), XXH32_update(), XXH32_digest(): Streaming version. - */ -XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed); - -/*! - * Streaming functions generate the xxHash value from an incremental input. - * This method is slower than single-call functions, due to state management. - * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. - * - * An XXH state must first be allocated using `XXH*_createState()`. - * - * Start a new hash by initializing the state with a seed using `XXH*_reset()`. - * - * Then, feed the hash state by calling `XXH*_update()` as many times as necessary. - * - * The function returns an error code, with 0 meaning OK, and any other value - * meaning there is an error. - * - * Finally, a hash value can be produced anytime, by using `XXH*_digest()`. - * This function returns the nn-bits hash as an int or long long. - * - * It's still possible to continue inserting input into the hash state after a - * digest, and generate new hash values later on by invoking `XXH*_digest()`. - * - * When done, release the state using `XXH*_freeState()`. - * - * Example code for incrementally hashing a file: - * @code{.c} - * #include - * #include - * #define BUFFER_SIZE 256 - * - * // Note: XXH64 and XXH3 use the same interface. - * XXH32_hash_t - * hashFile(FILE* stream) - * { - * XXH32_state_t* state; - * unsigned char buf[BUFFER_SIZE]; - * size_t amt; - * XXH32_hash_t hash; - * - * state = XXH32_createState(); // Create a state - * assert(state != NULL); // Error check here - * XXH32_reset(state, 0xbaad5eed); // Reset state with our seed - * while ((amt = fread(buf, 1, sizeof(buf), stream)) != 0) { - * XXH32_update(state, buf, amt); // Hash the file in chunks - * } - * hash = XXH32_digest(state); // Finalize the hash - * XXH32_freeState(state); // Clean up - * return hash; - * } - * @endcode + * @see @ref single_shot_example "Single Shot Example" for an example. */ +XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed); +#ifndef XXH_NO_STREAM /*! * @typedef struct XXH32_state_s XXH32_state_t * @brief The opaque state struct for the XXH32 streaming API. @@ -464,16 +640,21 @@ typedef struct XXH32_state_s XXH32_state_t; /*! * @brief Allocates an @ref XXH32_state_t. * - * Must be freed with XXH32_freeState(). - * @return An allocated XXH32_state_t on success, `NULL` on failure. + * @return An allocated pointer of @ref XXH32_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH32_freeState(). */ -XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void); +XXH_PUBLIC_API XXH_MALLOCF XXH32_state_t* XXH32_createState(void); /*! * @brief Frees an @ref XXH32_state_t. * - * Must be allocated with XXH32_createState(). * @param statePtr A pointer to an @ref XXH32_state_t allocated with @ref XXH32_createState(). - * @return XXH_OK. + * + * @return @ref XXH_OK. + * + * @note @p statePtr must be allocated with XXH32_createState(). + * */ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); /*! @@ -489,23 +670,22 @@ XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_ /*! * @brief Resets an @ref XXH32_state_t to begin a new hash. * - * This function resets and seeds a state. Call it before @ref XXH32_update(). - * * @param statePtr The state struct to reset. * @param seed The 32-bit seed to alter the hash result predictably. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note This function resets and seeds a state. Call it before @ref XXH32_update(). */ XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t seed); /*! * @brief Consumes a block of @p input to an @ref XXH32_state_t. * - * Call this to incrementally consume blocks of data. - * * @param statePtr The state struct to update. * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. @@ -517,47 +697,32 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. */ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); /*! * @brief Returns the calculated hash value from an @ref XXH32_state_t. * - * @note - * Calling XXH32_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * - * @return The calculated xxHash32 value from that state. + * @return The calculated 32-bit xxHash32 value from that state. + * + * @note + * Calling XXH32_digest() will not affect @p statePtr, so you can update, + * digest, and update again. */ -XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); +XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); +#endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ -/* - * The default return values from XXH functions are unsigned 32 and 64 bit - * integers. - * This the simplest and fastest format for further post-processing. - * - * However, this leaves open the question of what is the order on the byte level, - * since little and big endian conventions will store the same number differently. - * - * The canonical representation settles this issue by mandating big-endian - * convention, the same convention as human-readable numbers (large digits first). - * - * When writing hash values to storage, sending them over a network, or printing - * them, it's highly recommended to use the canonical representation to ensure - * portability across a wider range of systems, present and future. - * - * The following functions allow transformation of hash values to and from - * canonical format. - */ - /*! * @brief Canonical (big endian) representation of @ref XXH32_hash_t. */ @@ -568,11 +733,13 @@ typedef struct { /*! * @brief Converts an @ref XXH32_hash_t to a big endian @ref XXH32_canonical_t. * - * @param dst The @ref XXH32_canonical_t pointer to be stored to. + * @param dst The @ref XXH32_canonical_t pointer to be stored to. * @param hash The @ref XXH32_hash_t to be converted. * * @pre * @p dst must not be `NULL`. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); @@ -585,44 +752,75 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t * @p src must not be `NULL`. * * @return The converted hash. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ -XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); +XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); +/*! @cond Doxygen ignores this part */ #ifdef __has_attribute # define XXH_HAS_ATTRIBUTE(x) __has_attribute(x) #else # define XXH_HAS_ATTRIBUTE(x) 0 #endif +/*! @endcond */ +/*! @cond Doxygen ignores this part */ +/* + * C23 __STDC_VERSION__ number hasn't been specified yet. For now + * leave as `201711L` (C17 + 1). + * TODO: Update to correct value when its been specified. + */ +#define XXH_C23_VN 201711L +/*! @endcond */ + +/*! @cond Doxygen ignores this part */ /* C-language Attributes are added in C23. */ -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute) +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= XXH_C23_VN) && defined(__has_c_attribute) # define XXH_HAS_C_ATTRIBUTE(x) __has_c_attribute(x) #else # define XXH_HAS_C_ATTRIBUTE(x) 0 #endif +/*! @endcond */ +/*! @cond Doxygen ignores this part */ #if defined(__cplusplus) && defined(__has_cpp_attribute) # define XXH_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) #else # define XXH_HAS_CPP_ATTRIBUTE(x) 0 #endif +/*! @endcond */ +/*! @cond Doxygen ignores this part */ /* -Define XXH_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute -introduced in CPP17 and C23. -CPP17 : https://en.cppreference.com/w/cpp/language/attributes/fallthrough -C23 : https://en.cppreference.com/w/c/language/attributes/fallthrough -*/ -#if XXH_HAS_C_ATTRIBUTE(x) -# define XXH_FALLTHROUGH [[fallthrough]] -#elif XXH_HAS_CPP_ATTRIBUTE(x) + * Define XXH_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute + * introduced in CPP17 and C23. + * CPP17 : https://en.cppreference.com/w/cpp/language/attributes/fallthrough + * C23 : https://en.cppreference.com/w/c/language/attributes/fallthrough + */ +#if XXH_HAS_C_ATTRIBUTE(fallthrough) || XXH_HAS_CPP_ATTRIBUTE(fallthrough) # define XXH_FALLTHROUGH [[fallthrough]] #elif XXH_HAS_ATTRIBUTE(__fallthrough__) -# define XXH_FALLTHROUGH __attribute__ ((fallthrough)) +# define XXH_FALLTHROUGH __attribute__ ((__fallthrough__)) #else -# define XXH_FALLTHROUGH +# define XXH_FALLTHROUGH /* fallthrough */ #endif +/*! @endcond */ + +/*! @cond Doxygen ignores this part */ +/* + * Define XXH_NOESCAPE for annotated pointers in public API. + * https://clang.llvm.org/docs/AttributeReference.html#noescape + * As of writing this, only supported by clang. + */ +#if XXH_HAS_ATTRIBUTE(noescape) +# define XXH_NOESCAPE __attribute__((noescape)) +#else +# define XXH_NOESCAPE +#endif +/*! @endcond */ + /*! * @} @@ -644,7 +842,11 @@ typedef uint64_t XXH64_hash_t; #elif !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include +# ifdef _AIX +# include +# else +# include +# endif typedef uint64_t XXH64_hash_t; #else # include @@ -660,7 +862,7 @@ typedef uint64_t XXH64_hash_t; /*! * @} * - * @defgroup xxh64_family XXH64 family + * @defgroup XXH64_family XXH64 family * @ingroup public * @{ * Contains functions used in the classic 64-bit xxHash algorithm. @@ -671,13 +873,9 @@ typedef uint64_t XXH64_hash_t; * It provides better speed for systems with vector processing capabilities. */ - /*! * @brief Calculates the 64-bit hash of @p input using xxHash64. * - * This function usually runs faster on 64-bit systems, but slower on 32-bit - * systems (see benchmark). - * * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. * @param seed The 64-bit seed to alter the hash's output predictably. @@ -687,41 +885,145 @@ typedef uint64_t XXH64_hash_t; * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return The calculated 64-bit hash. + * @return The calculated 64-bit xxHash64 value. * - * @see - * XXH32(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128(): - * Direct equivalents for the other variants of xxHash. - * @see - * XXH64_createState(), XXH64_update(), XXH64_digest(): Streaming version. + * @see @ref single_shot_example "Single Shot Example" for an example. */ -XXH_PUBLIC_API XXH64_hash_t XXH64(const void* input, size_t length, XXH64_hash_t seed); +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed); /******* Streaming *******/ +#ifndef XXH_NO_STREAM /*! * @brief The opaque state struct for the XXH64 streaming API. * * @see XXH64_state_s for details. */ typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ -XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void); + +/*! + * @brief Allocates an @ref XXH64_state_t. + * + * @return An allocated pointer of @ref XXH64_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH64_freeState(). + */ +XXH_PUBLIC_API XXH_MALLOCF XXH64_state_t* XXH64_createState(void); + +/*! + * @brief Frees an @ref XXH64_state_t. + * + * @param statePtr A pointer to an @ref XXH64_state_t allocated with @ref XXH64_createState(). + * + * @return @ref XXH_OK. + * + * @note @p statePtr must be allocated with XXH64_createState(). + */ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); -XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state); -XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, XXH64_hash_t seed); -XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); -XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr); +/*! + * @brief Copies one @ref XXH64_state_t to another. + * + * @param dst_state The state to copy to. + * @param src_state The state to copy from. + * @pre + * @p dst_state and @p src_state must not be `NULL` and must not overlap. + */ +XXH_PUBLIC_API void XXH64_copyState(XXH_NOESCAPE XXH64_state_t* dst_state, const XXH64_state_t* src_state); +/*! + * @brief Resets an @ref XXH64_state_t to begin a new hash. + * + * @param statePtr The state struct to reset. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note This function resets and seeds a state. Call it before @ref XXH64_update(). + */ +XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH_NOESCAPE XXH64_state_t* statePtr, XXH64_hash_t seed); + +/*! + * @brief Consumes a block of @p input to an @ref XXH64_state_t. + * + * @param statePtr The state struct to update. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + */ +XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH_NOESCAPE XXH64_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); + +/*! + * @brief Returns the calculated hash value from an @ref XXH64_state_t. + * + * @param statePtr The state struct to calculate the hash from. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return The calculated 64-bit xxHash64 value from that state. + * + * @note + * Calling XXH64_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + */ +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_digest (XXH_NOESCAPE const XXH64_state_t* statePtr); +#endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ + +/*! + * @brief Canonical (big endian) representation of @ref XXH64_hash_t. + */ typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t; -XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash); -XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src); + +/*! + * @brief Converts an @ref XXH64_hash_t to a big endian @ref XXH64_canonical_t. + * + * @param dst The @ref XXH64_canonical_t pointer to be stored to. + * @param hash The @ref XXH64_hash_t to be converted. + * + * @pre + * @p dst must not be `NULL`. + * + * @see @ref canonical_representation_example "Canonical Representation Example" + */ +XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, XXH64_hash_t hash); + +/*! + * @brief Converts an @ref XXH64_canonical_t to a native @ref XXH64_hash_t. + * + * @param src The @ref XXH64_canonical_t to convert. + * + * @pre + * @p src must not be `NULL`. + * + * @return The converted hash. + * + * @see @ref canonical_representation_example "Canonical Representation Example" + */ +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_canonical_t* src); #ifndef XXH_NO_XXH3 + /*! * @} * ************************************************************************ - * @defgroup xxh3_family XXH3 family + * @defgroup XXH3_family XXH3 family * @ingroup public * @{ * @@ -741,16 +1043,26 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src * * XXH3's speed benefits greatly from SIMD and 64-bit arithmetic, * but does not require it. - * Any 32-bit and 64-bit targets that can run XXH32 smoothly - * can run XXH3 at competitive speeds, even without vector support. - * Further details are explained in the implementation. + * Most 32-bit and 64-bit targets that can run XXH32 smoothly can run XXH3 + * at competitive speeds, even without vector support. Further details are + * explained in the implementation. * - * Optimized implementations are provided for AVX512, AVX2, SSE2, NEON, POWER8, - * ZVector and scalar targets. This can be controlled via the XXH_VECTOR macro. + * XXH3 has a fast scalar implementation, but it also includes accelerated SIMD + * implementations for many common platforms: + * - AVX512 + * - AVX2 + * - SSE2 + * - ARM NEON + * - WebAssembly SIMD128 + * - POWER8 VSX + * - s390x ZVector + * This can be controlled via the @ref XXH_VECTOR macro, but it automatically + * selects the best version according to predefined macros. For the x86 family, an + * automatic runtime dispatcher is included separately in @ref xxh_x86dispatch.c. * * XXH3 implementation is portable: * it has a generic C90 formulation that can be compiled on any platform, - * all implementations generage exactly the same hash value on all platforms. + * all implementations generate exactly the same hash value on all platforms. * Starting from v0.8.0, it's also labelled "stable", meaning that * any future version will also generate the same hash value. * @@ -762,24 +1074,59 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src * * The API supports one-shot hashing, streaming mode, and custom secrets. */ - /*-********************************************************************** * XXH3 64-bit variant ************************************************************************/ -/* XXH3_64bits(): - * default 64-bit variant, using default secret and default seed of 0. - * It's the fastest variant. */ -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* data, size_t len); - -/* - * XXH3_64bits_withSeed(): - * This variant generates a custom secret on the fly - * based on default secret altered using the `seed` value. - * While this operation is decently fast, note that it's not completely free. - * Note: seed==0 produces the same results as XXH3_64bits(). +/*! + * @brief Calculates 64-bit unseeded variant of XXH3 hash of @p input. + * + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 64-bit XXH3 hash value. + * + * @note + * This is equivalent to @ref XXH3_64bits_withSeed() with a seed of `0`, however + * it may have slightly better performance due to constant propagation of the + * defaults. + * + * @see + * XXH3_64bits_withSeed(), XXH3_64bits_withSecret(): other seeding variants + * @see @ref single_shot_example "Single Shot Example" for an example. */ -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, XXH64_hash_t seed); +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits(XXH_NOESCAPE const void* input, size_t length); + +/*! + * @brief Calculates 64-bit seeded variant of XXH3 hash of @p input. + * + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 64-bit XXH3 hash value. + * + * @note + * seed == 0 produces the same results as @ref XXH3_64bits(). + * + * This variant generates a custom secret on the fly based on default secret + * altered using the @p seed value. + * + * While this operation is decently fast, note that it's not completely free. + * + * @see @ref single_shot_example "Single Shot Example" for an example. + */ +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed); /*! * The bare minimum size for a custom secret. @@ -790,27 +1137,43 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, X */ #define XXH3_SECRET_SIZE_MIN 136 -/* - * XXH3_64bits_withSecret(): +/*! + * @brief Calculates 64-bit variant of XXH3 with a custom "secret". + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @return The calculated 64-bit XXH3 hash value. + * + * @pre + * The memory between @p data and @p data + @p len must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p data may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * * It's possible to provide any blob of bytes as a "secret" to generate the hash. * This makes it more difficult for an external actor to prepare an intentional collision. - * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN). + * The main condition is that @p secretSize *must* be large enough (>= @ref XXH3_SECRET_SIZE_MIN). * However, the quality of the secret impacts the dispersion of the hash algorithm. * Therefore, the secret _must_ look like a bunch of random bytes. * Avoid "trivial" or structured data such as repeated sequences or a text document. * Whenever in doubt about the "randomness" of the blob of bytes, - * consider employing "XXH3_generateSecret()" instead (see below). + * consider employing @ref XXH3_generateSecret() instead (see below). * It will generate a proper high entropy secret derived from the blob of bytes. * Another advantage of using XXH3_generateSecret() is that * it guarantees that all bits within the initial blob of bytes * will impact every bit of the output. * This is not necessarily the case when using the blob of bytes directly * because, when hashing _small_ inputs, only a portion of the secret is employed. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize); +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize); /******* Streaming *******/ +#ifndef XXH_NO_STREAM /* * Streaming requires state maintenance. * This operation costs memory and CPU. @@ -819,40 +1182,124 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, */ /*! - * @brief The state struct for the XXH3 streaming API. + * @brief The opaque state struct for the XXH3 streaming API. * * @see XXH3_state_s for details. */ typedef struct XXH3_state_s XXH3_state_t; -XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void); +XXH_PUBLIC_API XXH_MALLOCF XXH3_state_t* XXH3_createState(void); XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr); -XXH_PUBLIC_API void XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state); -/* - * XXH3_64bits_reset(): - * Initialize with default parameters. - * digest will be equivalent to `XXH3_64bits()`. +/*! + * @brief Copies one @ref XXH3_state_t to another. + * + * @param dst_state The state to copy to. + * @param src_state The state to copy from. + * @pre + * @p dst_state and @p src_state must not be `NULL` and must not overlap. */ -XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH3_state_t* statePtr); -/* - * XXH3_64bits_reset_withSeed(): - * Generate a custom secret from `seed`, and store it into `statePtr`. - * digest will be equivalent to `XXH3_64bits_withSeed()`. +XXH_PUBLIC_API void XXH3_copyState(XXH_NOESCAPE XXH3_state_t* dst_state, XXH_NOESCAPE const XXH3_state_t* src_state); + +/*! + * @brief Resets an @ref XXH3_state_t to begin a new hash. + * + * @param statePtr The state struct to reset. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret with default parameters. + * - Call this function before @ref XXH3_64bits_update(). + * - Digest will be equivalent to `XXH3_64bits()`. + * */ -XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed); -/* - * XXH3_64bits_reset_withSecret(): - * `secret` is referenced, it _must outlive_ the hash streaming session. - * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`, +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr); + +/*! + * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash. + * + * @param statePtr The state struct to reset. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret from `seed`. + * - Call this function before @ref XXH3_64bits_update(). + * - Digest will be equivalent to `XXH3_64bits_withSeed()`. + * + */ +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); + +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr The state struct to reset. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * `secret` is referenced, it _must outlive_ the hash streaming session. + * + * Similar to one-shot API, `secretSize` must be >= @ref XXH3_SECRET_SIZE_MIN, * and the quality of produced hash values depends on secret's entropy * (secret's content should look like a bunch of random bytes). * When in doubt about the randomness of a candidate `secret`, * consider employing `XXH3_generateSecret()` instead (see below). */ -XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize); +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize); -XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH3_state_t* statePtr, const void* input, size_t length); -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* statePtr); +/*! + * @brief Consumes a block of @p input to an @ref XXH3_state_t. + * + * @param statePtr The state struct to update. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + */ +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); + +/*! + * @brief Returns the calculated XXH3 64-bit hash value from an @ref XXH3_state_t. + * + * @param statePtr The state struct to calculate the hash from. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return The calculated XXH3 64-bit hash value from that state. + * + * @note + * Calling XXH3_64bits_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + */ +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr); +#endif /* !XXH_NO_STREAM */ /* note : canonical representation of XXH3 is the same as XXH64 * since they both produce XXH64_hash_t values */ @@ -873,11 +1320,76 @@ typedef struct { XXH64_hash_t high64; /*!< `value >> 64` */ } XXH128_hash_t; -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* data, size_t len); -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed); -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize); +/*! + * @brief Calculates 128-bit unseeded variant of XXH3 of @p data. + * + * @param data The block of data to be hashed, at least @p length bytes in size. + * @param len The length of @p data, in bytes. + * + * @return The calculated 128-bit variant of XXH3 value. + * + * The 128-bit variant of XXH3 has more strength, but it has a bit of overhead + * for shorter inputs. + * + * This is equivalent to @ref XXH3_128bits_withSeed() with a seed of `0`, however + * it may have slightly better performance due to constant propagation of the + * defaults. + * + * @see XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants + * @see @ref single_shot_example "Single Shot Example" for an example. + */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits(XXH_NOESCAPE const void* data, size_t len); +/*! @brief Calculates 128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The block of data to be hashed, at least @p length bytes in size. + * @param len The length of @p data, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @return The calculated 128-bit variant of XXH3 value. + * + * @note + * seed == 0 produces the same results as @ref XXH3_64bits(). + * + * This variant generates a custom secret on the fly based on default secret + * altered using the @p seed value. + * + * While this operation is decently fast, note that it's not completely free. + * + * @see XXH3_128bits(), XXH3_128bits_withSecret(): other seeding variants + * @see @ref single_shot_example "Single Shot Example" for an example. + */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSeed(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed); +/*! + * @brief Calculates 128-bit variant of XXH3 with a custom "secret". + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @return The calculated 128-bit variant of XXH3 value. + * + * It's possible to provide any blob of bytes as a "secret" to generate the hash. + * This makes it more difficult for an external actor to prepare an intentional collision. + * The main condition is that @p secretSize *must* be large enough (>= @ref XXH3_SECRET_SIZE_MIN). + * However, the quality of the secret impacts the dispersion of the hash algorithm. + * Therefore, the secret _must_ look like a bunch of random bytes. + * Avoid "trivial" or structured data such as repeated sequences or a text document. + * Whenever in doubt about the "randomness" of the blob of bytes, + * consider employing @ref XXH3_generateSecret() instead (see below). + * It will generate a proper high entropy secret derived from the blob of bytes. + * Another advantage of using XXH3_generateSecret() is that + * it guarantees that all bits within the initial blob of bytes + * will impact every bit of the output. + * This is not necessarily the case when using the blob of bytes directly + * because, when hashing _small_ inputs, only a portion of the secret is employed. + * + * @see @ref single_shot_example "Single Shot Example" for an example. + */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize); /******* Streaming *******/ +#ifndef XXH_NO_STREAM /* * Streaming requires state maintenance. * This operation costs memory and CPU. @@ -890,39 +1402,163 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSecret(const void* data, size_t le * All reset and streaming functions have same meaning as their 64-bit counterpart. */ -XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH3_state_t* statePtr); -XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed); -XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize); +/*! + * @brief Resets an @ref XXH3_state_t to begin a new hash. + * + * @param statePtr The state struct to reset. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret with default parameters. + * - Call it before @ref XXH3_128bits_update(). + * - Digest will be equivalent to `XXH3_128bits()`. + */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr); -XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH3_state_t* statePtr, const void* input, size_t length); -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* statePtr); +/*! + * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash. + * + * @param statePtr The state struct to reset. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret from `seed`. + * - Call it before @ref XXH3_128bits_update(). + * - Digest will be equivalent to `XXH3_128bits_withSeed()`. + */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr The state struct to reset. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * `secret` is referenced, it _must outlive_ the hash streaming session. + * Similar to one-shot API, `secretSize` must be >= @ref XXH3_SECRET_SIZE_MIN, + * and the quality of produced hash values depends on secret's entropy + * (secret's content should look like a bunch of random bytes). + * When in doubt about the randomness of a candidate `secret`, + * consider employing `XXH3_generateSecret()` instead (see below). + */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize); + +/*! + * @brief Consumes a block of @p input to an @ref XXH3_state_t. + * + * Call this to incrementally consume blocks of data. + * + * @param statePtr The state struct to update. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); + +/*! + * @brief Returns the calculated XXH3 128-bit hash value from an @ref XXH3_state_t. + * + * @param statePtr The state struct to calculate the hash from. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return The calculated XXH3 128-bit hash value from that state. + * + * @note + * Calling XXH3_128bits_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr); +#endif /* !XXH_NO_STREAM */ /* Following helper functions make it possible to compare XXH128_hast_t values. * Since XXH128_hash_t is a structure, this capability is not offered by the language. * Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */ /*! - * XXH128_isEqual(): - * Return: 1 if `h1` and `h2` are equal, 0 if they are not. + * @brief Check equality of two XXH128_hash_t values + * + * @param h1 The 128-bit hash value. + * @param h2 Another 128-bit hash value. + * + * @return `1` if `h1` and `h2` are equal. + * @return `0` if they are not. */ -XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2); +XXH_PUBLIC_API XXH_PUREF int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2); /*! - * XXH128_cmp(): + * @brief Compares two @ref XXH128_hash_t * * This comparator is compatible with stdlib's `qsort()`/`bsearch()`. * - * return: >0 if *h128_1 > *h128_2 - * =0 if *h128_1 == *h128_2 - * <0 if *h128_1 < *h128_2 + * @param h128_1 Left-hand side value + * @param h128_2 Right-hand side value + * + * @return >0 if @p h128_1 > @p h128_2 + * @return =0 if @p h128_1 == @p h128_2 + * @return <0 if @p h128_1 < @p h128_2 */ -XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2); +XXH_PUBLIC_API XXH_PUREF int XXH128_cmp(XXH_NOESCAPE const void* h128_1, XXH_NOESCAPE const void* h128_2); /******* Canonical representation *******/ typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical_t; -XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash); -XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* src); + + +/*! + * @brief Converts an @ref XXH128_hash_t to a big endian @ref XXH128_canonical_t. + * + * @param dst The @ref XXH128_canonical_t pointer to be stored to. + * @param hash The @ref XXH128_hash_t to be converted. + * + * @pre + * @p dst must not be `NULL`. + * @see @ref canonical_representation_example "Canonical Representation Example" + */ +XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* dst, XXH128_hash_t hash); + +/*! + * @brief Converts an @ref XXH128_canonical_t to a native @ref XXH128_hash_t. + * + * @param src The @ref XXH128_canonical_t to convert. + * + * @pre + * @p src must not be `NULL`. + * + * @return The converted hash. + * @see @ref canonical_representation_example "Canonical Representation Example" + */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE const XXH128_canonical_t* src); #endif /* !XXH_NO_XXH3 */ @@ -996,7 +1632,6 @@ struct XXH64_state_s { XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it. */ }; /* typedef'd to XXH64_state_t */ - #ifndef XXH_NO_XXH3 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* >= C11 */ @@ -1032,6 +1667,7 @@ struct XXH64_state_s { #define XXH3_INTERNALBUFFER_SIZE 256 /*! + * @internal * @brief Default size of the secret buffer (and @ref XXH3_kSecret). * * This is the size used in @ref XXH3_kSecret and the seeded functions. @@ -1064,7 +1700,7 @@ struct XXH64_state_s { */ struct XXH3_state_s { XXH_ALIGN_MEMBER(64, XXH64_hash_t acc[8]); - /*!< The 8 accumulators. Similar to `vN` in @ref XXH32_state_s::v1 and @ref XXH64_state_s */ + /*!< The 8 accumulators. See @ref XXH32_state_s::v and @ref XXH64_state_s::v */ XXH_ALIGN_MEMBER(64, unsigned char customSecret[XXH3_SECRET_DEFAULT_SIZE]); /*!< Used to store a custom secret generated from a seed. */ XXH_ALIGN_MEMBER(64, unsigned char buffer[XXH3_INTERNALBUFFER_SIZE]); @@ -1104,69 +1740,148 @@ struct XXH3_state_s { * Note that this doesn't prepare the state for a streaming operation, * it's still necessary to use XXH3_NNbits_reset*() afterwards. */ -#define XXH3_INITSTATE(XXH3_state_ptr) { (XXH3_state_ptr)->seed = 0; } +#define XXH3_INITSTATE(XXH3_state_ptr) \ + do { \ + XXH3_state_t* tmp_xxh3_state_ptr = (XXH3_state_ptr); \ + tmp_xxh3_state_ptr->seed = 0; \ + tmp_xxh3_state_ptr->extSecret = NULL; \ + } while(0) -/* XXH128() : - * simple alias to pre-selected XXH3_128bits variant +/*! + * @brief Calculates the 128-bit hash of @p data using XXH3. + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param seed The 64-bit seed to alter the hash's output predictably. + * + * @pre + * The memory between @p data and @p data + @p len must be valid, + * readable, contiguous memory. However, if @p len is `0`, @p data may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 128-bit XXH3 value. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ -XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed); +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed); /* === Experimental API === */ /* Symbols defined below must be considered tied to a specific library version. */ -/* - * XXH3_generateSecret(): +/*! + * @brief Derive a high-entropy secret from any user-defined content, named customSeed. + * + * @param secretBuffer A writable buffer for derived high-entropy secret data. + * @param secretSize Size of secretBuffer, in bytes. Must be >= XXH3_SECRET_DEFAULT_SIZE. + * @param customSeed A user-defined content. + * @param customSeedSize Size of customSeed, in bytes. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. * - * Derive a high-entropy secret from any user-defined content, named customSeed. * The generated secret can be used in combination with `*_withSecret()` functions. - * The `_withSecret()` variants are useful to provide a higher level of protection than 64-bit seed, - * as it becomes much more difficult for an external actor to guess how to impact the calculation logic. + * The `_withSecret()` variants are useful to provide a higher level of protection + * than 64-bit seed, as it becomes much more difficult for an external actor to + * guess how to impact the calculation logic. * * The function accepts as input a custom seed of any length and any content, - * and derives from it a high-entropy secret of length @secretSize - * into an already allocated buffer @secretBuffer. - * @secretSize must be >= XXH3_SECRET_SIZE_MIN + * and derives from it a high-entropy secret of length @p secretSize into an + * already allocated buffer @p secretBuffer. * * The generated secret can then be used with any `*_withSecret()` variant. - * Functions `XXH3_128bits_withSecret()`, `XXH3_64bits_withSecret()`, - * `XXH3_128bits_reset_withSecret()` and `XXH3_64bits_reset_withSecret()` + * The functions @ref XXH3_128bits_withSecret(), @ref XXH3_64bits_withSecret(), + * @ref XXH3_128bits_reset_withSecret() and @ref XXH3_64bits_reset_withSecret() * are part of this list. They all accept a `secret` parameter - * which must be large enough for implementation reasons (>= XXH3_SECRET_SIZE_MIN) + * which must be large enough for implementation reasons (>= @ref XXH3_SECRET_SIZE_MIN) * _and_ feature very high entropy (consist of random-looking bytes). - * These conditions can be a high bar to meet, so - * XXH3_generateSecret() can be employed to ensure proper quality. + * These conditions can be a high bar to meet, so @ref XXH3_generateSecret() can + * be employed to ensure proper quality. * - * customSeed can be anything. It can have any size, even small ones, - * and its content can be anything, even "poor entropy" sources such as a bunch of zeroes. - * The resulting `secret` will nonetheless provide all required qualities. + * @p customSeed can be anything. It can have any size, even small ones, + * and its content can be anything, even "poor entropy" sources such as a bunch + * of zeroes. The resulting `secret` will nonetheless provide all required qualities. * - * When customSeedSize > 0, supplying NULL as customSeed is undefined behavior. + * @pre + * - @p secretSize must be >= @ref XXH3_SECRET_SIZE_MIN + * - When @p customSeedSize > 0, supplying NULL as customSeed is undefined behavior. + * + * Example code: + * @code{.c} + * #include + * #include + * #include + * #define XXH_STATIC_LINKING_ONLY // expose unstable API + * #include "xxhash.h" + * // Hashes argv[2] using the entropy from argv[1]. + * int main(int argc, char* argv[]) + * { + * char secret[XXH3_SECRET_SIZE_MIN]; + * if (argv != 3) { return 1; } + * XXH3_generateSecret(secret, sizeof(secret), argv[1], strlen(argv[1])); + * XXH64_hash_t h = XXH3_64bits_withSecret( + * argv[2], strlen(argv[2]), + * secret, sizeof(secret) + * ); + * printf("%016llx\n", (unsigned long long) h); + * } + * @endcode */ -XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize); +XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer, size_t secretSize, XXH_NOESCAPE const void* customSeed, size_t customSeedSize); - -/* - * XXH3_generateSecret_fromSeed(): +/*! + * @brief Generate the same secret as the _withSeed() variants. * - * Generate the same secret as the _withSeed() variants. - * - * The resulting secret has a length of XXH3_SECRET_DEFAULT_SIZE (necessarily). - * @secretBuffer must be already allocated, of size at least XXH3_SECRET_DEFAULT_SIZE bytes. + * @param secretBuffer A writable buffer of @ref XXH3_SECRET_SIZE_MIN bytes + * @param seed The 64-bit seed to alter the hash result predictably. * * The generated secret can be used in combination with *`*_withSecret()` and `_withSecretandSeed()` variants. - * This generator is notably useful in combination with `_withSecretandSeed()`, - * as a way to emulate a faster `_withSeed()` variant. + * + * Example C++ `std::string` hash class: + * @code{.cpp} + * #include + * #define XXH_STATIC_LINKING_ONLY // expose unstable API + * #include "xxhash.h" + * // Slow, seeds each time + * class HashSlow { + * XXH64_hash_t seed; + * public: + * HashSlow(XXH64_hash_t s) : seed{s} {} + * size_t operator()(const std::string& x) const { + * return size_t{XXH3_64bits_withSeed(x.c_str(), x.length(), seed)}; + * } + * }; + * // Fast, caches the seeded secret for future uses. + * class HashFast { + * unsigned char secret[XXH3_SECRET_SIZE_MIN]; + * public: + * HashFast(XXH64_hash_t s) { + * XXH3_generateSecret_fromSeed(secret, seed); + * } + * size_t operator()(const std::string& x) const { + * return size_t{ + * XXH3_64bits_withSecret(x.c_str(), x.length(), secret, sizeof(secret)) + * }; + * } + * }; + * @endcode */ -XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed); +XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(XXH_NOESCAPE void* secretBuffer, XXH64_hash_t seed); -/* - * *_withSecretandSeed() : +/*! + * @brief Calculates 64/128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. + * * These variants generate hash values using either - * @seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes) - * or @secret for "large" keys (>= XXH3_MIDSIZE_MAX). + * @p seed for "short" keys (< @ref XXH3_MIDSIZE_MAX = 240 bytes) + * or @p secret for "large" keys (>= @ref XXH3_MIDSIZE_MAX). * * This generally benefits speed, compared to `_withSeed()` or `_withSecret()`. * `_withSeed()` has to generate the secret on the fly for "large" keys. @@ -1175,7 +1890,7 @@ XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_ * which requires more instructions than _withSeed() variants. * Therefore, _withSecretandSeed variant combines the best of both worlds. * - * When @secret has been generated by XXH3_generateSecret_fromSeed(), + * When @p secret has been generated by XXH3_generateSecret_fromSeed(), * this variant produces *exactly* the same results as `_withSeed()` variant, * hence offering only a pure speed benefit on "large" input, * by skipping the need to regenerate the secret for every large input. @@ -1184,33 +1899,71 @@ XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_ * for example with XXH3_64bits(), which then becomes the seed, * and then employ both the seed and the secret in _withSecretandSeed(). * On top of speed, an added benefit is that each bit in the secret - * has a 50% chance to swap each bit in the output, - * via its impact to the seed. + * has a 50% chance to swap each bit in the output, via its impact to the seed. + * * This is not guaranteed when using the secret directly in "small data" scenarios, * because only portions of the secret are employed for small data. */ -XXH_PUBLIC_API XXH64_hash_t -XXH3_64bits_withSecretandSeed(const void* data, size_t len, - const void* secret, size_t secretSize, +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t +XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* data, size_t len, + XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed); - -XXH_PUBLIC_API XXH128_hash_t -XXH3_128bits_withSecretandSeed(const void* data, size_t len, - const void* secret, size_t secretSize, +/*! + * @brief Calculates 128-bit seeded variant of XXH3 hash of @p data. + * + * @param input The block of data to be hashed, at least @p len bytes in size. + * @param length The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed() + */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t +XXH3_128bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, + XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); - +#ifndef XXH_NO_STREAM +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed() + */ XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr, - const void* secret, size_t secretSize, +XXH3_64bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, + XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); - +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed() + */ XXH_PUBLIC_API XXH_errorcode -XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, - const void* secret, size_t secretSize, +XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, + XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); +#endif /* !XXH_NO_STREAM */ - -#endif /* XXH_NO_XXH3 */ +#endif /* !XXH_NO_XXH3 */ #endif /* XXH_NO_LONG_LONG */ #if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) # define XXH_IMPLEMENTATION @@ -1264,7 +2017,7 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, /*! * @brief Define this to disable 64-bit code. * - * Useful if only using the @ref xxh32_family and you have a strict C90 compiler. + * Useful if only using the @ref XXH32_family and you have a strict C90 compiler. */ # define XXH_NO_LONG_LONG # undef XXH_NO_LONG_LONG /* don't actually */ @@ -1287,7 +2040,7 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, * Use `memcpy()`. Safe and portable. Note that most modern compilers will * eliminate the function call and treat it as an unaligned access. * - * - `XXH_FORCE_MEMORY_ACCESS=1`: `__attribute__((packed))` + * - `XXH_FORCE_MEMORY_ACCESS=1`: `__attribute__((aligned(1)))` * @par * Depends on compiler extensions and is therefore not portable. * This method is safe _if_ your compiler supports it, @@ -1307,7 +2060,7 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, * inline small `memcpy()` calls, and it might also be faster on big-endian * systems which lack a native byteswap instruction. However, some compilers * will emit literal byteshifts even if the target supports unaligned access. - * . + * * * @warning * Methods 1 and 2 rely on implementation-defined behavior. Use these with @@ -1320,6 +2073,34 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, */ # define XXH_FORCE_MEMORY_ACCESS 0 +/*! + * @def XXH_SIZE_OPT + * @brief Controls how much xxHash optimizes for size. + * + * xxHash, when compiled, tends to result in a rather large binary size. This + * is mostly due to heavy usage to forced inlining and constant folding of the + * @ref XXH3_family to increase performance. + * + * However, some developers prefer size over speed. This option can + * significantly reduce the size of the generated code. When using the `-Os` + * or `-Oz` options on GCC or Clang, this is defined to 1 by default, + * otherwise it is defined to 0. + * + * Most of these size optimizations can be controlled manually. + * + * This is a number from 0-2. + * - `XXH_SIZE_OPT` == 0: Default. xxHash makes no size optimizations. Speed + * comes first. + * - `XXH_SIZE_OPT` == 1: Default for `-Os` and `-Oz`. xxHash is more + * conservative and disables hacks that increase code size. It implies the + * options @ref XXH_NO_INLINE_HINTS == 1, @ref XXH_FORCE_ALIGN_CHECK == 0, + * and @ref XXH3_NEON_LANES == 8 if they are not already defined. + * - `XXH_SIZE_OPT` == 2: xxHash tries to make itself as small as possible. + * Performance may cry. For example, the single shot functions just use the + * streaming API. + */ +# define XXH_SIZE_OPT 0 + /*! * @def XXH_FORCE_ALIGN_CHECK * @brief If defined to non-zero, adds a special path for aligned inputs (XXH32() @@ -1341,9 +2122,11 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, * * In these cases, the alignment check can be removed by setting this macro to 0. * Then the code will always use unaligned memory access. - * Align check is automatically disabled on x86, x64 & arm64, + * Align check is automatically disabled on x86, x64, ARM64, and some ARM chips * which are platforms known to offer good unaligned memory accesses performance. * + * It is also disabled by default when @ref XXH_SIZE_OPT >= 1. + * * This option does not affect XXH3 (only XXH32 and XXH64). */ # define XXH_FORCE_ALIGN_CHECK 0 @@ -1365,11 +2148,28 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, * XXH_NO_INLINE_HINTS marks all internal functions as static, giving the * compiler full control on whether to inline or not. * - * When not optimizing (-O0), optimizing for size (-Os, -Oz), or using - * -fno-inline with GCC or Clang, this will automatically be defined. + * When not optimizing (-O0), using `-fno-inline` with GCC or Clang, or if + * @ref XXH_SIZE_OPT >= 1, this will automatically be defined. */ # define XXH_NO_INLINE_HINTS 0 +/*! + * @def XXH3_INLINE_SECRET + * @brief Determines whether to inline the XXH3 withSecret code. + * + * When the secret size is known, the compiler can improve the performance + * of XXH3_64bits_withSecret() and XXH3_128bits_withSecret(). + * + * However, if the secret size is not known, it doesn't have any benefit. This + * happens when xxHash is compiled into a global symbol. Therefore, if + * @ref XXH_INLINE_ALL is *not* defined, this will be defined to 0. + * + * Additionally, this defaults to 0 on GCC 12+, which has an issue with function pointers + * that are *sometimes* force inline on -Og, and it is impossible to automatically + * detect this optimization level. + */ +# define XXH3_INLINE_SECRET 0 + /*! * @def XXH32_ENDJMP * @brief Whether to use a jump for `XXH32_finalize`. @@ -1391,34 +2191,45 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, */ # define XXH_OLD_NAMES # undef XXH_OLD_NAMES /* don't actually use, it is ugly. */ + +/*! + * @def XXH_NO_STREAM + * @brief Disables the streaming API. + * + * When xxHash is not inlined and the streaming functions are not used, disabling + * the streaming functions can improve code size significantly, especially with + * the @ref XXH3_family which tends to make constant folded copies of itself. + */ +# define XXH_NO_STREAM +# undef XXH_NO_STREAM /* don't actually */ #endif /* XXH_DOXYGEN */ /*! * @} */ #ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ - /* prefer __packed__ structures (method 1) for gcc on armv7+ and mips */ -# if !defined(__clang__) && \ -( \ - (defined(__INTEL_COMPILER) && !defined(_WIN32)) || \ - ( \ - defined(__GNUC__) && ( \ - (defined(__ARM_ARCH) && __ARM_ARCH >= 7) || \ - ( \ - defined(__mips__) && \ - (__mips <= 5 || __mips_isa_rev < 6) && \ - (!defined(__mips16) || defined(__mips_mips16e2)) \ - ) \ - ) \ - ) \ -) + /* prefer __packed__ structures (method 1) for GCC + * < ARMv7 with unaligned access (e.g. Raspbian armhf) still uses byte shifting, so we use memcpy + * which for some reason does unaligned loads. */ +# if defined(__GNUC__) && !(defined(__ARM_ARCH) && __ARM_ARCH < 7 && defined(__ARM_FEATURE_UNALIGNED)) # define XXH_FORCE_MEMORY_ACCESS 1 # endif #endif +#ifndef XXH_SIZE_OPT + /* default to 1 for -Os or -Oz */ +# if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE_SIZE__) +# define XXH_SIZE_OPT 1 +# else +# define XXH_SIZE_OPT 0 +# endif +#endif + #ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ -# if defined(__i386) || defined(__x86_64__) || defined(__aarch64__) \ - || defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64) /* visual */ + /* don't check on sizeopt, x86, aarch64, or arm when unaligned access is available */ +# if XXH_SIZE_OPT >= 1 || \ + defined(__i386) || defined(__x86_64__) || defined(__aarch64__) || defined(__ARM_FEATURE_UNALIGNED) \ + || defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64) || defined(_M_ARM) /* visual */ # define XXH_FORCE_ALIGN_CHECK 0 # else # define XXH_FORCE_ALIGN_CHECK 1 @@ -1426,14 +2237,22 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, #endif #ifndef XXH_NO_INLINE_HINTS -# if defined(__OPTIMIZE_SIZE__) /* -Os, -Oz */ \ - || defined(__NO_INLINE__) /* -O0, -fno-inline */ +# if XXH_SIZE_OPT >= 1 || defined(__NO_INLINE__) /* -O0, -fno-inline */ # define XXH_NO_INLINE_HINTS 1 # else # define XXH_NO_INLINE_HINTS 0 # endif #endif +#ifndef XXH3_INLINE_SECRET +# if (defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 12) \ + || !defined(XXH_INLINE_ALL) +# define XXH3_INLINE_SECRET 0 +# else +# define XXH3_INLINE_SECRET 1 +# endif +#endif + #ifndef XXH32_ENDJMP /* generally preferable for performance */ # define XXH32_ENDJMP 0 @@ -1448,13 +2267,56 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, /* ************************************* * Includes & Memory related functions ***************************************/ -/* Modify the local functions below should you wish to use some other memory routines */ -/* for ZSTD_malloc(), ZSTD_free() */ -#define ZSTD_DEPS_NEED_MALLOC -#include "zstd_deps.h" /* size_t, ZSTD_malloc, ZSTD_free, ZSTD_memcpy */ -static void* XXH_malloc(size_t s) { return ZSTD_malloc(s); } -static void XXH_free (void* p) { ZSTD_free(p); } -static void* XXH_memcpy(void* dest, const void* src, size_t size) { return ZSTD_memcpy(dest,src,size); } +#if defined(XXH_NO_STREAM) +/* nothing */ +#elif defined(XXH_NO_STDLIB) + +/* When requesting to disable any mention of stdlib, + * the library loses the ability to invoked malloc / free. + * In practice, it means that functions like `XXH*_createState()` + * will always fail, and return NULL. + * This flag is useful in situations where + * xxhash.h is integrated into some kernel, embedded or limited environment + * without access to dynamic allocation. + */ + +static XXH_CONSTF void* XXH_malloc(size_t s) { (void)s; return NULL; } +static void XXH_free(void* p) { (void)p; } + +#else + +/* + * Modify the local functions below should you wish to use + * different memory routines for malloc() and free() + */ +#include + +/*! + * @internal + * @brief Modify this function to use a different routine than malloc(). + */ +static XXH_MALLOCF void* XXH_malloc(size_t s) { return malloc(s); } + +/*! + * @internal + * @brief Modify this function to use a different routine than free(). + */ +static void XXH_free(void* p) { free(p); } + +#endif /* XXH_NO_STDLIB */ + +#include + +/*! + * @internal + * @brief Modify this function to use a different routine than memcpy(). + */ +static void* XXH_memcpy(void* dest, const void* src, size_t size) +{ + return memcpy(dest,src,size); +} + +#include /* ULLONG_MAX */ /* ************************************* @@ -1487,6 +2349,11 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) { return ZSTD_ # define XXH_NO_INLINE static #endif +#if XXH3_INLINE_SECRET +# define XXH3_WITH_SECRET_INLINE XXH_FORCE_INLINE +#else +# define XXH3_WITH_SECRET_INLINE XXH_NO_INLINE +#endif /* ************************************* @@ -1512,14 +2379,17 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) { return ZSTD_ # include /* note: can still be disabled with NDEBUG */ # define XXH_ASSERT(c) assert(c) #else -# define XXH_ASSERT(c) ((void)0) +# if defined(__INTEL_COMPILER) +# define XXH_ASSERT(c) XXH_ASSUME((unsigned char) (c)) +# else +# define XXH_ASSERT(c) XXH_ASSUME(c) +# endif #endif /* note: use after variable declarations */ #ifndef XXH_STATIC_ASSERT # if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */ -# include -# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0) +# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { _Static_assert((c),m); } while(0) # elif defined(__cplusplus) && (__cplusplus >= 201103L) /* C++11 */ # define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0) # else @@ -1534,7 +2404,7 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) { return ZSTD_ * @brief Used to prevent unwanted optimizations for @p var. * * It uses an empty GCC inline assembly statement with a register constraint - * which forces @p var into a general purpose register (e.g. eax, ebx, ecx + * which forces @p var into a general purpose register (eg eax, ebx, ecx * on x86) and marks it as modified. * * This is used in a few places to avoid unwanted autovectorization (e.g. @@ -1545,18 +2415,30 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) { return ZSTD_ * XXH3_initCustomSecret_scalar(). */ #if defined(__GNUC__) || defined(__clang__) -# define XXH_COMPILER_GUARD(var) __asm__ __volatile__("" : "+r" (var)) +# define XXH_COMPILER_GUARD(var) __asm__("" : "+r" (var)) #else # define XXH_COMPILER_GUARD(var) ((void)0) #endif +/* Specifically for NEON vectors which use the "w" constraint, on + * Clang. */ +#if defined(__clang__) && defined(__ARM_ARCH) && !defined(__wasm__) +# define XXH_COMPILER_GUARD_CLANG_NEON(var) __asm__("" : "+w" (var)) +#else +# define XXH_COMPILER_GUARD_CLANG_NEON(var) ((void)0) +#endif + /* ************************************* * Basic Types ***************************************/ #if !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include +# ifdef _AIX +# include +# else +# include +# endif typedef uint8_t xxh_u8; #else typedef unsigned char xxh_u8; @@ -1564,6 +2446,7 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) { return ZSTD_ typedef XXH32_hash_t xxh_u32; #ifdef XXH_OLD_NAMES +# warning "XXH_OLD_NAMES is planned to be removed starting v0.9. If the program depends on it, consider moving away from it by employing newer type names directly" # define BYTE xxh_u8 # define U8 xxh_u8 # define U32 xxh_u32 @@ -1637,18 +2520,19 @@ static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) /* - * __pack instructions are safer but compiler specific, hence potentially - * problematic for some compilers. - * - * Currently only defined for GCC and ICC. + * __attribute__((aligned(1))) is supported by gcc and clang. Originally the + * documentation claimed that it only increased the alignment, but actually it + * can decrease it on gcc, clang, and icc: + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69502, + * https://gcc.godbolt.org/z/xYez1j67Y. */ #ifdef XXH_OLD_NAMES typedef union { xxh_u32 u32; } __attribute__((packed)) unalign; #endif static xxh_u32 XXH_read32(const void* ptr) { - typedef union { xxh_u32 u32; } __attribute__((packed)) xxh_unalign; - return ((const xxh_unalign*)ptr)->u32; + typedef __attribute__((aligned(1))) xxh_u32 xxh_unalign32; + return *((const xxh_unalign32*)ptr); } #else @@ -1731,6 +2615,51 @@ static int XXH_isLittleEndian(void) # define XXH_HAS_BUILTIN(x) 0 #endif + + +/* + * C23 and future versions have standard "unreachable()". + * Once it has been implemented reliably we can add it as an + * additional case: + * + * ``` + * #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= XXH_C23_VN) + * # include + * # ifdef unreachable + * # define XXH_UNREACHABLE() unreachable() + * # endif + * #endif + * ``` + * + * Note C++23 also has std::unreachable() which can be detected + * as follows: + * ``` + * #if defined(__cpp_lib_unreachable) && (__cpp_lib_unreachable >= 202202L) + * # include + * # define XXH_UNREACHABLE() std::unreachable() + * #endif + * ``` + * NB: `__cpp_lib_unreachable` is defined in the `` header. + * We don't use that as including `` in `extern "C"` blocks + * doesn't work on GCC12 + */ + +#if XXH_HAS_BUILTIN(__builtin_unreachable) +# define XXH_UNREACHABLE() __builtin_unreachable() + +#elif defined(_MSC_VER) +# define XXH_UNREACHABLE() __assume(0) + +#else +# define XXH_UNREACHABLE() +#endif + +#if XXH_HAS_BUILTIN(__builtin_assume) +# define XXH_ASSUME(c) __builtin_assume(c) +#else +# define XXH_ASSUME(c) if (!(c)) { XXH_UNREACHABLE(); } +#endif + /*! * @internal * @def XXH_rotl32(x,r) @@ -1853,8 +2782,10 @@ XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } *********************************************************************/ /*! * @} - * @defgroup xxh32_impl XXH32 implementation + * @defgroup XXH32_impl XXH32 implementation * @ingroup impl + * + * Details on the XXH32 implementation. * @{ */ /* #define instead of static const, to be used as initializers */ @@ -1888,7 +2819,7 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) acc += input * XXH_PRIME32_2; acc = XXH_rotl32(acc, 13); acc *= XXH_PRIME32_1; -#if (defined(__SSE4_1__) || defined(__aarch64__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) +#if (defined(__SSE4_1__) || defined(__aarch64__) || defined(__wasm_simd128__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) /* * UGLY HACK: * A compiler fence is the only thing that prevents GCC and Clang from @@ -1918,9 +2849,12 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) * can load data, while v3 can multiply. SSE forces them to operate * together. * - * This is also enabled on AArch64, as Clang autovectorizes it incorrectly - * and it is pointless writing a NEON implementation that is basically the - * same speed as scalar for XXH32. + * This is also enabled on AArch64, as Clang is *very aggressive* in vectorizing + * the loop. NEON is only faster on the A53, and with the newer cores, it is less + * than half the speed. + * + * Additionally, this is used on WASM SIMD128 because it JITs to the same + * SIMD instructions and has the same issue. */ XXH_COMPILER_GUARD(acc); #endif @@ -1934,17 +2868,17 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) * The final mix ensures that all input bits have a chance to impact any bit in * the output digest, resulting in an unbiased distribution. * - * @param h32 The hash to avalanche. + * @param hash The hash to avalanche. * @return The avalanched hash. */ -static xxh_u32 XXH32_avalanche(xxh_u32 h32) +static xxh_u32 XXH32_avalanche(xxh_u32 hash) { - h32 ^= h32 >> 15; - h32 *= XXH_PRIME32_2; - h32 ^= h32 >> 13; - h32 *= XXH_PRIME32_3; - h32 ^= h32 >> 16; - return(h32); + hash ^= hash >> 15; + hash *= XXH_PRIME32_2; + hash ^= hash >> 13; + hash *= XXH_PRIME32_3; + hash ^= hash >> 16; + return hash; } #define XXH_get32bits(p) XXH_readLE32_align(p, align) @@ -1957,24 +2891,25 @@ static xxh_u32 XXH32_avalanche(xxh_u32 h32) * This final stage will digest them to ensure that all input bytes are present * in the final mix. * - * @param h32 The hash to finalize. + * @param hash The hash to finalize. * @param ptr The pointer to the remaining input. * @param len The remaining length, modulo 16. * @param align Whether @p ptr is aligned. * @return The finalized hash. + * @see XXH64_finalize(). */ -static xxh_u32 -XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align) +static XXH_PUREF xxh_u32 +XXH32_finalize(xxh_u32 hash, const xxh_u8* ptr, size_t len, XXH_alignment align) { -#define XXH_PROCESS1 do { \ - h32 += (*ptr++) * XXH_PRIME32_5; \ - h32 = XXH_rotl32(h32, 11) * XXH_PRIME32_1; \ +#define XXH_PROCESS1 do { \ + hash += (*ptr++) * XXH_PRIME32_5; \ + hash = XXH_rotl32(hash, 11) * XXH_PRIME32_1; \ } while (0) -#define XXH_PROCESS4 do { \ - h32 += XXH_get32bits(ptr) * XXH_PRIME32_3; \ - ptr += 4; \ - h32 = XXH_rotl32(h32, 17) * XXH_PRIME32_4; \ +#define XXH_PROCESS4 do { \ + hash += XXH_get32bits(ptr) * XXH_PRIME32_3; \ + ptr += 4; \ + hash = XXH_rotl32(hash, 17) * XXH_PRIME32_4; \ } while (0) if (ptr==NULL) XXH_ASSERT(len == 0); @@ -1990,49 +2925,49 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align) XXH_PROCESS1; --len; } - return XXH32_avalanche(h32); + return XXH32_avalanche(hash); } else { switch(len&15) /* or switch(bEnd - p) */ { case 12: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 8: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 4: XXH_PROCESS4; - return XXH32_avalanche(h32); + return XXH32_avalanche(hash); case 13: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 9: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 5: XXH_PROCESS4; XXH_PROCESS1; - return XXH32_avalanche(h32); + return XXH32_avalanche(hash); case 14: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 10: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 6: XXH_PROCESS4; XXH_PROCESS1; XXH_PROCESS1; - return XXH32_avalanche(h32); + return XXH32_avalanche(hash); case 15: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 11: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 7: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 3: XXH_PROCESS1; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 2: XXH_PROCESS1; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 1: XXH_PROCESS1; - XXH_FALLTHROUGH; - case 0: return XXH32_avalanche(h32); + XXH_FALLTHROUGH; /* fallthrough */ + case 0: return XXH32_avalanche(hash); } XXH_ASSERT(0); - return h32; /* reaching this point is deemed impossible */ + return hash; /* reaching this point is deemed impossible */ } } @@ -2052,7 +2987,7 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align) * @param align Whether @p input is aligned. * @return The calculated hash. */ -XXH_FORCE_INLINE xxh_u32 +XXH_FORCE_INLINE XXH_PUREF xxh_u32 XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment align) { xxh_u32 h32; @@ -2085,10 +3020,10 @@ XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment return XXH32_finalize(h32, input, len&15, align); } -/*! @ingroup xxh32_family */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t seed) { -#if 0 +#if !defined(XXH_NO_STREAM) && XXH_SIZE_OPT >= 2 /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ XXH32_state_t state; XXH32_reset(&state, seed); @@ -2107,27 +3042,26 @@ XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t s /******* Hash streaming *******/ -/*! - * @ingroup xxh32_family - */ +#ifndef XXH_NO_STREAM +/*! @ingroup XXH32_family */ XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void) { return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); } -/*! @ingroup xxh32_family */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) { XXH_free(statePtr); return XXH_OK; } -/*! @ingroup xxh32_family */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState) { XXH_memcpy(dstState, srcState, sizeof(*dstState)); } -/*! @ingroup xxh32_family */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t seed) { XXH_ASSERT(statePtr != NULL); @@ -2140,7 +3074,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t s } -/*! @ingroup xxh32_family */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API XXH_errorcode XXH32_update(XXH32_state_t* state, const void* input, size_t len) { @@ -2195,7 +3129,7 @@ XXH32_update(XXH32_state_t* state, const void* input, size_t len) } -/*! @ingroup xxh32_family */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state) { xxh_u32 h32; @@ -2213,31 +3147,18 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state) return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned); } - +#endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ -/*! - * @ingroup xxh32_family - * The default return values from XXH functions are unsigned 32 and 64 bit - * integers. - * - * The canonical representation uses big endian convention, the same convention - * as human-readable numbers (large digits first). - * - * This way, hash values can be written into a file or buffer, remaining - * comparable across different systems. - * - * The following functions allow transformation of hash values to and from their - * canonical format. - */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) { - /* XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); */ + XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); XXH_memcpy(dst, &hash, sizeof(*dst)); } -/*! @ingroup xxh32_family */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src) { return XXH_readBE32(src); @@ -2278,18 +3199,19 @@ static xxh_u64 XXH_read64(const void* memPtr) #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) /* - * __pack instructions are safer, but compiler specific, hence potentially - * problematic for some compilers. - * - * Currently only defined for GCC and ICC. + * __attribute__((aligned(1))) is supported by gcc and clang. Originally the + * documentation claimed that it only increased the alignment, but actually it + * can decrease it on gcc, clang, and icc: + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69502, + * https://gcc.godbolt.org/z/xYez1j67Y. */ #ifdef XXH_OLD_NAMES typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64; #endif static xxh_u64 XXH_read64(const void* ptr) { - typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) xxh_unalign64; - return ((const xxh_unalign64*)ptr)->u64; + typedef __attribute__((aligned(1))) xxh_u64 xxh_unalign64; + return *((const xxh_unalign64*)ptr); } #else @@ -2380,8 +3302,10 @@ XXH_readLE64_align(const void* ptr, XXH_alignment align) /******* xxh64 *******/ /*! * @} - * @defgroup xxh64_impl XXH64 implementation + * @defgroup XXH64_impl XXH64 implementation * @ingroup impl + * + * Details on the XXH64 implementation. * @{ */ /* #define rather that static const, to be used as initializers */ @@ -2399,11 +3323,29 @@ XXH_readLE64_align(const void* ptr, XXH_alignment align) # define PRIME64_5 XXH_PRIME64_5 #endif +/*! @copydoc XXH32_round */ static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input) { acc += input * XXH_PRIME64_2; acc = XXH_rotl64(acc, 31); acc *= XXH_PRIME64_1; +#if (defined(__AVX512F__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) + /* + * DISABLE AUTOVECTORIZATION: + * A compiler fence is used to prevent GCC and Clang from + * autovectorizing the XXH64 loop (pragmas and attributes don't work for some + * reason) without globally disabling AVX512. + * + * Autovectorization of XXH64 tends to be detrimental, + * though the exact outcome may change depending on exact cpu and compiler version. + * For information, it has been reported as detrimental for Skylake-X, + * but possibly beneficial for Zen4. + * + * The default is to disable auto-vectorization, + * but you can select to enable it instead using `XXH_ENABLE_AUTOVECTORIZE` build variable. + */ + XXH_COMPILER_GUARD(acc); +#endif return acc; } @@ -2415,43 +3357,59 @@ static xxh_u64 XXH64_mergeRound(xxh_u64 acc, xxh_u64 val) return acc; } -static xxh_u64 XXH64_avalanche(xxh_u64 h64) +/*! @copydoc XXH32_avalanche */ +static xxh_u64 XXH64_avalanche(xxh_u64 hash) { - h64 ^= h64 >> 33; - h64 *= XXH_PRIME64_2; - h64 ^= h64 >> 29; - h64 *= XXH_PRIME64_3; - h64 ^= h64 >> 32; - return h64; + hash ^= hash >> 33; + hash *= XXH_PRIME64_2; + hash ^= hash >> 29; + hash *= XXH_PRIME64_3; + hash ^= hash >> 32; + return hash; } #define XXH_get64bits(p) XXH_readLE64_align(p, align) -static xxh_u64 -XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align) +/*! + * @internal + * @brief Processes the last 0-31 bytes of @p ptr. + * + * There may be up to 31 bytes remaining to consume from the input. + * This final stage will digest them to ensure that all input bytes are present + * in the final mix. + * + * @param hash The hash to finalize. + * @param ptr The pointer to the remaining input. + * @param len The remaining length, modulo 32. + * @param align Whether @p ptr is aligned. + * @return The finalized hash + * @see XXH32_finalize(). + */ +static XXH_PUREF xxh_u64 +XXH64_finalize(xxh_u64 hash, const xxh_u8* ptr, size_t len, XXH_alignment align) { if (ptr==NULL) XXH_ASSERT(len == 0); len &= 31; while (len >= 8) { xxh_u64 const k1 = XXH64_round(0, XXH_get64bits(ptr)); ptr += 8; - h64 ^= k1; - h64 = XXH_rotl64(h64,27) * XXH_PRIME64_1 + XXH_PRIME64_4; + hash ^= k1; + hash = XXH_rotl64(hash,27) * XXH_PRIME64_1 + XXH_PRIME64_4; len -= 8; } if (len >= 4) { - h64 ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1; + hash ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1; ptr += 4; - h64 = XXH_rotl64(h64, 23) * XXH_PRIME64_2 + XXH_PRIME64_3; + hash = XXH_rotl64(hash, 23) * XXH_PRIME64_2 + XXH_PRIME64_3; len -= 4; } while (len > 0) { - h64 ^= (*ptr++) * XXH_PRIME64_5; - h64 = XXH_rotl64(h64, 11) * XXH_PRIME64_1; + hash ^= (*ptr++) * XXH_PRIME64_5; + hash = XXH_rotl64(hash, 11) * XXH_PRIME64_1; --len; } - return XXH64_avalanche(h64); + return XXH64_avalanche(hash); } #ifdef XXH_OLD_NAMES @@ -2464,7 +3422,15 @@ XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align) # undef XXH_PROCESS8_64 #endif -XXH_FORCE_INLINE xxh_u64 +/*! + * @internal + * @brief The implementation for @ref XXH64(). + * + * @param input , len , seed Directly passed from @ref XXH64(). + * @param align Whether @p input is aligned. + * @return The calculated hash. + */ +XXH_FORCE_INLINE XXH_PUREF xxh_u64 XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment align) { xxh_u64 h64; @@ -2501,10 +3467,10 @@ XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment } -/*! @ingroup xxh64_family */ -XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t len, XXH64_hash_t seed) +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API XXH64_hash_t XXH64 (XXH_NOESCAPE const void* input, size_t len, XXH64_hash_t seed) { -#if 0 +#if !defined(XXH_NO_STREAM) && XXH_SIZE_OPT >= 2 /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ XXH64_state_t state; XXH64_reset(&state, seed); @@ -2522,27 +3488,27 @@ XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t len, XXH64_hash_t s } /******* Hash Streaming *******/ - -/*! @ingroup xxh64_family*/ +#ifndef XXH_NO_STREAM +/*! @ingroup XXH64_family*/ XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void) { return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); } -/*! @ingroup xxh64_family */ +/*! @ingroup XXH64_family */ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) { XXH_free(statePtr); return XXH_OK; } -/*! @ingroup xxh64_family */ -XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState) +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API void XXH64_copyState(XXH_NOESCAPE XXH64_state_t* dstState, const XXH64_state_t* srcState) { XXH_memcpy(dstState, srcState, sizeof(*dstState)); } -/*! @ingroup xxh64_family */ -XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, XXH64_hash_t seed) +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH_NOESCAPE XXH64_state_t* statePtr, XXH64_hash_t seed) { XXH_ASSERT(statePtr != NULL); memset(statePtr, 0, sizeof(*statePtr)); @@ -2553,9 +3519,9 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, XXH64_hash_t s return XXH_OK; } -/*! @ingroup xxh64_family */ +/*! @ingroup XXH64_family */ XXH_PUBLIC_API XXH_errorcode -XXH64_update (XXH64_state_t* state, const void* input, size_t len) +XXH64_update (XXH_NOESCAPE XXH64_state_t* state, XXH_NOESCAPE const void* input, size_t len) { if (input==NULL) { XXH_ASSERT(len == 0); @@ -2605,8 +3571,8 @@ XXH64_update (XXH64_state_t* state, const void* input, size_t len) } -/*! @ingroup xxh64_family */ -XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t* state) +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API XXH64_hash_t XXH64_digest(XXH_NOESCAPE const XXH64_state_t* state) { xxh_u64 h64; @@ -2624,20 +3590,20 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t* state) return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned); } - +#endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ -/*! @ingroup xxh64_family */ -XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash) +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, XXH64_hash_t hash) { - /* XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); */ + XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); XXH_memcpy(dst, &hash, sizeof(*dst)); } -/*! @ingroup xxh64_family */ -XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src) +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_canonical_t* src) { return XXH_readBE64(src); } @@ -2650,7 +3616,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src ************************************************************************ */ /*! * @} - * @defgroup xxh3_impl XXH3 implementation + * @defgroup XXH3_impl XXH3 implementation * @ingroup impl * @{ */ @@ -2658,11 +3624,19 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src /* === Compiler specifics === */ #if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */ -# define XXH_RESTRICT /* disable */ +# define XXH_RESTRICT /* disable */ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ # define XXH_RESTRICT restrict +#elif (defined (__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \ + || (defined (__clang__)) \ + || (defined (_MSC_VER) && (_MSC_VER >= 1400)) \ + || (defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300)) +/* + * There are a LOT more compilers that recognize __restrict but this + * covers the major ones. + */ +# define XXH_RESTRICT __restrict #else -/* Note: it might be useful to define __restrict or __restrict__ for some C++ compilers */ # define XXH_RESTRICT /* disable */ #endif @@ -2676,10 +3650,26 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src # define XXH_unlikely(x) (x) #endif +#ifndef XXH_HAS_INCLUDE +# ifdef __has_include +/* + * Not defined as XXH_HAS_INCLUDE(x) (function-like) because + * this causes segfaults in Apple Clang 4.2 (on Mac OS X 10.7 Lion) + */ +# define XXH_HAS_INCLUDE __has_include +# else +# define XXH_HAS_INCLUDE(x) 0 +# endif +#endif + #if defined(__GNUC__) || defined(__clang__) +# if defined(__ARM_FEATURE_SVE) +# include +# endif # if defined(__ARM_NEON__) || defined(__ARM_NEON) \ - || defined(__aarch64__) || defined(_M_ARM) \ - || defined(_M_ARM64) || defined(_M_ARM64EC) + || (defined(_M_ARM) && _M_ARM >= 7) \ + || defined(_M_ARM64) || defined(_M_ARM64EC) \ + || (defined(__wasm_simd128__) && XXH_HAS_INCLUDE()) /* WASM SIMD128 via SIMDe */ # define inline __inline__ /* circumvent a clang bug */ # include # undef inline @@ -2790,7 +3780,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src * Note that these are actually implemented as macros. * * If this is not defined, it is detected automatically. - * @ref XXH_X86DISPATCH overrides this. + * internal macro XXH_X86DISPATCH overrides this. */ enum XXH_VECTOR_TYPE /* fake enum */ { XXH_SCALAR = 0, /*!< Portable scalar version */ @@ -2802,8 +3792,13 @@ enum XXH_VECTOR_TYPE /* fake enum */ { */ XXH_AVX2 = 2, /*!< AVX2 for Haswell and Bulldozer */ XXH_AVX512 = 3, /*!< AVX512 for Skylake and Icelake */ - XXH_NEON = 4, /*!< NEON for most ARMv7-A and all AArch64 */ + XXH_NEON = 4, /*!< + * NEON for most ARMv7-A, all AArch64, and WASM SIMD128 + * via the SIMDeverywhere polyfill provided with the + * Emscripten SDK. + */ XXH_VSX = 5, /*!< VSX and ZVector for POWER8/z13 (64-bit) */ + XXH_SVE = 6, /*!< SVE for some ARMv8-A and ARMv9-A */ }; /*! * @ingroup tuning @@ -2825,12 +3820,16 @@ enum XXH_VECTOR_TYPE /* fake enum */ { # define XXH_AVX512 3 # define XXH_NEON 4 # define XXH_VSX 5 +# define XXH_SVE 6 #endif #ifndef XXH_VECTOR /* can be defined on command line */ -# if ( \ +# if defined(__ARM_FEATURE_SVE) +# define XXH_VECTOR XXH_SVE +# elif ( \ defined(__ARM_NEON__) || defined(__ARM_NEON) /* gcc */ \ || defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC) /* msvc */ \ + || (defined(__wasm_simd128__) && XXH_HAS_INCLUDE()) /* wasm simd128 via SIMDe */ \ ) && ( \ defined(_WIN32) || defined(__LITTLE_ENDIAN__) /* little endian only */ \ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \ @@ -2851,6 +3850,17 @@ enum XXH_VECTOR_TYPE /* fake enum */ { # endif #endif +/* __ARM_FEATURE_SVE is only supported by GCC & Clang. */ +#if (XXH_VECTOR == XXH_SVE) && !defined(__ARM_FEATURE_SVE) +# ifdef _MSC_VER +# pragma warning(once : 4606) +# else +# warning "__ARM_FEATURE_SVE isn't supported. Use SCALAR instead." +# endif +# undef XXH_VECTOR +# define XXH_VECTOR XXH_SCALAR +#endif + /* * Controls the alignment of the accumulator, * for compatibility with aligned vector loads, which are usually faster. @@ -2870,16 +3880,26 @@ enum XXH_VECTOR_TYPE /* fake enum */ { # define XXH_ACC_ALIGN 16 # elif XXH_VECTOR == XXH_AVX512 /* avx512 */ # define XXH_ACC_ALIGN 64 +# elif XXH_VECTOR == XXH_SVE /* sve */ +# define XXH_ACC_ALIGN 64 # endif #endif #if defined(XXH_X86DISPATCH) || XXH_VECTOR == XXH_SSE2 \ || XXH_VECTOR == XXH_AVX2 || XXH_VECTOR == XXH_AVX512 # define XXH_SEC_ALIGN XXH_ACC_ALIGN +#elif XXH_VECTOR == XXH_SVE +# define XXH_SEC_ALIGN XXH_ACC_ALIGN #else # define XXH_SEC_ALIGN 8 #endif +#if defined(__GNUC__) || defined(__clang__) +# define XXH_ALIASING __attribute__((may_alias)) +#else +# define XXH_ALIASING /* nothing */ +#endif + /* * UGLY HACK: * GCC usually generates the best code with -O3 for xxHash. @@ -2903,153 +3923,126 @@ enum XXH_VECTOR_TYPE /* fake enum */ { */ #if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \ && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ - && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */ + && defined(__OPTIMIZE__) && XXH_SIZE_OPT <= 0 /* respect -O0 and -Os */ # pragma GCC push_options # pragma GCC optimize("-O2") #endif - #if XXH_VECTOR == XXH_NEON + /* - * NEON's setup for vmlal_u32 is a little more complicated than it is on - * SSE2, AVX2, and VSX. + * UGLY HACK: While AArch64 GCC on Linux does not seem to care, on macOS, GCC -O3 + * optimizes out the entire hashLong loop because of the aliasing violation. * - * While PMULUDQ and VMULEUW both perform a mask, VMLAL.U32 performs an upcast. - * - * To do the same operation, the 128-bit 'Q' register needs to be split into - * two 64-bit 'D' registers, performing this operation:: - * - * [ a | b ] - * | '---------. .--------' | - * | x | - * | .---------' '--------. | - * [ a & 0xFFFFFFFF | b & 0xFFFFFFFF ],[ a >> 32 | b >> 32 ] - * - * Due to significant changes in aarch64, the fastest method for aarch64 is - * completely different than the fastest method for ARMv7-A. - * - * ARMv7-A treats D registers as unions overlaying Q registers, so modifying - * D11 will modify the high half of Q5. This is similar to how modifying AH - * will only affect bits 8-15 of AX on x86. - * - * VZIP takes two registers, and puts even lanes in one register and odd lanes - * in the other. - * - * On ARMv7-A, this strangely modifies both parameters in place instead of - * taking the usual 3-operand form. - * - * Therefore, if we want to do this, we can simply use a D-form VZIP.32 on the - * lower and upper halves of the Q register to end up with the high and low - * halves where we want - all in one instruction. - * - * vzip.32 d10, d11 @ d10 = { d10[0], d11[0] }; d11 = { d10[1], d11[1] } - * - * Unfortunately we need inline assembly for this: Instructions modifying two - * registers at once is not possible in GCC or Clang's IR, and they have to - * create a copy. - * - * aarch64 requires a different approach. - * - * In order to make it easier to write a decent compiler for aarch64, many - * quirks were removed, such as conditional execution. - * - * NEON was also affected by this. - * - * aarch64 cannot access the high bits of a Q-form register, and writes to a - * D-form register zero the high bits, similar to how writes to W-form scalar - * registers (or DWORD registers on x86_64) work. - * - * The formerly free vget_high intrinsics now require a vext (with a few - * exceptions) - * - * Additionally, VZIP was replaced by ZIP1 and ZIP2, which are the equivalent - * of PUNPCKL* and PUNPCKH* in SSE, respectively, in order to only modify one - * operand. - * - * The equivalent of the VZIP.32 on the lower and upper halves would be this - * mess: - * - * ext v2.4s, v0.4s, v0.4s, #2 // v2 = { v0[2], v0[3], v0[0], v0[1] } - * zip1 v1.2s, v0.2s, v2.2s // v1 = { v0[0], v2[0] } - * zip2 v0.2s, v0.2s, v1.2s // v0 = { v0[1], v2[1] } - * - * Instead, we use a literal downcast, vmovn_u64 (XTN), and vshrn_n_u64 (SHRN): - * - * shrn v1.2s, v0.2d, #32 // v1 = (uint32x2_t)(v0 >> 32); - * xtn v0.2s, v0.2d // v0 = (uint32x2_t)(v0 & 0xFFFFFFFF); - * - * This is available on ARMv7-A, but is less efficient than a single VZIP.32. + * However, GCC is also inefficient at load-store optimization with vld1q/vst1q, + * so the only option is to mark it as aliasing. */ +typedef uint64x2_t xxh_aliasing_uint64x2_t XXH_ALIASING; /*! - * Function-like macro: - * void XXH_SPLIT_IN_PLACE(uint64x2_t &in, uint32x2_t &outLo, uint32x2_t &outHi) - * { - * outLo = (uint32x2_t)(in & 0xFFFFFFFF); - * outHi = (uint32x2_t)(in >> 32); - * in = UNDEFINED; - * } + * @internal + * @brief `vld1q_u64` but faster and alignment-safe. + * + * On AArch64, unaligned access is always safe, but on ARMv7-a, it is only + * *conditionally* safe (`vld1` has an alignment bit like `movdq[ua]` in x86). + * + * GCC for AArch64 sees `vld1q_u8` as an intrinsic instead of a load, so it + * prohibits load-store optimizations. Therefore, a direct dereference is used. + * + * Otherwise, `vld1q_u8` is used with `vreinterpretq_u8_u64` to do a safe + * unaligned load. */ -# if !defined(XXH_NO_VZIP_HACK) /* define to disable */ \ - && (defined(__GNUC__) || defined(__clang__)) \ - && (defined(__arm__) || defined(__thumb__) || defined(_M_ARM)) -# define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \ - do { \ - /* Undocumented GCC/Clang operand modifier: %e0 = lower D half, %f0 = upper D half */ \ - /* https://github.com/gcc-mirror/gcc/blob/38cf91e5/gcc/config/arm/arm.c#L22486 */ \ - /* https://github.com/llvm-mirror/llvm/blob/2c4ca683/lib/Target/ARM/ARMAsmPrinter.cpp#L399 */ \ - __asm__("vzip.32 %e0, %f0" : "+w" (in)); \ - (outLo) = vget_low_u32 (vreinterpretq_u32_u64(in)); \ - (outHi) = vget_high_u32(vreinterpretq_u32_u64(in)); \ - } while (0) -# else -# define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \ - do { \ - (outLo) = vmovn_u64 (in); \ - (outHi) = vshrn_n_u64 ((in), 32); \ - } while (0) -# endif +#if defined(__aarch64__) && defined(__GNUC__) && !defined(__clang__) +XXH_FORCE_INLINE uint64x2_t XXH_vld1q_u64(void const* ptr) /* silence -Wcast-align */ +{ + return *(xxh_aliasing_uint64x2_t const *)ptr; +} +#else +XXH_FORCE_INLINE uint64x2_t XXH_vld1q_u64(void const* ptr) +{ + return vreinterpretq_u64_u8(vld1q_u8((uint8_t const*)ptr)); +} +#endif + +/*! + * @internal + * @brief `vmlal_u32` on low and high halves of a vector. + * + * This is a workaround for AArch64 GCC < 11 which implemented arm_neon.h with + * inline assembly and were therefore incapable of merging the `vget_{low, high}_u32` + * with `vmlal_u32`. + */ +#if defined(__aarch64__) && defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 11 +XXH_FORCE_INLINE uint64x2_t +XXH_vmlal_low_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs) +{ + /* Inline assembly is the only way */ + __asm__("umlal %0.2d, %1.2s, %2.2s" : "+w" (acc) : "w" (lhs), "w" (rhs)); + return acc; +} +XXH_FORCE_INLINE uint64x2_t +XXH_vmlal_high_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs) +{ + /* This intrinsic works as expected */ + return vmlal_high_u32(acc, lhs, rhs); +} +#else +/* Portable intrinsic versions */ +XXH_FORCE_INLINE uint64x2_t +XXH_vmlal_low_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs) +{ + return vmlal_u32(acc, vget_low_u32(lhs), vget_low_u32(rhs)); +} +/*! @copydoc XXH_vmlal_low_u32 + * Assume the compiler converts this to vmlal_high_u32 on aarch64 */ +XXH_FORCE_INLINE uint64x2_t +XXH_vmlal_high_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs) +{ + return vmlal_u32(acc, vget_high_u32(lhs), vget_high_u32(rhs)); +} +#endif /*! * @ingroup tuning * @brief Controls the NEON to scalar ratio for XXH3 * - * On AArch64 when not optimizing for size, XXH3 will run 6 lanes using NEON and - * 2 lanes on scalar by default. + * This can be set to 2, 4, 6, or 8. * - * This can be set to 2, 4, 6, or 8. ARMv7 will default to all 8 NEON lanes, as the - * emulated 64-bit arithmetic is too slow. + * ARM Cortex CPUs are _very_ sensitive to how their pipelines are used. * - * Modern ARM CPUs are _very_ sensitive to how their pipelines are used. + * For example, the Cortex-A73 can dispatch 3 micro-ops per cycle, but only 2 of those + * can be NEON. If you are only using NEON instructions, you are only using 2/3 of the CPU + * bandwidth. * - * For example, the Cortex-A73 can dispatch 3 micro-ops per cycle, but it can't - * have more than 2 NEON (F0/F1) micro-ops. If you are only using NEON instructions, - * you are only using 2/3 of the CPU bandwidth. - * - * This is even more noticeable on the more advanced cores like the A76 which + * This is even more noticeable on the more advanced cores like the Cortex-A76 which * can dispatch 8 micro-ops per cycle, but still only 2 NEON micro-ops at once. * - * Therefore, @ref XXH3_NEON_LANES lanes will be processed using NEON, and the - * remaining lanes will use scalar instructions. This improves the bandwidth - * and also gives the integer pipelines something to do besides twiddling loop - * counters and pointers. + * Therefore, to make the most out of the pipeline, it is beneficial to run 6 NEON lanes + * and 2 scalar lanes, which is chosen by default. + * + * This does not apply to Apple processors or 32-bit processors, which run better with + * full NEON. These will default to 8. Additionally, size-optimized builds run 8 lanes. * * This change benefits CPUs with large micro-op buffers without negatively affecting - * other CPUs: + * most other CPUs: * * | Chipset | Dispatch type | NEON only | 6:2 hybrid | Diff. | * |:----------------------|:--------------------|----------:|-----------:|------:| * | Snapdragon 730 (A76) | 2 NEON/8 micro-ops | 8.8 GB/s | 10.1 GB/s | ~16% | * | Snapdragon 835 (A73) | 2 NEON/3 micro-ops | 5.1 GB/s | 5.3 GB/s | ~5% | * | Marvell PXA1928 (A53) | In-order dual-issue | 1.9 GB/s | 1.9 GB/s | 0% | + * | Apple M1 | 4 NEON/8 micro-ops | 37.3 GB/s | 36.1 GB/s | ~-3% | * * It also seems to fix some bad codegen on GCC, making it almost as fast as clang. * + * When using WASM SIMD128, if this is 2 or 6, SIMDe will scalarize 2 of the lanes meaning + * it effectively becomes worse 4. + * * @see XXH3_accumulate_512_neon() */ # ifndef XXH3_NEON_LANES # if (defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) || defined(_M_ARM64EC)) \ - && !defined(__OPTIMIZE_SIZE__) + && !defined(__APPLE__) && XXH_SIZE_OPT <= 0 # define XXH3_NEON_LANES 6 # else # define XXH3_NEON_LANES XXH_ACC_NB @@ -3066,27 +4059,42 @@ enum XXH_VECTOR_TYPE /* fake enum */ { * inconsistent intrinsics, spotty coverage, and multiple endiannesses. */ #if XXH_VECTOR == XXH_VSX +/* Annoyingly, these headers _may_ define three macros: `bool`, `vector`, + * and `pixel`. This is a problem for obvious reasons. + * + * These keywords are unnecessary; the spec literally says they are + * equivalent to `__bool`, `__vector`, and `__pixel` and may be undef'd + * after including the header. + * + * We use pragma push_macro/pop_macro to keep the namespace clean. */ +# pragma push_macro("bool") +# pragma push_macro("vector") +# pragma push_macro("pixel") +/* silence potential macro redefined warnings */ +# undef bool +# undef vector +# undef pixel + # if defined(__s390x__) # include # else -/* gcc's altivec.h can have the unwanted consequence to unconditionally - * #define bool, vector, and pixel keywords, - * with bad consequences for programs already using these keywords for other purposes. - * The paragraph defining these macros is skipped when __APPLE_ALTIVEC__ is defined. - * __APPLE_ALTIVEC__ is _generally_ defined automatically by the compiler, - * but it seems that, in some cases, it isn't. - * Force the build macro to be defined, so that keywords are not altered. - */ -# if defined(__GNUC__) && !defined(__APPLE_ALTIVEC__) -# define __APPLE_ALTIVEC__ -# endif # include # endif +/* Restore the original macro values, if applicable. */ +# pragma pop_macro("pixel") +# pragma pop_macro("vector") +# pragma pop_macro("bool") + typedef __vector unsigned long long xxh_u64x2; typedef __vector unsigned char xxh_u8x16; typedef __vector unsigned xxh_u32x4; +/* + * UGLY HACK: Similar to aarch64 macOS GCC, s390x GCC has the same aliasing issue. + */ +typedef xxh_u64x2 xxh_aliasing_u64x2 XXH_ALIASING; + # ifndef XXH_VSX_BE # if defined(__BIG_ENDIAN__) \ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) @@ -3138,8 +4146,9 @@ XXH_FORCE_INLINE xxh_u64x2 XXH_vec_loadu(const void *ptr) /* s390x is always big endian, no issue on this platform */ # define XXH_vec_mulo vec_mulo # define XXH_vec_mule vec_mule -# elif defined(__clang__) && XXH_HAS_BUILTIN(__builtin_altivec_vmuleuw) +# elif defined(__clang__) && XXH_HAS_BUILTIN(__builtin_altivec_vmuleuw) && !defined(__ibmxl__) /* Clang has a better way to control this, we can just use the builtin which doesn't swap. */ + /* The IBM XL Compiler (which defined __clang__) only implements the vec_* operations */ # define XXH_vec_mulo __builtin_altivec_vmulouw # define XXH_vec_mule __builtin_altivec_vmuleuw # else @@ -3160,13 +4169,28 @@ XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mule(xxh_u32x4 a, xxh_u32x4 b) # endif /* XXH_vec_mulo, XXH_vec_mule */ #endif /* XXH_VECTOR == XXH_VSX */ +#if XXH_VECTOR == XXH_SVE +#define ACCRND(acc, offset) \ +do { \ + svuint64_t input_vec = svld1_u64(mask, xinput + offset); \ + svuint64_t secret_vec = svld1_u64(mask, xsecret + offset); \ + svuint64_t mixed = sveor_u64_x(mask, secret_vec, input_vec); \ + svuint64_t swapped = svtbl_u64(input_vec, kSwap); \ + svuint64_t mixed_lo = svextw_u64_x(mask, mixed); \ + svuint64_t mixed_hi = svlsr_n_u64_x(mask, mixed, 32); \ + svuint64_t mul = svmad_u64_x(mask, mixed_lo, mixed_hi, swapped); \ + acc = svadd_u64_x(mask, acc, mul); \ +} while (0) +#endif /* XXH_VECTOR == XXH_SVE */ /* prefetch * can be disabled, by declaring XXH_NO_PREFETCH build macro */ #if defined(XXH_NO_PREFETCH) # define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */ #else -# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) /* _mm_prefetch() not defined outside of x86/x64 */ +# if XXH_SIZE_OPT >= 1 +# define XXH_PREFETCH(ptr) (void)(ptr) +# elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) /* _mm_prefetch() not defined outside of x86/x64 */ # include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ # define XXH_PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0) # elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) @@ -3203,6 +4227,8 @@ XXH_ALIGN(64) static const xxh_u8 XXH3_kSecret[XXH_SECRET_DEFAULT_SIZE] = { 0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e, }; +static const xxh_u64 PRIME_MX1 = 0x165667919E3779F9ULL; /*!< 0b0001011001010110011001111001000110011110001101110111100111111001 */ +static const xxh_u64 PRIME_MX2 = 0x9FB21C651E98DF25ULL; /*!< 0b1001111110110010000111000110010100011110100110001101111100100101 */ #ifdef XXH_OLD_NAMES # define kSecret XXH3_kSecret @@ -3394,7 +4420,7 @@ XXH3_mul128_fold64(xxh_u64 lhs, xxh_u64 rhs) } /*! Seems to produce slightly better code on GCC for some reason. */ -XXH_FORCE_INLINE xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift) +XXH_FORCE_INLINE XXH_CONSTF xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift) { XXH_ASSERT(0 <= shift && shift < 64); return v64 ^ (v64 >> shift); @@ -3407,7 +4433,7 @@ XXH_FORCE_INLINE xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift) static XXH64_hash_t XXH3_avalanche(xxh_u64 h64) { h64 = XXH_xorshift64(h64, 37); - h64 *= 0x165667919E3779F9ULL; + h64 *= PRIME_MX1; h64 = XXH_xorshift64(h64, 32); return h64; } @@ -3421,9 +4447,9 @@ static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len) { /* this mix is inspired by Pelle Evensen's rrmxmx */ h64 ^= XXH_rotl64(h64, 49) ^ XXH_rotl64(h64, 24); - h64 *= 0x9FB21C651E98DF25ULL; + h64 *= PRIME_MX2; h64 ^= (h64 >> 35) + len ; - h64 *= 0x9FB21C651E98DF25ULL; + h64 *= PRIME_MX2; return XXH_xorshift64(h64, 28); } @@ -3461,7 +4487,7 @@ static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len) * * This adds an extra layer of strength for custom secrets. */ -XXH_FORCE_INLINE XXH64_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) { XXH_ASSERT(input != NULL); @@ -3483,7 +4509,7 @@ XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_h } } -XXH_FORCE_INLINE XXH64_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) { XXH_ASSERT(input != NULL); @@ -3499,7 +4525,7 @@ XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_h } } -XXH_FORCE_INLINE XXH64_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) { XXH_ASSERT(input != NULL); @@ -3516,7 +4542,7 @@ XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_ } } -XXH_FORCE_INLINE XXH64_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t XXH3_len_0to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) { XXH_ASSERT(len <= 16); @@ -3586,7 +4612,7 @@ XXH_FORCE_INLINE xxh_u64 XXH3_mix16B(const xxh_u8* XXH_RESTRICT input, } /* For mid range keys, XXH3 uses a Mum-hash variant. */ -XXH_FORCE_INLINE XXH64_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, XXH64_hash_t seed) @@ -3595,6 +4621,14 @@ XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len, XXH_ASSERT(16 < len && len <= 128); { xxh_u64 acc = len * XXH_PRIME64_1; +#if XXH_SIZE_OPT >= 1 + /* Smaller and cleaner, but slightly slower. */ + unsigned int i = (unsigned int)(len - 1) / 32; + do { + acc += XXH3_mix16B(input+16 * i, secret+32*i, seed); + acc += XXH3_mix16B(input+len-16*(i+1), secret+32*i+16, seed); + } while (i-- != 0); +#else if (len > 32) { if (len > 64) { if (len > 96) { @@ -3609,14 +4643,17 @@ XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len, } acc += XXH3_mix16B(input+0, secret+0, seed); acc += XXH3_mix16B(input+len-16, secret+16, seed); - +#endif return XXH3_avalanche(acc); } } +/*! + * @brief Maximum size of "short" key in bytes. + */ #define XXH3_MIDSIZE_MAX 240 -XXH_NO_INLINE XXH64_hash_t +XXH_NO_INLINE XXH_PUREF XXH64_hash_t XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, XXH64_hash_t seed) @@ -3628,13 +4665,17 @@ XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, #define XXH3_MIDSIZE_LASTOFFSET 17 { xxh_u64 acc = len * XXH_PRIME64_1; - int const nbRounds = (int)len / 16; - int i; + xxh_u64 acc_end; + unsigned int const nbRounds = (unsigned int)len / 16; + unsigned int i; + XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX); for (i=0; i<8; i++) { acc += XXH3_mix16B(input+(16*i), secret+(16*i), seed); } - acc = XXH3_avalanche(acc); + /* last bytes */ + acc_end = XXH3_mix16B(input + len - 16, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET, seed); XXH_ASSERT(nbRounds >= 8); + acc = XXH3_avalanche(acc); #if defined(__clang__) /* Clang */ \ && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \ && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */ @@ -3661,11 +4702,13 @@ XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, #pragma clang loop vectorize(disable) #endif for (i=8 ; i < nbRounds; i++) { - acc += XXH3_mix16B(input+(16*i), secret+(16*(i-8)) + XXH3_MIDSIZE_STARTOFFSET, seed); + /* + * Prevents clang for unrolling the acc loop and interleaving with this one. + */ + XXH_COMPILER_GUARD(acc); + acc_end += XXH3_mix16B(input+(16*i), secret+(16*(i-8)) + XXH3_MIDSIZE_STARTOFFSET, seed); } - /* last bytes */ - acc += XXH3_mix16B(input + len - 16, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET, seed); - return XXH3_avalanche(acc); + return XXH3_avalanche(acc + acc_end); } } @@ -3681,6 +4724,47 @@ XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, # define ACC_NB XXH_ACC_NB #endif +#ifndef XXH_PREFETCH_DIST +# ifdef __clang__ +# define XXH_PREFETCH_DIST 320 +# else +# if (XXH_VECTOR == XXH_AVX512) +# define XXH_PREFETCH_DIST 512 +# else +# define XXH_PREFETCH_DIST 384 +# endif +# endif /* __clang__ */ +#endif /* XXH_PREFETCH_DIST */ + +/* + * These macros are to generate an XXH3_accumulate() function. + * The two arguments select the name suffix and target attribute. + * + * The name of this symbol is XXH3_accumulate_() and it calls + * XXH3_accumulate_512_(). + * + * It may be useful to hand implement this function if the compiler fails to + * optimize the inline function. + */ +#define XXH3_ACCUMULATE_TEMPLATE(name) \ +void \ +XXH3_accumulate_##name(xxh_u64* XXH_RESTRICT acc, \ + const xxh_u8* XXH_RESTRICT input, \ + const xxh_u8* XXH_RESTRICT secret, \ + size_t nbStripes) \ +{ \ + size_t n; \ + for (n = 0; n < nbStripes; n++ ) { \ + const xxh_u8* const in = input + n*XXH_STRIPE_LEN; \ + XXH_PREFETCH(in + XXH_PREFETCH_DIST); \ + XXH3_accumulate_512_##name( \ + acc, \ + in, \ + secret + n*XXH_SECRET_CONSUME_RATE); \ + } \ +} + + XXH_FORCE_INLINE void XXH_writeLE64(void* dst, xxh_u64 v64) { if (!XXH_CPU_LITTLE_ENDIAN) v64 = XXH_swap64(v64); @@ -3749,7 +4833,7 @@ XXH3_accumulate_512_avx512(void* XXH_RESTRICT acc, /* data_key = data_vec ^ key_vec; */ __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec); /* data_key_lo = data_key >> 32; */ - __m512i const data_key_lo = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1)); + __m512i const data_key_lo = _mm512_srli_epi64 (data_key, 32); /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ __m512i const product = _mm512_mul_epu32 (data_key, data_key_lo); /* xacc[0] += swap(data_vec); */ @@ -3759,6 +4843,7 @@ XXH3_accumulate_512_avx512(void* XXH_RESTRICT acc, *xacc = _mm512_add_epi64(product, sum); } } +XXH_FORCE_INLINE XXH_TARGET_AVX512 XXH3_ACCUMULATE_TEMPLATE(avx512) /* * XXH3_scrambleAcc: Scrambles the accumulators to improve mixing. @@ -3792,13 +4877,12 @@ XXH3_scrambleAcc_avx512(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) /* xacc[0] ^= (xacc[0] >> 47) */ __m512i const acc_vec = *xacc; __m512i const shifted = _mm512_srli_epi64 (acc_vec, 47); - __m512i const data_vec = _mm512_xor_si512 (acc_vec, shifted); /* xacc[0] ^= secret; */ __m512i const key_vec = _mm512_loadu_si512 (secret); - __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec); + __m512i const data_key = _mm512_ternarylogic_epi32(key_vec, acc_vec, shifted, 0x96 /* key_vec ^ acc_vec ^ shifted */); /* xacc[0] *= XXH_PRIME32_1; */ - __m512i const data_key_hi = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1)); + __m512i const data_key_hi = _mm512_srli_epi64 (data_key, 32); __m512i const prod_lo = _mm512_mul_epu32 (data_key, prime32); __m512i const prod_hi = _mm512_mul_epu32 (data_key_hi, prime32); *xacc = _mm512_add_epi64(prod_lo, _mm512_slli_epi64(prod_hi, 32)); @@ -3813,7 +4897,8 @@ XXH3_initCustomSecret_avx512(void* XXH_RESTRICT customSecret, xxh_u64 seed64) XXH_ASSERT(((size_t)customSecret & 63) == 0); (void)(&XXH_writeLE64); { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m512i); - __m512i const seed = _mm512_mask_set1_epi64(_mm512_set1_epi64((xxh_i64)seed64), 0xAA, (xxh_i64)(0U - seed64)); + __m512i const seed_pos = _mm512_set1_epi64((xxh_i64)seed64); + __m512i const seed = _mm512_mask_sub_epi64(seed_pos, 0xAA, _mm512_set1_epi8(0), seed_pos); const __m512i* const src = (const __m512i*) ((const void*) XXH3_kSecret); __m512i* const dest = ( __m512i*) customSecret; @@ -3821,14 +4906,7 @@ XXH3_initCustomSecret_avx512(void* XXH_RESTRICT customSecret, xxh_u64 seed64) XXH_ASSERT(((size_t)src & 63) == 0); /* control alignment */ XXH_ASSERT(((size_t)dest & 63) == 0); for (i=0; i < nbRounds; ++i) { - /* GCC has a bug, _mm512_stream_load_si512 accepts 'void*', not 'void const*', - * this will warn "discards 'const' qualifier". */ - union { - const __m512i* cp; - void* p; - } remote_const_void; - remote_const_void.cp = src + i; - dest[i] = _mm512_add_epi64(_mm512_stream_load_si512(remote_const_void.p), seed); + dest[i] = _mm512_add_epi64(_mm512_load_si512(src + i), seed); } } } @@ -3864,7 +4942,7 @@ XXH3_accumulate_512_avx2( void* XXH_RESTRICT acc, /* data_key = data_vec ^ key_vec; */ __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec); /* data_key_lo = data_key >> 32; */ - __m256i const data_key_lo = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + __m256i const data_key_lo = _mm256_srli_epi64 (data_key, 32); /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ __m256i const product = _mm256_mul_epu32 (data_key, data_key_lo); /* xacc[i] += swap(data_vec); */ @@ -3874,6 +4952,7 @@ XXH3_accumulate_512_avx2( void* XXH_RESTRICT acc, xacc[i] = _mm256_add_epi64(product, sum); } } } +XXH_FORCE_INLINE XXH_TARGET_AVX2 XXH3_ACCUMULATE_TEMPLATE(avx2) XXH_FORCE_INLINE XXH_TARGET_AVX2 void XXH3_scrambleAcc_avx2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) @@ -3896,7 +4975,7 @@ XXH3_scrambleAcc_avx2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec); /* xacc[i] *= XXH_PRIME32_1; */ - __m256i const data_key_hi = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + __m256i const data_key_hi = _mm256_srli_epi64 (data_key, 32); __m256i const prod_lo = _mm256_mul_epu32 (data_key, prime32); __m256i const prod_hi = _mm256_mul_epu32 (data_key_hi, prime32); xacc[i] = _mm256_add_epi64(prod_lo, _mm256_slli_epi64(prod_hi, 32)); @@ -3928,12 +5007,12 @@ XXH_FORCE_INLINE XXH_TARGET_AVX2 void XXH3_initCustomSecret_avx2(void* XXH_RESTR XXH_ASSERT(((size_t)dest & 31) == 0); /* GCC -O2 need unroll loop manually */ - dest[0] = _mm256_add_epi64(_mm256_stream_load_si256(src+0), seed); - dest[1] = _mm256_add_epi64(_mm256_stream_load_si256(src+1), seed); - dest[2] = _mm256_add_epi64(_mm256_stream_load_si256(src+2), seed); - dest[3] = _mm256_add_epi64(_mm256_stream_load_si256(src+3), seed); - dest[4] = _mm256_add_epi64(_mm256_stream_load_si256(src+4), seed); - dest[5] = _mm256_add_epi64(_mm256_stream_load_si256(src+5), seed); + dest[0] = _mm256_add_epi64(_mm256_load_si256(src+0), seed); + dest[1] = _mm256_add_epi64(_mm256_load_si256(src+1), seed); + dest[2] = _mm256_add_epi64(_mm256_load_si256(src+2), seed); + dest[3] = _mm256_add_epi64(_mm256_load_si256(src+3), seed); + dest[4] = _mm256_add_epi64(_mm256_load_si256(src+4), seed); + dest[5] = _mm256_add_epi64(_mm256_load_si256(src+5), seed); } } @@ -3980,6 +5059,7 @@ XXH3_accumulate_512_sse2( void* XXH_RESTRICT acc, xacc[i] = _mm_add_epi64(product, sum); } } } +XXH_FORCE_INLINE XXH_TARGET_SSE2 XXH3_ACCUMULATE_TEMPLATE(sse2) XXH_FORCE_INLINE XXH_TARGET_SSE2 void XXH3_scrambleAcc_sse2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) @@ -4058,14 +5138,28 @@ XXH3_scalarScrambleRound(void* XXH_RESTRICT acc, /*! * @internal - * @brief The bulk processing loop for NEON. + * @brief The bulk processing loop for NEON and WASM SIMD128. * * The NEON code path is actually partially scalar when running on AArch64. This * is to optimize the pipelining and can have up to 15% speedup depending on the * CPU, and it also mitigates some GCC codegen issues. * * @see XXH3_NEON_LANES for configuring this and details about this optimization. + * + * NEON's 32-bit to 64-bit long multiply takes a half vector of 32-bit + * integers instead of the other platforms which mask full 64-bit vectors, + * so the setup is more complicated than just shifting right. + * + * Additionally, there is an optimization for 4 lanes at once noted below. + * + * Since, as stated, the most optimal amount of lanes for Cortexes is 6, + * there needs to be *three* versions of the accumulate operation used + * for the remaining 2 lanes. + * + * WASM's SIMD128 uses SIMDe's arm_neon.h polyfill because the intrinsics overlap + * nearly perfectly. */ + XXH_FORCE_INLINE void XXH3_accumulate_512_neon( void* XXH_RESTRICT acc, const void* XXH_RESTRICT input, @@ -4073,101 +5167,182 @@ XXH3_accumulate_512_neon( void* XXH_RESTRICT acc, { XXH_ASSERT((((size_t)acc) & 15) == 0); XXH_STATIC_ASSERT(XXH3_NEON_LANES > 0 && XXH3_NEON_LANES <= XXH_ACC_NB && XXH3_NEON_LANES % 2 == 0); - { - uint64x2_t* const xacc = (uint64x2_t *) acc; + { /* GCC for darwin arm64 does not like aliasing here */ + xxh_aliasing_uint64x2_t* const xacc = (xxh_aliasing_uint64x2_t*) acc; /* We don't use a uint32x4_t pointer because it causes bus errors on ARMv7. */ - uint8_t const* const xinput = (const uint8_t *) input; - uint8_t const* const xsecret = (const uint8_t *) secret; + uint8_t const* xinput = (const uint8_t *) input; + uint8_t const* xsecret = (const uint8_t *) secret; size_t i; - /* NEON for the first few lanes (these loops are normally interleaved) */ - for (i=0; i < XXH3_NEON_LANES / 2; i++) { - /* data_vec = xinput[i]; */ - uint8x16_t data_vec = vld1q_u8(xinput + (i * 16)); - /* key_vec = xsecret[i]; */ - uint8x16_t key_vec = vld1q_u8(xsecret + (i * 16)); - uint64x2_t data_key; - uint32x2_t data_key_lo, data_key_hi; - /* xacc[i] += swap(data_vec); */ - uint64x2_t const data64 = vreinterpretq_u64_u8(data_vec); - uint64x2_t const swapped = vextq_u64(data64, data64, 1); - xacc[i] = vaddq_u64 (xacc[i], swapped); - /* data_key = data_vec ^ key_vec; */ - data_key = vreinterpretq_u64_u8(veorq_u8(data_vec, key_vec)); - /* data_key_lo = (uint32x2_t) (data_key & 0xFFFFFFFF); - * data_key_hi = (uint32x2_t) (data_key >> 32); - * data_key = UNDEFINED; */ - XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi); - /* xacc[i] += (uint64x2_t) data_key_lo * (uint64x2_t) data_key_hi; */ - xacc[i] = vmlal_u32 (xacc[i], data_key_lo, data_key_hi); - - } - /* Scalar for the remainder. This may be a zero iteration loop. */ +#ifdef __wasm_simd128__ + /* + * On WASM SIMD128, Clang emits direct address loads when XXH3_kSecret + * is constant propagated, which results in it converting it to this + * inside the loop: + * + * a = v128.load(XXH3_kSecret + 0 + $secret_offset, offset = 0) + * b = v128.load(XXH3_kSecret + 16 + $secret_offset, offset = 0) + * ... + * + * This requires a full 32-bit address immediate (and therefore a 6 byte + * instruction) as well as an add for each offset. + * + * Putting an asm guard prevents it from folding (at the cost of losing + * the alignment hint), and uses the free offset in `v128.load` instead + * of adding secret_offset each time which overall reduces code size by + * about a kilobyte and improves performance. + */ + XXH_COMPILER_GUARD(xsecret); +#endif + /* Scalar lanes use the normal scalarRound routine */ for (i = XXH3_NEON_LANES; i < XXH_ACC_NB; i++) { XXH3_scalarRound(acc, input, secret, i); } + i = 0; + /* 4 NEON lanes at a time. */ + for (; i+1 < XXH3_NEON_LANES / 2; i+=2) { + /* data_vec = xinput[i]; */ + uint64x2_t data_vec_1 = XXH_vld1q_u64(xinput + (i * 16)); + uint64x2_t data_vec_2 = XXH_vld1q_u64(xinput + ((i+1) * 16)); + /* key_vec = xsecret[i]; */ + uint64x2_t key_vec_1 = XXH_vld1q_u64(xsecret + (i * 16)); + uint64x2_t key_vec_2 = XXH_vld1q_u64(xsecret + ((i+1) * 16)); + /* data_swap = swap(data_vec) */ + uint64x2_t data_swap_1 = vextq_u64(data_vec_1, data_vec_1, 1); + uint64x2_t data_swap_2 = vextq_u64(data_vec_2, data_vec_2, 1); + /* data_key = data_vec ^ key_vec; */ + uint64x2_t data_key_1 = veorq_u64(data_vec_1, key_vec_1); + uint64x2_t data_key_2 = veorq_u64(data_vec_2, key_vec_2); + + /* + * If we reinterpret the 64x2 vectors as 32x4 vectors, we can use a + * de-interleave operation for 4 lanes in 1 step with `vuzpq_u32` to + * get one vector with the low 32 bits of each lane, and one vector + * with the high 32 bits of each lane. + * + * The intrinsic returns a double vector because the original ARMv7-a + * instruction modified both arguments in place. AArch64 and SIMD128 emit + * two instructions from this intrinsic. + * + * [ dk11L | dk11H | dk12L | dk12H ] -> [ dk11L | dk12L | dk21L | dk22L ] + * [ dk21L | dk21H | dk22L | dk22H ] -> [ dk11H | dk12H | dk21H | dk22H ] + */ + uint32x4x2_t unzipped = vuzpq_u32( + vreinterpretq_u32_u64(data_key_1), + vreinterpretq_u32_u64(data_key_2) + ); + /* data_key_lo = data_key & 0xFFFFFFFF */ + uint32x4_t data_key_lo = unzipped.val[0]; + /* data_key_hi = data_key >> 32 */ + uint32x4_t data_key_hi = unzipped.val[1]; + /* + * Then, we can split the vectors horizontally and multiply which, as for most + * widening intrinsics, have a variant that works on both high half vectors + * for free on AArch64. A similar instruction is available on SIMD128. + * + * sum = data_swap + (u64x2) data_key_lo * (u64x2) data_key_hi + */ + uint64x2_t sum_1 = XXH_vmlal_low_u32(data_swap_1, data_key_lo, data_key_hi); + uint64x2_t sum_2 = XXH_vmlal_high_u32(data_swap_2, data_key_lo, data_key_hi); + /* + * Clang reorders + * a += b * c; // umlal swap.2d, dkl.2s, dkh.2s + * c += a; // add acc.2d, acc.2d, swap.2d + * to + * c += a; // add acc.2d, acc.2d, swap.2d + * c += b * c; // umlal acc.2d, dkl.2s, dkh.2s + * + * While it would make sense in theory since the addition is faster, + * for reasons likely related to umlal being limited to certain NEON + * pipelines, this is worse. A compiler guard fixes this. + */ + XXH_COMPILER_GUARD_CLANG_NEON(sum_1); + XXH_COMPILER_GUARD_CLANG_NEON(sum_2); + /* xacc[i] = acc_vec + sum; */ + xacc[i] = vaddq_u64(xacc[i], sum_1); + xacc[i+1] = vaddq_u64(xacc[i+1], sum_2); + } + /* Operate on the remaining NEON lanes 2 at a time. */ + for (; i < XXH3_NEON_LANES / 2; i++) { + /* data_vec = xinput[i]; */ + uint64x2_t data_vec = XXH_vld1q_u64(xinput + (i * 16)); + /* key_vec = xsecret[i]; */ + uint64x2_t key_vec = XXH_vld1q_u64(xsecret + (i * 16)); + /* acc_vec_2 = swap(data_vec) */ + uint64x2_t data_swap = vextq_u64(data_vec, data_vec, 1); + /* data_key = data_vec ^ key_vec; */ + uint64x2_t data_key = veorq_u64(data_vec, key_vec); + /* For two lanes, just use VMOVN and VSHRN. */ + /* data_key_lo = data_key & 0xFFFFFFFF; */ + uint32x2_t data_key_lo = vmovn_u64(data_key); + /* data_key_hi = data_key >> 32; */ + uint32x2_t data_key_hi = vshrn_n_u64(data_key, 32); + /* sum = data_swap + (u64x2) data_key_lo * (u64x2) data_key_hi; */ + uint64x2_t sum = vmlal_u32(data_swap, data_key_lo, data_key_hi); + /* Same Clang workaround as before */ + XXH_COMPILER_GUARD_CLANG_NEON(sum); + /* xacc[i] = acc_vec + sum; */ + xacc[i] = vaddq_u64 (xacc[i], sum); + } } } +XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(neon) XXH_FORCE_INLINE void XXH3_scrambleAcc_neon(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) { XXH_ASSERT((((size_t)acc) & 15) == 0); - { uint64x2_t* xacc = (uint64x2_t*) acc; + { xxh_aliasing_uint64x2_t* xacc = (xxh_aliasing_uint64x2_t*) acc; uint8_t const* xsecret = (uint8_t const*) secret; - uint32x2_t prime = vdup_n_u32 (XXH_PRIME32_1); size_t i; - /* NEON for the first few lanes (these loops are normally interleaved) */ - for (i=0; i < XXH3_NEON_LANES / 2; i++) { - /* xacc[i] ^= (xacc[i] >> 47); */ - uint64x2_t acc_vec = xacc[i]; - uint64x2_t shifted = vshrq_n_u64 (acc_vec, 47); - uint64x2_t data_vec = veorq_u64 (acc_vec, shifted); + /* WASM uses operator overloads and doesn't need these. */ +#ifndef __wasm_simd128__ + /* { prime32_1, prime32_1 } */ + uint32x2_t const kPrimeLo = vdup_n_u32(XXH_PRIME32_1); + /* { 0, prime32_1, 0, prime32_1 } */ + uint32x4_t const kPrimeHi = vreinterpretq_u32_u64(vdupq_n_u64((xxh_u64)XXH_PRIME32_1 << 32)); +#endif - /* xacc[i] ^= xsecret[i]; */ - uint8x16_t key_vec = vld1q_u8 (xsecret + (i * 16)); - uint64x2_t data_key = veorq_u64 (data_vec, vreinterpretq_u64_u8(key_vec)); - - /* xacc[i] *= XXH_PRIME32_1 */ - uint32x2_t data_key_lo, data_key_hi; - /* data_key_lo = (uint32x2_t) (xacc[i] & 0xFFFFFFFF); - * data_key_hi = (uint32x2_t) (xacc[i] >> 32); - * xacc[i] = UNDEFINED; */ - XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi); - { /* - * prod_hi = (data_key >> 32) * XXH_PRIME32_1; - * - * Avoid vmul_u32 + vshll_n_u32 since Clang 6 and 7 will - * incorrectly "optimize" this: - * tmp = vmul_u32(vmovn_u64(a), vmovn_u64(b)); - * shifted = vshll_n_u32(tmp, 32); - * to this: - * tmp = "vmulq_u64"(a, b); // no such thing! - * shifted = vshlq_n_u64(tmp, 32); - * - * However, unlike SSE, Clang lacks a 64-bit multiply routine - * for NEON, and it scalarizes two 64-bit multiplies instead. - * - * vmull_u32 has the same timing as vmul_u32, and it avoids - * this bug completely. - * See https://bugs.llvm.org/show_bug.cgi?id=39967 - */ - uint64x2_t prod_hi = vmull_u32 (data_key_hi, prime); - /* xacc[i] = prod_hi << 32; */ - xacc[i] = vshlq_n_u64(prod_hi, 32); - /* xacc[i] += (prod_hi & 0xFFFFFFFF) * XXH_PRIME32_1; */ - xacc[i] = vmlal_u32(xacc[i], data_key_lo, prime); - } - } - /* Scalar for the remainder. This may be a zero iteration loop. */ + /* AArch64 uses both scalar and neon at the same time */ for (i = XXH3_NEON_LANES; i < XXH_ACC_NB; i++) { XXH3_scalarScrambleRound(acc, secret, i); } + for (i=0; i < XXH3_NEON_LANES / 2; i++) { + /* xacc[i] ^= (xacc[i] >> 47); */ + uint64x2_t acc_vec = xacc[i]; + uint64x2_t shifted = vshrq_n_u64(acc_vec, 47); + uint64x2_t data_vec = veorq_u64(acc_vec, shifted); + + /* xacc[i] ^= xsecret[i]; */ + uint64x2_t key_vec = XXH_vld1q_u64(xsecret + (i * 16)); + uint64x2_t data_key = veorq_u64(data_vec, key_vec); + /* xacc[i] *= XXH_PRIME32_1 */ +#ifdef __wasm_simd128__ + /* SIMD128 has multiply by u64x2, use it instead of expanding and scalarizing */ + xacc[i] = data_key * XXH_PRIME32_1; +#else + /* + * Expanded version with portable NEON intrinsics + * + * lo(x) * lo(y) + (hi(x) * lo(y) << 32) + * + * prod_hi = hi(data_key) * lo(prime) << 32 + * + * Since we only need 32 bits of this multiply a trick can be used, reinterpreting the vector + * as a uint32x4_t and multiplying by { 0, prime, 0, prime } to cancel out the unwanted bits + * and avoid the shift. + */ + uint32x4_t prod_hi = vmulq_u32 (vreinterpretq_u32_u64(data_key), kPrimeHi); + /* Extract low bits for vmlal_u32 */ + uint32x2_t data_key_lo = vmovn_u64(data_key); + /* xacc[i] = prod_hi + lo(data_key) * XXH_PRIME32_1; */ + xacc[i] = vmlal_u32(vreinterpretq_u64_u32(prod_hi), data_key_lo, kPrimeLo); +#endif + } } } - #endif #if (XXH_VECTOR == XXH_VSX) @@ -4178,23 +5353,23 @@ XXH3_accumulate_512_vsx( void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) { /* presumed aligned */ - unsigned int* const xacc = (unsigned int*) acc; - xxh_u64x2 const* const xinput = (xxh_u64x2 const*) input; /* no alignment restriction */ - xxh_u64x2 const* const xsecret = (xxh_u64x2 const*) secret; /* no alignment restriction */ + xxh_aliasing_u64x2* const xacc = (xxh_aliasing_u64x2*) acc; + xxh_u8 const* const xinput = (xxh_u8 const*) input; /* no alignment restriction */ + xxh_u8 const* const xsecret = (xxh_u8 const*) secret; /* no alignment restriction */ xxh_u64x2 const v32 = { 32, 32 }; size_t i; for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) { /* data_vec = xinput[i]; */ - xxh_u64x2 const data_vec = XXH_vec_loadu(xinput + i); + xxh_u64x2 const data_vec = XXH_vec_loadu(xinput + 16*i); /* key_vec = xsecret[i]; */ - xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i); + xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + 16*i); xxh_u64x2 const data_key = data_vec ^ key_vec; /* shuffled = (data_key << 32) | (data_key >> 32); */ xxh_u32x4 const shuffled = (xxh_u32x4)vec_rl(data_key, v32); /* product = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)shuffled & 0xFFFFFFFF); */ xxh_u64x2 const product = XXH_vec_mulo((xxh_u32x4)data_key, shuffled); /* acc_vec = xacc[i]; */ - xxh_u64x2 acc_vec = (xxh_u64x2)vec_xl(0, xacc + 4 * i); + xxh_u64x2 acc_vec = xacc[i]; acc_vec += product; /* swap high and low halves */ @@ -4203,18 +5378,18 @@ XXH3_accumulate_512_vsx( void* XXH_RESTRICT acc, #else acc_vec += vec_xxpermdi(data_vec, data_vec, 2); #endif - /* xacc[i] = acc_vec; */ - vec_xst((xxh_u32x4)acc_vec, 0, xacc + 4 * i); + xacc[i] = acc_vec; } } +XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(vsx) XXH_FORCE_INLINE void XXH3_scrambleAcc_vsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) { XXH_ASSERT((((size_t)acc) & 15) == 0); - { xxh_u64x2* const xacc = (xxh_u64x2*) acc; - const xxh_u64x2* const xsecret = (const xxh_u64x2*) secret; + { xxh_aliasing_u64x2* const xacc = (xxh_aliasing_u64x2*) acc; + const xxh_u8* const xsecret = (const xxh_u8*) secret; /* constants */ xxh_u64x2 const v32 = { 32, 32 }; xxh_u64x2 const v47 = { 47, 47 }; @@ -4226,7 +5401,7 @@ XXH3_scrambleAcc_vsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) xxh_u64x2 const data_vec = acc_vec ^ (acc_vec >> v47); /* xacc[i] ^= xsecret[i]; */ - xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i); + xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + 16*i); xxh_u64x2 const data_key = data_vec ^ key_vec; /* xacc[i] *= XXH_PRIME32_1 */ @@ -4240,8 +5415,148 @@ XXH3_scrambleAcc_vsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) #endif +#if (XXH_VECTOR == XXH_SVE) + +XXH_FORCE_INLINE void +XXH3_accumulate_512_sve( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + uint64_t *xacc = (uint64_t *)acc; + const uint64_t *xinput = (const uint64_t *)(const void *)input; + const uint64_t *xsecret = (const uint64_t *)(const void *)secret; + svuint64_t kSwap = sveor_n_u64_z(svptrue_b64(), svindex_u64(0, 1), 1); + uint64_t element_count = svcntd(); + if (element_count >= 8) { + svbool_t mask = svptrue_pat_b64(SV_VL8); + svuint64_t vacc = svld1_u64(mask, xacc); + ACCRND(vacc, 0); + svst1_u64(mask, xacc, vacc); + } else if (element_count == 2) { /* sve128 */ + svbool_t mask = svptrue_pat_b64(SV_VL2); + svuint64_t acc0 = svld1_u64(mask, xacc + 0); + svuint64_t acc1 = svld1_u64(mask, xacc + 2); + svuint64_t acc2 = svld1_u64(mask, xacc + 4); + svuint64_t acc3 = svld1_u64(mask, xacc + 6); + ACCRND(acc0, 0); + ACCRND(acc1, 2); + ACCRND(acc2, 4); + ACCRND(acc3, 6); + svst1_u64(mask, xacc + 0, acc0); + svst1_u64(mask, xacc + 2, acc1); + svst1_u64(mask, xacc + 4, acc2); + svst1_u64(mask, xacc + 6, acc3); + } else { + svbool_t mask = svptrue_pat_b64(SV_VL4); + svuint64_t acc0 = svld1_u64(mask, xacc + 0); + svuint64_t acc1 = svld1_u64(mask, xacc + 4); + ACCRND(acc0, 0); + ACCRND(acc1, 4); + svst1_u64(mask, xacc + 0, acc0); + svst1_u64(mask, xacc + 4, acc1); + } +} + +XXH_FORCE_INLINE void +XXH3_accumulate_sve(xxh_u64* XXH_RESTRICT acc, + const xxh_u8* XXH_RESTRICT input, + const xxh_u8* XXH_RESTRICT secret, + size_t nbStripes) +{ + if (nbStripes != 0) { + uint64_t *xacc = (uint64_t *)acc; + const uint64_t *xinput = (const uint64_t *)(const void *)input; + const uint64_t *xsecret = (const uint64_t *)(const void *)secret; + svuint64_t kSwap = sveor_n_u64_z(svptrue_b64(), svindex_u64(0, 1), 1); + uint64_t element_count = svcntd(); + if (element_count >= 8) { + svbool_t mask = svptrue_pat_b64(SV_VL8); + svuint64_t vacc = svld1_u64(mask, xacc + 0); + do { + /* svprfd(svbool_t, void *, enum svfprop); */ + svprfd(mask, xinput + 128, SV_PLDL1STRM); + ACCRND(vacc, 0); + xinput += 8; + xsecret += 1; + nbStripes--; + } while (nbStripes != 0); + + svst1_u64(mask, xacc + 0, vacc); + } else if (element_count == 2) { /* sve128 */ + svbool_t mask = svptrue_pat_b64(SV_VL2); + svuint64_t acc0 = svld1_u64(mask, xacc + 0); + svuint64_t acc1 = svld1_u64(mask, xacc + 2); + svuint64_t acc2 = svld1_u64(mask, xacc + 4); + svuint64_t acc3 = svld1_u64(mask, xacc + 6); + do { + svprfd(mask, xinput + 128, SV_PLDL1STRM); + ACCRND(acc0, 0); + ACCRND(acc1, 2); + ACCRND(acc2, 4); + ACCRND(acc3, 6); + xinput += 8; + xsecret += 1; + nbStripes--; + } while (nbStripes != 0); + + svst1_u64(mask, xacc + 0, acc0); + svst1_u64(mask, xacc + 2, acc1); + svst1_u64(mask, xacc + 4, acc2); + svst1_u64(mask, xacc + 6, acc3); + } else { + svbool_t mask = svptrue_pat_b64(SV_VL4); + svuint64_t acc0 = svld1_u64(mask, xacc + 0); + svuint64_t acc1 = svld1_u64(mask, xacc + 4); + do { + svprfd(mask, xinput + 128, SV_PLDL1STRM); + ACCRND(acc0, 0); + ACCRND(acc1, 4); + xinput += 8; + xsecret += 1; + nbStripes--; + } while (nbStripes != 0); + + svst1_u64(mask, xacc + 0, acc0); + svst1_u64(mask, xacc + 4, acc1); + } + } +} + +#endif + /* scalar variants - universal */ +#if defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) +/* + * In XXH3_scalarRound(), GCC and Clang have a similar codegen issue, where they + * emit an excess mask and a full 64-bit multiply-add (MADD X-form). + * + * While this might not seem like much, as AArch64 is a 64-bit architecture, only + * big Cortex designs have a full 64-bit multiplier. + * + * On the little cores, the smaller 32-bit multiplier is used, and full 64-bit + * multiplies expand to 2-3 multiplies in microcode. This has a major penalty + * of up to 4 latency cycles and 2 stall cycles in the multiply pipeline. + * + * Thankfully, AArch64 still provides the 32-bit long multiply-add (UMADDL) which does + * not have this penalty and does the mask automatically. + */ +XXH_FORCE_INLINE xxh_u64 +XXH_mult32to64_add64(xxh_u64 lhs, xxh_u64 rhs, xxh_u64 acc) +{ + xxh_u64 ret; + /* note: %x = 64-bit register, %w = 32-bit register */ + __asm__("umaddl %x0, %w1, %w2, %x3" : "=r" (ret) : "r" (lhs), "r" (rhs), "r" (acc)); + return ret; +} +#else +XXH_FORCE_INLINE xxh_u64 +XXH_mult32to64_add64(xxh_u64 lhs, xxh_u64 rhs, xxh_u64 acc) +{ + return XXH_mult32to64((xxh_u32)lhs, (xxh_u32)rhs) + acc; +} +#endif + /*! * @internal * @brief Scalar round for @ref XXH3_accumulate_512_scalar(). @@ -4264,7 +5579,7 @@ XXH3_scalarRound(void* XXH_RESTRICT acc, xxh_u64 const data_val = XXH_readLE64(xinput + lane * 8); xxh_u64 const data_key = data_val ^ XXH_readLE64(xsecret + lane * 8); xacc[lane ^ 1] += data_val; /* swap adjacent lanes */ - xacc[lane] += XXH_mult32to64(data_key & 0xFFFFFFFF, data_key >> 32); + xacc[lane] = XXH_mult32to64_add64(data_key /* & 0xFFFFFFFF */, data_key >> 32, xacc[lane]); } } @@ -4278,10 +5593,18 @@ XXH3_accumulate_512_scalar(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) { size_t i; + /* ARM GCC refuses to unroll this loop, resulting in a 24% slowdown on ARMv6. */ +#if defined(__GNUC__) && !defined(__clang__) \ + && (defined(__arm__) || defined(__thumb2__)) \ + && defined(__ARM_FEATURE_UNALIGNED) /* no unaligned access just wastes bytes */ \ + && XXH_SIZE_OPT <= 0 +# pragma GCC unroll 8 +#endif for (i=0; i < XXH_ACC_NB; i++) { XXH3_scalarRound(acc, input, secret, i); } } +XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(scalar) /*! * @internal @@ -4333,10 +5656,10 @@ XXH3_initCustomSecret_scalar(void* XXH_RESTRICT customSecret, xxh_u64 seed64) const xxh_u8* kSecretPtr = XXH3_kSecret; XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0); -#if defined(__clang__) && defined(__aarch64__) +#if defined(__GNUC__) && defined(__aarch64__) /* * UGLY HACK: - * Clang generates a bunch of MOV/MOVK pairs for aarch64, and they are + * GCC and Clang generate a bunch of MOV/MOVK pairs for aarch64, and they are * placed sequentially, in order, at the top of the unrolled loop. * * While MOVK is great for generating constants (2 cycles for a 64-bit @@ -4351,7 +5674,7 @@ XXH3_initCustomSecret_scalar(void* XXH_RESTRICT customSecret, xxh_u64 seed64) * ADD * SUB STR * STR - * By forcing loads from memory (as the asm line causes Clang to assume + * By forcing loads from memory (as the asm line causes the compiler to assume * that XXH3_kSecretPtr has been changed), the pipelines are used more * efficiently: * I L S @@ -4368,17 +5691,11 @@ XXH3_initCustomSecret_scalar(void* XXH_RESTRICT customSecret, xxh_u64 seed64) */ XXH_COMPILER_GUARD(kSecretPtr); #endif - /* - * Note: in debug mode, this overrides the asm optimization - * and Clang will emit MOVK chains again. - */ - XXH_ASSERT(kSecretPtr == XXH3_kSecret); - { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / 16; int i; for (i=0; i < nbRounds; i++) { /* - * The asm hack causes Clang to assume that kSecretPtr aliases with + * The asm hack causes the compiler to assume that kSecretPtr aliases with * customSecret, and on aarch64, this prevented LDP from merging two * loads together for free. Putting the loads together before the stores * properly generates LDP. @@ -4391,7 +5708,7 @@ XXH3_initCustomSecret_scalar(void* XXH_RESTRICT customSecret, xxh_u64 seed64) } -typedef void (*XXH3_f_accumulate_512)(void* XXH_RESTRICT, const void*, const void*); +typedef void (*XXH3_f_accumulate)(xxh_u64* XXH_RESTRICT, const xxh_u8* XXH_RESTRICT, const xxh_u8* XXH_RESTRICT, size_t); typedef void (*XXH3_f_scrambleAcc)(void* XXH_RESTRICT, const void*); typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64); @@ -4399,82 +5716,63 @@ typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64); #if (XXH_VECTOR == XXH_AVX512) #define XXH3_accumulate_512 XXH3_accumulate_512_avx512 +#define XXH3_accumulate XXH3_accumulate_avx512 #define XXH3_scrambleAcc XXH3_scrambleAcc_avx512 #define XXH3_initCustomSecret XXH3_initCustomSecret_avx512 #elif (XXH_VECTOR == XXH_AVX2) #define XXH3_accumulate_512 XXH3_accumulate_512_avx2 +#define XXH3_accumulate XXH3_accumulate_avx2 #define XXH3_scrambleAcc XXH3_scrambleAcc_avx2 #define XXH3_initCustomSecret XXH3_initCustomSecret_avx2 #elif (XXH_VECTOR == XXH_SSE2) #define XXH3_accumulate_512 XXH3_accumulate_512_sse2 +#define XXH3_accumulate XXH3_accumulate_sse2 #define XXH3_scrambleAcc XXH3_scrambleAcc_sse2 #define XXH3_initCustomSecret XXH3_initCustomSecret_sse2 #elif (XXH_VECTOR == XXH_NEON) #define XXH3_accumulate_512 XXH3_accumulate_512_neon +#define XXH3_accumulate XXH3_accumulate_neon #define XXH3_scrambleAcc XXH3_scrambleAcc_neon #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar #elif (XXH_VECTOR == XXH_VSX) #define XXH3_accumulate_512 XXH3_accumulate_512_vsx +#define XXH3_accumulate XXH3_accumulate_vsx #define XXH3_scrambleAcc XXH3_scrambleAcc_vsx #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar +#elif (XXH_VECTOR == XXH_SVE) +#define XXH3_accumulate_512 XXH3_accumulate_512_sve +#define XXH3_accumulate XXH3_accumulate_sve +#define XXH3_scrambleAcc XXH3_scrambleAcc_scalar +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + #else /* scalar */ #define XXH3_accumulate_512 XXH3_accumulate_512_scalar +#define XXH3_accumulate XXH3_accumulate_scalar #define XXH3_scrambleAcc XXH3_scrambleAcc_scalar #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar #endif - - -#ifndef XXH_PREFETCH_DIST -# ifdef __clang__ -# define XXH_PREFETCH_DIST 320 -# else -# if (XXH_VECTOR == XXH_AVX512) -# define XXH_PREFETCH_DIST 512 -# else -# define XXH_PREFETCH_DIST 384 -# endif -# endif /* __clang__ */ -#endif /* XXH_PREFETCH_DIST */ - -/* - * XXH3_accumulate() - * Loops over XXH3_accumulate_512(). - * Assumption: nbStripes will not overflow the secret size - */ -XXH_FORCE_INLINE void -XXH3_accumulate( xxh_u64* XXH_RESTRICT acc, - const xxh_u8* XXH_RESTRICT input, - const xxh_u8* XXH_RESTRICT secret, - size_t nbStripes, - XXH3_f_accumulate_512 f_acc512) -{ - size_t n; - for (n = 0; n < nbStripes; n++ ) { - const xxh_u8* const in = input + n*XXH_STRIPE_LEN; - XXH_PREFETCH(in + XXH_PREFETCH_DIST); - f_acc512(acc, - in, - secret + n*XXH_SECRET_CONSUME_RATE); - } -} +#if XXH_SIZE_OPT >= 1 /* don't do SIMD for initialization */ +# undef XXH3_initCustomSecret +# define XXH3_initCustomSecret XXH3_initCustomSecret_scalar +#endif XXH_FORCE_INLINE void XXH3_hashLong_internal_loop(xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, - XXH3_f_accumulate_512 f_acc512, + XXH3_f_accumulate f_acc, XXH3_f_scrambleAcc f_scramble) { size_t const nbStripesPerBlock = (secretSize - XXH_STRIPE_LEN) / XXH_SECRET_CONSUME_RATE; @@ -4486,7 +5784,7 @@ XXH3_hashLong_internal_loop(xxh_u64* XXH_RESTRICT acc, XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); for (n = 0; n < nb_blocks; n++) { - XXH3_accumulate(acc, input + n*block_len, secret, nbStripesPerBlock, f_acc512); + f_acc(acc, input + n*block_len, secret, nbStripesPerBlock); f_scramble(acc, secret + secretSize - XXH_STRIPE_LEN); } @@ -4494,12 +5792,12 @@ XXH3_hashLong_internal_loop(xxh_u64* XXH_RESTRICT acc, XXH_ASSERT(len > XXH_STRIPE_LEN); { size_t const nbStripes = ((len - 1) - (block_len * nb_blocks)) / XXH_STRIPE_LEN; XXH_ASSERT(nbStripes <= (secretSize / XXH_SECRET_CONSUME_RATE)); - XXH3_accumulate(acc, input + nb_blocks*block_len, secret, nbStripes, f_acc512); + f_acc(acc, input + nb_blocks*block_len, secret, nbStripes); /* last stripe */ { const xxh_u8* const p = input + len - XXH_STRIPE_LEN; #define XXH_SECRET_LASTACC_START 7 /* not aligned on 8, last secret is different from acc & scrambler */ - f_acc512(acc, p, secret + secretSize - XXH_STRIPE_LEN - XXH_SECRET_LASTACC_START); + XXH3_accumulate_512(acc, p, secret + secretSize - XXH_STRIPE_LEN - XXH_SECRET_LASTACC_START); } } } @@ -4544,12 +5842,12 @@ XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secre XXH_FORCE_INLINE XXH64_hash_t XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len, const void* XXH_RESTRICT secret, size_t secretSize, - XXH3_f_accumulate_512 f_acc512, + XXH3_f_accumulate f_acc, XXH3_f_scrambleAcc f_scramble) { XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC; - XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize, f_acc512, f_scramble); + XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize, f_acc, f_scramble); /* converge into final hash */ XXH_STATIC_ASSERT(sizeof(acc) == 64); @@ -4563,13 +5861,15 @@ XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len, * It's important for performance to transmit secret's size (when it's static) * so that the compiler can properly optimize the vectorized loop. * This makes a big performance difference for "medium" keys (<1 KB) when using AVX instruction set. + * When the secret size is unknown, or on GCC 12 where the mix of NO_INLINE and FORCE_INLINE + * breaks -Og, this is XXH_NO_INLINE. */ -XXH_FORCE_INLINE XXH64_hash_t +XXH3_WITH_SECRET_INLINE XXH64_hash_t XXH3_hashLong_64b_withSecret(const void* XXH_RESTRICT input, size_t len, XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen) { (void)seed64; - return XXH3_hashLong_64b_internal(input, len, secret, secretLen, XXH3_accumulate_512, XXH3_scrambleAcc); + return XXH3_hashLong_64b_internal(input, len, secret, secretLen, XXH3_accumulate, XXH3_scrambleAcc); } /* @@ -4578,12 +5878,12 @@ XXH3_hashLong_64b_withSecret(const void* XXH_RESTRICT input, size_t len, * Note that inside this no_inline function, we do inline the internal loop, * and provide a statically defined secret size to allow optimization of vector loop. */ -XXH_NO_INLINE XXH64_hash_t +XXH_NO_INLINE XXH_PUREF XXH64_hash_t XXH3_hashLong_64b_default(const void* XXH_RESTRICT input, size_t len, XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen) { (void)seed64; (void)secret; (void)secretLen; - return XXH3_hashLong_64b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_accumulate_512, XXH3_scrambleAcc); + return XXH3_hashLong_64b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_accumulate, XXH3_scrambleAcc); } /* @@ -4600,18 +5900,20 @@ XXH3_hashLong_64b_default(const void* XXH_RESTRICT input, size_t len, XXH_FORCE_INLINE XXH64_hash_t XXH3_hashLong_64b_withSeed_internal(const void* input, size_t len, XXH64_hash_t seed, - XXH3_f_accumulate_512 f_acc512, + XXH3_f_accumulate f_acc, XXH3_f_scrambleAcc f_scramble, XXH3_f_initCustomSecret f_initSec) { +#if XXH_SIZE_OPT <= 0 if (seed == 0) return XXH3_hashLong_64b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), - f_acc512, f_scramble); + f_acc, f_scramble); +#endif { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE]; f_initSec(secret, seed); return XXH3_hashLong_64b_internal(input, len, secret, sizeof(secret), - f_acc512, f_scramble); + f_acc, f_scramble); } } @@ -4619,12 +5921,12 @@ XXH3_hashLong_64b_withSeed_internal(const void* input, size_t len, * It's important for performance that XXH3_hashLong is not inlined. */ XXH_NO_INLINE XXH64_hash_t -XXH3_hashLong_64b_withSeed(const void* input, size_t len, - XXH64_hash_t seed, const xxh_u8* secret, size_t secretLen) +XXH3_hashLong_64b_withSeed(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed, const xxh_u8* XXH_RESTRICT secret, size_t secretLen) { (void)secret; (void)secretLen; return XXH3_hashLong_64b_withSeed_internal(input, len, seed, - XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret); + XXH3_accumulate, XXH3_scrambleAcc, XXH3_initCustomSecret); } @@ -4656,37 +5958,37 @@ XXH3_64bits_internal(const void* XXH_RESTRICT input, size_t len, /* === Public entry point === */ -/*! @ingroup xxh3_family */ -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* input, size_t len) +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(XXH_NOESCAPE const void* input, size_t length) { - return XXH3_64bits_internal(input, len, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_default); + return XXH3_64bits_internal(input, length, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_default); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH64_hash_t -XXH3_64bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize) +XXH3_64bits_withSecret(XXH_NOESCAPE const void* input, size_t length, XXH_NOESCAPE const void* secret, size_t secretSize) { - return XXH3_64bits_internal(input, len, 0, secret, secretSize, XXH3_hashLong_64b_withSecret); + return XXH3_64bits_internal(input, length, 0, secret, secretSize, XXH3_hashLong_64b_withSecret); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH64_hash_t -XXH3_64bits_withSeed(const void* input, size_t len, XXH64_hash_t seed) +XXH3_64bits_withSeed(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed) { - return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed); + return XXH3_64bits_internal(input, length, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed); } XXH_PUBLIC_API XXH64_hash_t -XXH3_64bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed) +XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed) { - if (len <= XXH3_MIDSIZE_MAX) - return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL); - return XXH3_hashLong_64b_withSecret(input, len, seed, (const xxh_u8*)secret, secretSize); + if (length <= XXH3_MIDSIZE_MAX) + return XXH3_64bits_internal(input, length, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL); + return XXH3_hashLong_64b_withSecret(input, length, seed, (const xxh_u8*)secret, secretSize); } /* === XXH3 streaming === */ - +#ifndef XXH_NO_STREAM /* * Malloc's a pointer that is always aligned to align. * @@ -4710,7 +6012,7 @@ XXH3_64bits_withSecretandSeed(const void* input, size_t len, const void* secret, * * Align must be a power of 2 and 8 <= align <= 128. */ -static void* XXH_alignedMalloc(size_t s, size_t align) +static XXH_MALLOCF void* XXH_alignedMalloc(size_t s, size_t align) { XXH_ASSERT(align <= 128 && align >= 8); /* range check */ XXH_ASSERT((align & (align-1)) == 0); /* power of 2 */ @@ -4752,7 +6054,15 @@ static void XXH_alignedFree(void* p) XXH_free(base); } } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ +/*! + * @brief Allocate an @ref XXH3_state_t. + * + * @return An allocated pointer of @ref XXH3_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH3_freeState(). + */ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) { XXH3_state_t* const state = (XXH3_state_t*)XXH_alignedMalloc(sizeof(XXH3_state_t), 64); @@ -4761,16 +6071,25 @@ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) return state; } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ +/*! + * @brief Frees an @ref XXH3_state_t. + * + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * + * @return @ref XXH_OK. + * + * @note Must be allocated with XXH3_createState(). + */ XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr) { XXH_alignedFree(statePtr); return XXH_OK; } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API void -XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state) +XXH3_copyState(XXH_NOESCAPE XXH3_state_t* dst_state, XXH_NOESCAPE const XXH3_state_t* src_state) { XXH_memcpy(dst_state, src_state, sizeof(*dst_state)); } @@ -4802,18 +6121,18 @@ XXH3_reset_internal(XXH3_state_t* statePtr, statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE; } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_reset(XXH3_state_t* statePtr) +XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr) { if (statePtr == NULL) return XXH_ERROR; XXH3_reset_internal(statePtr, 0, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE); return XXH_OK; } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize) +XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize) { if (statePtr == NULL) return XXH_ERROR; XXH3_reset_internal(statePtr, 0, secret, secretSize); @@ -4822,9 +6141,9 @@ XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t return XXH_OK; } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed) +XXH3_64bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed) { if (statePtr == NULL) return XXH_ERROR; if (seed==0) return XXH3_64bits_reset(statePtr); @@ -4834,9 +6153,9 @@ XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed) return XXH_OK; } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed64) +XXH3_64bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64) { if (statePtr == NULL) return XXH_ERROR; if (secret == NULL) return XXH_ERROR; @@ -4846,35 +6165,61 @@ XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, return XXH_OK; } -/* Note : when XXH3_consumeStripes() is invoked, - * there must be a guarantee that at least one more byte must be consumed from input - * so that the function can blindly consume all stripes using the "normal" secret segment */ -XXH_FORCE_INLINE void +/*! + * @internal + * @brief Processes a large input for XXH3_update() and XXH3_digest_long(). + * + * Unlike XXH3_hashLong_internal_loop(), this can process data that overlaps a block. + * + * @param acc Pointer to the 8 accumulator lanes + * @param nbStripesSoFarPtr In/out pointer to the number of leftover stripes in the block* + * @param nbStripesPerBlock Number of stripes in a block + * @param input Input pointer + * @param nbStripes Number of stripes to process + * @param secret Secret pointer + * @param secretLimit Offset of the last block in @p secret + * @param f_acc Pointer to an XXH3_accumulate implementation + * @param f_scramble Pointer to an XXH3_scrambleAcc implementation + * @return Pointer past the end of @p input after processing + */ +XXH_FORCE_INLINE const xxh_u8 * XXH3_consumeStripes(xxh_u64* XXH_RESTRICT acc, size_t* XXH_RESTRICT nbStripesSoFarPtr, size_t nbStripesPerBlock, const xxh_u8* XXH_RESTRICT input, size_t nbStripes, const xxh_u8* XXH_RESTRICT secret, size_t secretLimit, - XXH3_f_accumulate_512 f_acc512, + XXH3_f_accumulate f_acc, XXH3_f_scrambleAcc f_scramble) { - XXH_ASSERT(nbStripes <= nbStripesPerBlock); /* can handle max 1 scramble per invocation */ - XXH_ASSERT(*nbStripesSoFarPtr < nbStripesPerBlock); - if (nbStripesPerBlock - *nbStripesSoFarPtr <= nbStripes) { - /* need a scrambling operation */ - size_t const nbStripesToEndofBlock = nbStripesPerBlock - *nbStripesSoFarPtr; - size_t const nbStripesAfterBlock = nbStripes - nbStripesToEndofBlock; - XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripesToEndofBlock, f_acc512); - f_scramble(acc, secret + secretLimit); - XXH3_accumulate(acc, input + nbStripesToEndofBlock * XXH_STRIPE_LEN, secret, nbStripesAfterBlock, f_acc512); - *nbStripesSoFarPtr = nbStripesAfterBlock; - } else { - XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripes, f_acc512); + const xxh_u8* initialSecret = secret + *nbStripesSoFarPtr * XXH_SECRET_CONSUME_RATE; + /* Process full blocks */ + if (nbStripes >= (nbStripesPerBlock - *nbStripesSoFarPtr)) { + /* Process the initial partial block... */ + size_t nbStripesThisIter = nbStripesPerBlock - *nbStripesSoFarPtr; + + do { + /* Accumulate and scramble */ + f_acc(acc, input, initialSecret, nbStripesThisIter); + f_scramble(acc, secret + secretLimit); + input += nbStripesThisIter * XXH_STRIPE_LEN; + nbStripes -= nbStripesThisIter; + /* Then continue the loop with the full block size */ + nbStripesThisIter = nbStripesPerBlock; + initialSecret = secret; + } while (nbStripes >= nbStripesPerBlock); + *nbStripesSoFarPtr = 0; + } + /* Process a partial block */ + if (nbStripes > 0) { + f_acc(acc, input, initialSecret, nbStripes); + input += nbStripes * XXH_STRIPE_LEN; *nbStripesSoFarPtr += nbStripes; } + /* Return end pointer */ + return input; } #ifndef XXH3_STREAM_USE_STACK -# ifndef __clang__ /* clang doesn't need additional stack space */ +# if XXH_SIZE_OPT <= 0 && !defined(__clang__) /* clang doesn't need additional stack space */ # define XXH3_STREAM_USE_STACK 1 # endif #endif @@ -4884,7 +6229,7 @@ XXH3_consumeStripes(xxh_u64* XXH_RESTRICT acc, XXH_FORCE_INLINE XXH_errorcode XXH3_update(XXH3_state_t* XXH_RESTRICT const state, const xxh_u8* XXH_RESTRICT input, size_t len, - XXH3_f_accumulate_512 f_acc512, + XXH3_f_accumulate f_acc, XXH3_f_scrambleAcc f_scramble) { if (input==NULL) { @@ -4900,7 +6245,8 @@ XXH3_update(XXH3_state_t* XXH_RESTRICT const state, * when operating accumulators directly into state. * Operating into stack space seems to enable proper optimization. * clang, on the other hand, doesn't seem to need this trick */ - XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[8]; memcpy(acc, state->acc, sizeof(acc)); + XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[8]; + XXH_memcpy(acc, state->acc, sizeof(acc)); #else xxh_u64* XXH_RESTRICT const acc = state->acc; #endif @@ -4908,7 +6254,7 @@ XXH3_update(XXH3_state_t* XXH_RESTRICT const state, XXH_ASSERT(state->bufferedSize <= XXH3_INTERNALBUFFER_SIZE); /* small input : just fill in tmp buffer */ - if (state->bufferedSize + len <= XXH3_INTERNALBUFFER_SIZE) { + if (len <= XXH3_INTERNALBUFFER_SIZE - state->bufferedSize) { XXH_memcpy(state->buffer + state->bufferedSize, input, len); state->bufferedSize += (XXH32_hash_t)len; return XXH_OK; @@ -4930,57 +6276,20 @@ XXH3_update(XXH3_state_t* XXH_RESTRICT const state, &state->nbStripesSoFar, state->nbStripesPerBlock, state->buffer, XXH3_INTERNALBUFFER_STRIPES, secret, state->secretLimit, - f_acc512, f_scramble); + f_acc, f_scramble); state->bufferedSize = 0; } XXH_ASSERT(input < bEnd); - - /* large input to consume : ingest per full block */ - if ((size_t)(bEnd - input) > state->nbStripesPerBlock * XXH_STRIPE_LEN) { + if (bEnd - input > XXH3_INTERNALBUFFER_SIZE) { size_t nbStripes = (size_t)(bEnd - 1 - input) / XXH_STRIPE_LEN; - XXH_ASSERT(state->nbStripesPerBlock >= state->nbStripesSoFar); - /* join to current block's end */ - { size_t const nbStripesToEnd = state->nbStripesPerBlock - state->nbStripesSoFar; - XXH_ASSERT(nbStripesToEnd <= nbStripes); - XXH3_accumulate(acc, input, secret + state->nbStripesSoFar * XXH_SECRET_CONSUME_RATE, nbStripesToEnd, f_acc512); - f_scramble(acc, secret + state->secretLimit); - state->nbStripesSoFar = 0; - input += nbStripesToEnd * XXH_STRIPE_LEN; - nbStripes -= nbStripesToEnd; - } - /* consume per entire blocks */ - while(nbStripes >= state->nbStripesPerBlock) { - XXH3_accumulate(acc, input, secret, state->nbStripesPerBlock, f_acc512); - f_scramble(acc, secret + state->secretLimit); - input += state->nbStripesPerBlock * XXH_STRIPE_LEN; - nbStripes -= state->nbStripesPerBlock; - } - /* consume last partial block */ - XXH3_accumulate(acc, input, secret, nbStripes, f_acc512); - input += nbStripes * XXH_STRIPE_LEN; - XXH_ASSERT(input < bEnd); /* at least some bytes left */ - state->nbStripesSoFar = nbStripes; - /* buffer predecessor of last partial stripe */ - XXH_memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN); - XXH_ASSERT(bEnd - input <= XXH_STRIPE_LEN); - } else { - /* content to consume <= block size */ - /* Consume input by a multiple of internal buffer size */ - if (bEnd - input > XXH3_INTERNALBUFFER_SIZE) { - const xxh_u8* const limit = bEnd - XXH3_INTERNALBUFFER_SIZE; - do { - XXH3_consumeStripes(acc, + input = XXH3_consumeStripes(acc, &state->nbStripesSoFar, state->nbStripesPerBlock, - input, XXH3_INTERNALBUFFER_STRIPES, - secret, state->secretLimit, - f_acc512, f_scramble); - input += XXH3_INTERNALBUFFER_SIZE; - } while (inputbuffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN); - } - } + input, nbStripes, + secret, state->secretLimit, + f_acc, f_scramble); + XXH_memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN); + } /* Some remaining input (always) : buffer it */ XXH_ASSERT(input < bEnd); XXH_ASSERT(bEnd - input <= XXH3_INTERNALBUFFER_SIZE); @@ -4989,19 +6298,19 @@ XXH3_update(XXH3_state_t* XXH_RESTRICT const state, state->bufferedSize = (XXH32_hash_t)(bEnd-input); #if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1 /* save stack accumulators into state */ - memcpy(state->acc, acc, sizeof(acc)); + XXH_memcpy(state->acc, acc, sizeof(acc)); #endif } return XXH_OK; } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_update(XXH3_state_t* state, const void* input, size_t len) +XXH3_64bits_update(XXH_NOESCAPE XXH3_state_t* state, XXH_NOESCAPE const void* input, size_t len) { return XXH3_update(state, (const xxh_u8*)input, len, - XXH3_accumulate_512, XXH3_scrambleAcc); + XXH3_accumulate, XXH3_scrambleAcc); } @@ -5010,37 +6319,40 @@ XXH3_digest_long (XXH64_hash_t* acc, const XXH3_state_t* state, const unsigned char* secret) { + xxh_u8 lastStripe[XXH_STRIPE_LEN]; + const xxh_u8* lastStripePtr; + /* * Digest on a local copy. This way, the state remains unaltered, and it can * continue ingesting more input afterwards. */ XXH_memcpy(acc, state->acc, sizeof(state->acc)); if (state->bufferedSize >= XXH_STRIPE_LEN) { + /* Consume remaining stripes then point to remaining data in buffer */ size_t const nbStripes = (state->bufferedSize - 1) / XXH_STRIPE_LEN; size_t nbStripesSoFar = state->nbStripesSoFar; XXH3_consumeStripes(acc, &nbStripesSoFar, state->nbStripesPerBlock, state->buffer, nbStripes, secret, state->secretLimit, - XXH3_accumulate_512, XXH3_scrambleAcc); - /* last stripe */ - XXH3_accumulate_512(acc, - state->buffer + state->bufferedSize - XXH_STRIPE_LEN, - secret + state->secretLimit - XXH_SECRET_LASTACC_START); + XXH3_accumulate, XXH3_scrambleAcc); + lastStripePtr = state->buffer + state->bufferedSize - XXH_STRIPE_LEN; } else { /* bufferedSize < XXH_STRIPE_LEN */ - xxh_u8 lastStripe[XXH_STRIPE_LEN]; + /* Copy to temp buffer */ size_t const catchupSize = XXH_STRIPE_LEN - state->bufferedSize; XXH_ASSERT(state->bufferedSize > 0); /* there is always some input buffered */ XXH_memcpy(lastStripe, state->buffer + sizeof(state->buffer) - catchupSize, catchupSize); XXH_memcpy(lastStripe + catchupSize, state->buffer, state->bufferedSize); - XXH3_accumulate_512(acc, - lastStripe, - secret + state->secretLimit - XXH_SECRET_LASTACC_START); + lastStripePtr = lastStripe; } + /* Last stripe */ + XXH3_accumulate_512(acc, + lastStripePtr, + secret + state->secretLimit - XXH_SECRET_LASTACC_START); } -/*! @ingroup xxh3_family */ -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state) +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* state) { const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret; if (state->totalLen > XXH3_MIDSIZE_MAX) { @@ -5056,7 +6368,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state) return XXH3_64bits_withSecret(state->buffer, (size_t)(state->totalLen), secret, state->secretLimit + XXH_STRIPE_LEN); } - +#endif /* !XXH_NO_STREAM */ /* ========================================== @@ -5076,7 +6388,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state) * fast for a _128-bit_ hash on 32-bit (it usually clears XXH64). */ -XXH_FORCE_INLINE XXH128_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) { /* A doubled version of 1to3_64b with different constants. */ @@ -5105,7 +6417,7 @@ XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_ } } -XXH_FORCE_INLINE XXH128_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) { XXH_ASSERT(input != NULL); @@ -5125,14 +6437,14 @@ XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_ m128.low64 ^= (m128.high64 >> 3); m128.low64 = XXH_xorshift64(m128.low64, 35); - m128.low64 *= 0x9FB21C651E98DF25ULL; + m128.low64 *= PRIME_MX2; m128.low64 = XXH_xorshift64(m128.low64, 28); m128.high64 = XXH3_avalanche(m128.high64); return m128; } } -XXH_FORCE_INLINE XXH128_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) { XXH_ASSERT(input != NULL); @@ -5207,7 +6519,7 @@ XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64 /* * Assumption: `secret` size is >= XXH3_SECRET_SIZE_MIN */ -XXH_FORCE_INLINE XXH128_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t XXH3_len_0to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) { XXH_ASSERT(len <= 16); @@ -5238,7 +6550,7 @@ XXH128_mix32B(XXH128_hash_t acc, const xxh_u8* input_1, const xxh_u8* input_2, } -XXH_FORCE_INLINE XXH128_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, XXH64_hash_t seed) @@ -5249,6 +6561,16 @@ XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len, { XXH128_hash_t acc; acc.low64 = len * XXH_PRIME64_1; acc.high64 = 0; + +#if XXH_SIZE_OPT >= 1 + { + /* Smaller, but slightly slower. */ + unsigned int i = (unsigned int)(len - 1) / 32; + do { + acc = XXH128_mix32B(acc, input+16*i, input+len-16*(i+1), secret+32*i, seed); + } while (i-- != 0); + } +#else if (len > 32) { if (len > 64) { if (len > 96) { @@ -5259,6 +6581,7 @@ XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len, acc = XXH128_mix32B(acc, input+16, input+len-32, secret+32, seed); } acc = XXH128_mix32B(acc, input, input+len-16, secret, seed); +#endif { XXH128_hash_t h128; h128.low64 = acc.low64 + acc.high64; h128.high64 = (acc.low64 * XXH_PRIME64_1) @@ -5271,7 +6594,7 @@ XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len, } } -XXH_NO_INLINE XXH128_hash_t +XXH_NO_INLINE XXH_PUREF XXH128_hash_t XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, XXH64_hash_t seed) @@ -5280,25 +6603,34 @@ XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX); { XXH128_hash_t acc; - int const nbRounds = (int)len / 32; - int i; + unsigned i; acc.low64 = len * XXH_PRIME64_1; acc.high64 = 0; - for (i=0; i<4; i++) { + /* + * We set as `i` as offset + 32. We do this so that unchanged + * `len` can be used as upper bound. This reaches a sweet spot + * where both x86 and aarch64 get simple agen and good codegen + * for the loop. + */ + for (i = 32; i < 160; i += 32) { acc = XXH128_mix32B(acc, - input + (32 * i), - input + (32 * i) + 16, - secret + (32 * i), + input + i - 32, + input + i - 16, + secret + i - 32, seed); } acc.low64 = XXH3_avalanche(acc.low64); acc.high64 = XXH3_avalanche(acc.high64); - XXH_ASSERT(nbRounds >= 4); - for (i=4 ; i < nbRounds; i++) { + /* + * NB: `i <= len` will duplicate the last 32-bytes if + * len % 32 was zero. This is an unfortunate necessity to keep + * the hash result stable. + */ + for (i=160; i <= len; i += 32) { acc = XXH128_mix32B(acc, - input + (32 * i), - input + (32 * i) + 16, - secret + XXH3_MIDSIZE_STARTOFFSET + (32 * (i - 4)), + input + i - 32, + input + i - 16, + secret + XXH3_MIDSIZE_STARTOFFSET + i - 160, seed); } /* last bytes */ @@ -5306,7 +6638,7 @@ XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, input + len - 16, input + len - 32, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET - 16, - 0ULL - seed); + (XXH64_hash_t)0 - seed); { XXH128_hash_t h128; h128.low64 = acc.low64 + acc.high64; @@ -5323,12 +6655,12 @@ XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, XXH_FORCE_INLINE XXH128_hash_t XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, - XXH3_f_accumulate_512 f_acc512, + XXH3_f_accumulate f_acc, XXH3_f_scrambleAcc f_scramble) { XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC; - XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, secret, secretSize, f_acc512, f_scramble); + XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, secret, secretSize, f_acc, f_scramble); /* converge into final hash */ XXH_STATIC_ASSERT(sizeof(acc) == 64); @@ -5346,47 +6678,50 @@ XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, } /* - * It's important for performance that XXH3_hashLong is not inlined. + * It's important for performance that XXH3_hashLong() is not inlined. */ -XXH_NO_INLINE XXH128_hash_t +XXH_NO_INLINE XXH_PUREF XXH128_hash_t XXH3_hashLong_128b_default(const void* XXH_RESTRICT input, size_t len, XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen) { (void)seed64; (void)secret; (void)secretLen; return XXH3_hashLong_128b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), - XXH3_accumulate_512, XXH3_scrambleAcc); + XXH3_accumulate, XXH3_scrambleAcc); } /* - * It's important for performance to pass @secretLen (when it's static) + * It's important for performance to pass @p secretLen (when it's static) * to the compiler, so that it can properly optimize the vectorized loop. + * + * When the secret size is unknown, or on GCC 12 where the mix of NO_INLINE and FORCE_INLINE + * breaks -Og, this is XXH_NO_INLINE. */ -XXH_FORCE_INLINE XXH128_hash_t +XXH3_WITH_SECRET_INLINE XXH128_hash_t XXH3_hashLong_128b_withSecret(const void* XXH_RESTRICT input, size_t len, XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen) { (void)seed64; return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, secretLen, - XXH3_accumulate_512, XXH3_scrambleAcc); + XXH3_accumulate, XXH3_scrambleAcc); } XXH_FORCE_INLINE XXH128_hash_t XXH3_hashLong_128b_withSeed_internal(const void* XXH_RESTRICT input, size_t len, XXH64_hash_t seed64, - XXH3_f_accumulate_512 f_acc512, + XXH3_f_accumulate f_acc, XXH3_f_scrambleAcc f_scramble, XXH3_f_initCustomSecret f_initSec) { if (seed64 == 0) return XXH3_hashLong_128b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), - f_acc512, f_scramble); + f_acc, f_scramble); { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE]; f_initSec(secret, seed64); return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, sizeof(secret), - f_acc512, f_scramble); + f_acc, f_scramble); } } @@ -5399,7 +6734,7 @@ XXH3_hashLong_128b_withSeed(const void* input, size_t len, { (void)secret; (void)secretLen; return XXH3_hashLong_128b_withSeed_internal(input, len, seed64, - XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret); + XXH3_accumulate, XXH3_scrambleAcc, XXH3_initCustomSecret); } typedef XXH128_hash_t (*XXH3_hashLong128_f)(const void* XXH_RESTRICT, size_t, @@ -5429,94 +6764,93 @@ XXH3_128bits_internal(const void* input, size_t len, /* === Public XXH128 API === */ -/*! @ingroup xxh3_family */ -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* input, size_t len) +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(XXH_NOESCAPE const void* input, size_t len) { return XXH3_128bits_internal(input, len, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_128b_default); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH128_hash_t -XXH3_128bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize) +XXH3_128bits_withSecret(XXH_NOESCAPE const void* input, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize) { return XXH3_128bits_internal(input, len, 0, (const xxh_u8*)secret, secretSize, XXH3_hashLong_128b_withSecret); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH128_hash_t -XXH3_128bits_withSeed(const void* input, size_t len, XXH64_hash_t seed) +XXH3_128bits_withSeed(XXH_NOESCAPE const void* input, size_t len, XXH64_hash_t seed) { return XXH3_128bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_128b_withSeed); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH128_hash_t -XXH3_128bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed) +XXH3_128bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed) { if (len <= XXH3_MIDSIZE_MAX) return XXH3_128bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL); return XXH3_hashLong_128b_withSecret(input, len, seed, secret, secretSize); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH128_hash_t -XXH128(const void* input, size_t len, XXH64_hash_t seed) +XXH128(XXH_NOESCAPE const void* input, size_t len, XXH64_hash_t seed) { return XXH3_128bits_withSeed(input, len, seed); } /* === XXH3 128-bit streaming === */ - +#ifndef XXH_NO_STREAM /* * All initialization and update functions are identical to 64-bit streaming variant. * The only difference is the finalization routine. */ -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_128bits_reset(XXH3_state_t* statePtr) +XXH3_128bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr) { return XXH3_64bits_reset(statePtr); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize) +XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize) { return XXH3_64bits_reset_withSecret(statePtr, secret, secretSize); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed) +XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed) { return XXH3_64bits_reset_withSeed(statePtr, seed); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed) +XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed) { return XXH3_64bits_reset_withSecretandSeed(statePtr, secret, secretSize, seed); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_128bits_update(XXH3_state_t* state, const void* input, size_t len) +XXH3_128bits_update(XXH_NOESCAPE XXH3_state_t* state, XXH_NOESCAPE const void* input, size_t len) { - return XXH3_update(state, (const xxh_u8*)input, len, - XXH3_accumulate_512, XXH3_scrambleAcc); + return XXH3_64bits_update(state, input, len); } -/*! @ingroup xxh3_family */ -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state) +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_t* state) { const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret; if (state->totalLen > XXH3_MIDSIZE_MAX) { @@ -5540,13 +6874,13 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state) return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen), secret, state->secretLimit + XXH_STRIPE_LEN); } - +#endif /* !XXH_NO_STREAM */ /* 128-bit utility functions */ #include /* memcmp, memcpy */ /* return : 1 is equal, 0 if different */ -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2) { /* note : XXH128_hash_t is compact, it has no padding byte */ @@ -5554,11 +6888,11 @@ XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2) } /* This prototype is compatible with stdlib's qsort(). - * return : >0 if *h128_1 > *h128_2 - * <0 if *h128_1 < *h128_2 - * =0 if *h128_1 == *h128_2 */ -/*! @ingroup xxh3_family */ -XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2) + * @return : >0 if *h128_1 > *h128_2 + * <0 if *h128_1 < *h128_2 + * =0 if *h128_1 == *h128_2 */ +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API int XXH128_cmp(XXH_NOESCAPE const void* h128_1, XXH_NOESCAPE const void* h128_2) { XXH128_hash_t const h1 = *(const XXH128_hash_t*)h128_1; XXH128_hash_t const h2 = *(const XXH128_hash_t*)h128_2; @@ -5570,9 +6904,9 @@ XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2) /*====== Canonical representation ======*/ -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API void -XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash) +XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* dst, XXH128_hash_t hash) { XXH_STATIC_ASSERT(sizeof(XXH128_canonical_t) == sizeof(XXH128_hash_t)); if (XXH_CPU_LITTLE_ENDIAN) { @@ -5583,9 +6917,9 @@ XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash) XXH_memcpy((char*)dst + sizeof(hash.high64), &hash.low64, sizeof(hash.low64)); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH128_hash_t -XXH128_hashFromCanonical(const XXH128_canonical_t* src) +XXH128_hashFromCanonical(XXH_NOESCAPE const XXH128_canonical_t* src) { XXH128_hash_t h; h.high64 = XXH_readBE64(src); @@ -5607,9 +6941,9 @@ XXH_FORCE_INLINE void XXH3_combine16(void* dst, XXH128_hash_t h128) XXH_writeLE64( (char*)dst+8, XXH_readLE64((char*)dst+8) ^ h128.high64 ); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize) +XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer, size_t secretSize, XXH_NOESCAPE const void* customSeed, size_t customSeedSize) { #if (XXH_DEBUGLEVEL >= 1) XXH_ASSERT(secretBuffer != NULL); @@ -5652,9 +6986,9 @@ XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSee return XXH_OK; } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API void -XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed) +XXH3_generateSecret_fromSeed(XXH_NOESCAPE void* secretBuffer, XXH64_hash_t seed) { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE]; XXH3_initCustomSecret(secret, seed); @@ -5667,7 +7001,7 @@ XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed) /* Pop our optimization override from above */ #if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \ && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ - && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */ + && defined(__OPTIMIZE__) && XXH_SIZE_OPT <= 0 /* respect -O0 and -Os */ # pragma GCC pop_options #endif @@ -5682,5 +7016,5 @@ XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed) #if defined (__cplusplus) -} +} /* extern "C" */ #endif diff --git a/src/dependencies/zstd-1.5.4/lib/common/zstd_common.c b/src/dependencies/zstd-1.5.6/lib/common/zstd_common.c similarity index 61% rename from src/dependencies/zstd-1.5.4/lib/common/zstd_common.c rename to src/dependencies/zstd-1.5.6/lib/common/zstd_common.c index 3208552..3f04c22 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/zstd_common.c +++ b/src/dependencies/zstd-1.5.6/lib/common/zstd_common.c @@ -14,7 +14,6 @@ * Dependencies ***************************************/ #define ZSTD_DEPS_NEED_MALLOC -#include "zstd_deps.h" /* ZSTD_malloc, ZSTD_calloc, ZSTD_free, ZSTD_memset */ #include "error_private.h" #include "zstd_internal.h" @@ -47,37 +46,3 @@ ZSTD_ErrorCode ZSTD_getErrorCode(size_t code) { return ERR_getErrorCode(code); } /*! ZSTD_getErrorString() : * provides error code string from enum */ const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString(code); } - - - -/*=************************************************************** -* Custom allocator -****************************************************************/ -void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem) -{ - if (customMem.customAlloc) - return customMem.customAlloc(customMem.opaque, size); - return ZSTD_malloc(size); -} - -void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem) -{ - if (customMem.customAlloc) { - /* calloc implemented as malloc+memset; - * not as efficient as calloc, but next best guess for custom malloc */ - void* const ptr = customMem.customAlloc(customMem.opaque, size); - ZSTD_memset(ptr, 0, size); - return ptr; - } - return ZSTD_calloc(1, size); -} - -void ZSTD_customFree(void* ptr, ZSTD_customMem customMem) -{ - if (ptr!=NULL) { - if (customMem.customFree) - customMem.customFree(customMem.opaque, ptr); - else - ZSTD_free(ptr); - } -} diff --git a/src/dependencies/zstd-1.5.4/lib/common/zstd_deps.h b/src/dependencies/zstd-1.5.6/lib/common/zstd_deps.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/common/zstd_deps.h rename to src/dependencies/zstd-1.5.6/lib/common/zstd_deps.h diff --git a/src/dependencies/zstd-1.5.4/lib/common/zstd_internal.h b/src/dependencies/zstd-1.5.6/lib/common/zstd_internal.h similarity index 96% rename from src/dependencies/zstd-1.5.4/lib/common/zstd_internal.h rename to src/dependencies/zstd-1.5.6/lib/common/zstd_internal.h index 37836dc..ecb9cfb 100644 --- a/src/dependencies/zstd-1.5.4/lib/common/zstd_internal.h +++ b/src/dependencies/zstd-1.5.6/lib/common/zstd_internal.h @@ -178,7 +178,7 @@ static void ZSTD_copy8(void* dst, const void* src) { ZSTD_memcpy(dst, src, 8); #endif } -#define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; } +#define COPY8(d,s) do { ZSTD_copy8(d,s); d+=8; s+=8; } while (0) /* Need to use memmove here since the literal buffer can now be located within the dst buffer. In circumstances where the op "catches up" to where the @@ -198,7 +198,7 @@ static void ZSTD_copy16(void* dst, const void* src) { ZSTD_memcpy(dst, copy16_buf, 16); #endif } -#define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; } +#define COPY16(d,s) do { ZSTD_copy16(d,s); d+=16; s+=16; } while (0) #define WILDCOPY_OVERLENGTH 32 #define WILDCOPY_VECLEN 16 @@ -227,7 +227,7 @@ void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e if (ovtype == ZSTD_overlap_src_before_dst && diff < WILDCOPY_VECLEN) { /* Handle short offset copies. */ do { - COPY8(op, ip) + COPY8(op, ip); } while (op < oend); } else { assert(diff >= WILDCOPY_VECLEN || diff <= -WILDCOPY_VECLEN); @@ -350,11 +350,6 @@ typedef struct { const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBuilder */ int ZSTD_seqToCodes(const seqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */ -/* custom memory allocation functions */ -void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem); -void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem); -void ZSTD_customFree(void* ptr, ZSTD_customMem customMem); - /* ZSTD_invalidateRepCodes() : * ensures next compression will not use repcodes from previous block. @@ -371,13 +366,13 @@ typedef struct { /*! ZSTD_getcBlockSize() : * Provides the size of compressed block from block header `src` */ -/* Used by: decompress, fullbench (does not get its definition from here) */ +/* Used by: decompress, fullbench */ size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr); /*! ZSTD_decodeSeqHeaders() : * decode sequence header from src */ -/* Used by: decompress, fullbench (does not get its definition from here) */ +/* Used by: zstd_decompress_block, fullbench */ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, const void* src, size_t srcSize); diff --git a/src/dependencies/zstd-1.5.4/lib/common/zstd_trace.h b/src/dependencies/zstd-1.5.6/lib/common/zstd_trace.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/common/zstd_trace.h rename to src/dependencies/zstd-1.5.6/lib/common/zstd_trace.h diff --git a/src/dependencies/zstd-1.5.4/lib/compress/clevels.h b/src/dependencies/zstd-1.5.6/lib/compress/clevels.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/compress/clevels.h rename to src/dependencies/zstd-1.5.6/lib/compress/clevels.h diff --git a/src/dependencies/zstd-1.5.4/lib/compress/fse_compress.c b/src/dependencies/zstd-1.5.6/lib/compress/fse_compress.c similarity index 98% rename from src/dependencies/zstd-1.5.4/lib/compress/fse_compress.c rename to src/dependencies/zstd-1.5.6/lib/compress/fse_compress.c index 5d37708..1ce3cf1 100644 --- a/src/dependencies/zstd-1.5.4/lib/compress/fse_compress.c +++ b/src/dependencies/zstd-1.5.6/lib/compress/fse_compress.c @@ -25,7 +25,7 @@ #include "../common/error_private.h" #define ZSTD_DEPS_NEED_MALLOC #define ZSTD_DEPS_NEED_MATH64 -#include "../common/zstd_deps.h" /* ZSTD_malloc, ZSTD_free, ZSTD_memcpy, ZSTD_memset */ +#include "../common/zstd_deps.h" /* ZSTD_memset */ #include "../common/bits.h" /* ZSTD_highbit32 */ @@ -225,8 +225,8 @@ size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog) size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog + 4 /* bitCount initialized at 4 */ + 2 /* first two symbols may use one additional bit each */) / 8) - + 1 /* round up to whole nb bytes */ - + 2 /* additional two bytes for bitstream flush */; + + 1 /* round up to whole nb bytes */ + + 2 /* additional two bytes for bitstream flush */; return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */ } @@ -255,7 +255,7 @@ FSE_writeNCount_generic (void* header, size_t headerBufferSize, /* Init */ remaining = tableSize+1; /* +1 for extra accuracy */ threshold = tableSize; - nbBits = tableLog+1; + nbBits = (int)tableLog+1; while ((symbol < alphabetSize) && (remaining>1)) { /* stops at 1 */ if (previousIs0) { @@ -274,7 +274,7 @@ FSE_writeNCount_generic (void* header, size_t headerBufferSize, } while (symbol >= start+3) { start+=3; - bitStream += 3 << bitCount; + bitStream += 3U << bitCount; bitCount += 2; } bitStream += (symbol-start) << bitCount; @@ -294,7 +294,7 @@ FSE_writeNCount_generic (void* header, size_t headerBufferSize, count++; /* +1 for extra accuracy */ if (count>=threshold) count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */ - bitStream += count << bitCount; + bitStream += (U32)count << bitCount; bitCount += nbBits; bitCount -= (count>8); out+= (bitCount+7) /8; - return (out-ostart); + assert(out >= ostart); + return (size_t)(out-ostart); } diff --git a/src/dependencies/zstd-1.5.4/lib/compress/hist.c b/src/dependencies/zstd-1.5.6/lib/compress/hist.c similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/compress/hist.c rename to src/dependencies/zstd-1.5.6/lib/compress/hist.c diff --git a/src/dependencies/zstd-1.5.4/lib/compress/hist.h b/src/dependencies/zstd-1.5.6/lib/compress/hist.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/compress/hist.h rename to src/dependencies/zstd-1.5.6/lib/compress/hist.h diff --git a/src/dependencies/zstd-1.5.4/lib/compress/huf_compress.c b/src/dependencies/zstd-1.5.6/lib/compress/huf_compress.c similarity index 96% rename from src/dependencies/zstd-1.5.4/lib/compress/huf_compress.c rename to src/dependencies/zstd-1.5.6/lib/compress/huf_compress.c index 2987187..ea00072 100644 --- a/src/dependencies/zstd-1.5.4/lib/compress/huf_compress.c +++ b/src/dependencies/zstd-1.5.6/lib/compress/huf_compress.c @@ -220,6 +220,25 @@ static void HUF_setValue(HUF_CElt* elt, size_t value) } } +HUF_CTableHeader HUF_readCTableHeader(HUF_CElt const* ctable) +{ + HUF_CTableHeader header; + ZSTD_memcpy(&header, ctable, sizeof(header)); + return header; +} + +static void HUF_writeCTableHeader(HUF_CElt* ctable, U32 tableLog, U32 maxSymbolValue) +{ + HUF_CTableHeader header; + HUF_STATIC_ASSERT(sizeof(ctable[0]) == sizeof(header)); + ZSTD_memset(&header, 0, sizeof(header)); + assert(tableLog < 256); + header.tableLog = (BYTE)tableLog; + assert(maxSymbolValue < 256); + header.maxSymbolValue = (BYTE)maxSymbolValue; + ZSTD_memcpy(ctable, &header, sizeof(header)); +} + typedef struct { HUF_CompressWeightsWksp wksp; BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; /* precomputed conversion table */ @@ -237,6 +256,9 @@ size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, HUF_STATIC_ASSERT(HUF_CTABLE_WORKSPACE_SIZE >= sizeof(HUF_WriteCTableWksp)); + assert(HUF_readCTableHeader(CTable).maxSymbolValue == maxSymbolValue); + assert(HUF_readCTableHeader(CTable).tableLog == huffLog); + /* check conditions */ if (workspaceSize < sizeof(HUF_WriteCTableWksp)) return ERROR(GENERIC); if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge); @@ -283,7 +305,9 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); if (nbSymbols > *maxSymbolValuePtr+1) return ERROR(maxSymbolValue_tooSmall); - CTable[0] = tableLog; + *maxSymbolValuePtr = nbSymbols - 1; + + HUF_writeCTableHeader(CTable, tableLog, *maxSymbolValuePtr); /* Prepare base value per rank */ { U32 n, nextRankStart = 0; @@ -315,7 +339,6 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void { U32 n; for (n=0; n HUF_readCTableHeader(CTable).maxSymbolValue) + return 0; return (U32)HUF_getNbBits(ct[symbolValue]); } @@ -723,7 +748,8 @@ static void HUF_buildCTableFromTree(HUF_CElt* CTable, nodeElt const* huffNode, i HUF_setNbBits(ct + huffNode[n].byte, huffNode[n].nbBits); /* push nbBits per symbol, symbol order */ for (n=0; n 11) @@ -1255,7 +1288,7 @@ unsigned HUF_optimalTableLog( { BYTE* dst = (BYTE*)workSpace + sizeof(HUF_WriteCTableWksp); size_t dstSize = wkspSize - sizeof(HUF_WriteCTableWksp); - size_t maxBits, hSize, newSize; + size_t hSize, newSize; const unsigned symbolCardinality = HUF_cardinality(count, maxSymbolValue); const unsigned minTableLog = HUF_minTableLog(symbolCardinality); size_t optSize = ((size_t) ~0) - 1; @@ -1266,12 +1299,14 @@ unsigned HUF_optimalTableLog( /* Search until size increases */ for (optLogGuess = minTableLog; optLogGuess <= maxTableLog; optLogGuess++) { DEBUGLOG(7, "checking for huffLog=%u", optLogGuess); - maxBits = HUF_buildCTable_wksp(table, count, maxSymbolValue, optLogGuess, workSpace, wkspSize); - if (ERR_isError(maxBits)) continue; - if (maxBits < optLogGuess && optLogGuess > minTableLog) break; + { size_t maxBits = HUF_buildCTable_wksp(table, count, maxSymbolValue, optLogGuess, workSpace, wkspSize); + if (ERR_isError(maxBits)) continue; - hSize = HUF_writeCTable_wksp(dst, dstSize, table, maxSymbolValue, (U32)maxBits, workSpace, wkspSize); + if (maxBits < optLogGuess && optLogGuess > minTableLog) break; + + hSize = HUF_writeCTable_wksp(dst, dstSize, table, maxSymbolValue, (U32)maxBits, workSpace, wkspSize); + } if (ERR_isError(hSize)) continue; @@ -1372,12 +1407,6 @@ HUF_compress_internal (void* dst, size_t dstSize, huffLog = (U32)maxBits; DEBUGLOG(6, "bit distribution completed (%zu symbols)", showCTableBits(table->CTable + 1, maxSymbolValue+1)); } - /* Zero unused symbols in CTable, so we can check it for validity */ - { - size_t const ctableSize = HUF_CTABLE_SIZE_ST(maxSymbolValue); - size_t const unusedSize = sizeof(table->CTable) - ctableSize * sizeof(HUF_CElt); - ZSTD_memset(table->CTable + ctableSize, 0, unusedSize); - } /* Write table description header */ { CHECK_V_F(hSize, HUF_writeCTable_wksp(op, dstSize, table->CTable, maxSymbolValue, huffLog, @@ -1420,7 +1449,7 @@ size_t HUF_compress1X_repeat (void* dst, size_t dstSize, /* HUF_compress4X_repeat(): * compress input using 4 streams. * consider skipping quickly - * re-use an existing huffman compression table */ + * reuse an existing huffman compression table */ size_t HUF_compress4X_repeat (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_compress.c b/src/dependencies/zstd-1.5.6/lib/compress/zstd_compress.c similarity index 93% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_compress.c rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_compress.c index b55f684..9284e2a 100644 --- a/src/dependencies/zstd-1.5.4/lib/compress/zstd_compress.c +++ b/src/dependencies/zstd-1.5.6/lib/compress/zstd_compress.c @@ -11,6 +11,7 @@ /*-************************************* * Dependencies ***************************************/ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */ #include "../common/zstd_deps.h" /* INT_MAX, ZSTD_memset, ZSTD_memcpy */ #include "../common/mem.h" #include "hist.h" /* HIST_countFast_wksp */ @@ -26,7 +27,7 @@ #include "zstd_opt.h" #include "zstd_ldm.h" #include "zstd_compress_superblock.h" -#include "../common/bits.h" /* ZSTD_highbit32 */ +#include "../common/bits.h" /* ZSTD_highbit32, ZSTD_rotateRight_U64 */ /* *************************************************************** * Tuning parameters @@ -177,6 +178,7 @@ static void ZSTD_freeCCtxContent(ZSTD_CCtx* cctx) size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx) { + DEBUGLOG(3, "ZSTD_freeCCtx (address: %p)", (void*)cctx); if (cctx==NULL) return 0; /* support free on NULL */ RETURN_ERROR_IF(cctx->staticSize, memory_allocation, "not compatible with static CCtx"); @@ -648,10 +650,11 @@ static size_t ZSTD_cParam_clampBounds(ZSTD_cParameter cParam, int* value) return 0; } -#define BOUNDCHECK(cParam, val) { \ - RETURN_ERROR_IF(!ZSTD_cParam_withinBounds(cParam,val), \ - parameter_outOfBound, "Param out of bounds"); \ -} +#define BOUNDCHECK(cParam, val) \ + do { \ + RETURN_ERROR_IF(!ZSTD_cParam_withinBounds(cParam,val), \ + parameter_outOfBound, "Param out of bounds"); \ + } while (0) static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param) @@ -867,7 +870,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, #else FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), ""); CCtxParams->nbWorkers = value; - return CCtxParams->nbWorkers; + return (size_t)(CCtxParams->nbWorkers); #endif case ZSTD_c_jobSize : @@ -891,7 +894,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, #else FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value), ""); CCtxParams->overlapLog = value; - return CCtxParams->overlapLog; + return (size_t)CCtxParams->overlapLog; #endif case ZSTD_c_rsyncable : @@ -901,7 +904,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, #else FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value), ""); CCtxParams->rsyncable = value; - return CCtxParams->rsyncable; + return (size_t)CCtxParams->rsyncable; #endif case ZSTD_c_enableDedicatedDictSearch : @@ -938,8 +941,10 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, return CCtxParams->ldmParams.hashRateLog; case ZSTD_c_targetCBlockSize : - if (value!=0) /* 0 ==> default */ + if (value!=0) { /* 0 ==> default */ + value = MAX(value, ZSTD_TARGETCBLOCKSIZE_MIN); BOUNDCHECK(ZSTD_c_targetCBlockSize, value); + } CCtxParams->targetCBlockSize = (U32)value; return CCtxParams->targetCBlockSize; @@ -967,7 +972,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, case ZSTD_c_validateSequences: BOUNDCHECK(ZSTD_c_validateSequences, value); CCtxParams->validateSequences = value; - return CCtxParams->validateSequences; + return (size_t)CCtxParams->validateSequences; case ZSTD_c_useBlockSplitter: BOUNDCHECK(ZSTD_c_useBlockSplitter, value); @@ -982,7 +987,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, case ZSTD_c_deterministicRefPrefix: BOUNDCHECK(ZSTD_c_deterministicRefPrefix, value); CCtxParams->deterministicRefPrefix = !!value; - return CCtxParams->deterministicRefPrefix; + return (size_t)CCtxParams->deterministicRefPrefix; case ZSTD_c_prefetchCDictTables: BOUNDCHECK(ZSTD_c_prefetchCDictTables, value); @@ -992,7 +997,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, case ZSTD_c_enableSeqProducerFallback: BOUNDCHECK(ZSTD_c_enableSeqProducerFallback, value); CCtxParams->enableMatchFinderFallback = value; - return CCtxParams->enableMatchFinderFallback; + return (size_t)CCtxParams->enableMatchFinderFallback; case ZSTD_c_maxBlockSize: if (value!=0) /* 0 ==> default */ @@ -1177,16 +1182,39 @@ size_t ZSTD_CCtx_setParametersUsingCCtxParams( size_t ZSTD_CCtx_setCParams(ZSTD_CCtx* cctx, ZSTD_compressionParameters cparams) { + ZSTD_STATIC_ASSERT(sizeof(cparams) == 7 * 4 /* all params are listed below */); DEBUGLOG(4, "ZSTD_CCtx_setCParams"); - assert(cctx != NULL); - if (cctx->streamStage != zcss_init) { - /* All parameters in @cparams are allowed to be updated during MT compression. - * This must be signaled, so that MT compression picks up the changes */ - cctx->cParamsChanged = 1; - } - /* only update if parameters are valid */ + /* only update if all parameters are valid */ FORWARD_IF_ERROR(ZSTD_checkCParams(cparams), ""); - cctx->requestedParams.cParams = cparams; + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, cparams.windowLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_chainLog, cparams.chainLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_hashLog, cparams.hashLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_searchLog, cparams.searchLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, cparams.minMatch), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetLength, cparams.targetLength), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, cparams.strategy), ""); + return 0; +} + +size_t ZSTD_CCtx_setFParams(ZSTD_CCtx* cctx, ZSTD_frameParameters fparams) +{ + ZSTD_STATIC_ASSERT(sizeof(fparams) == 3 * 4 /* all params are listed below */); + DEBUGLOG(4, "ZSTD_CCtx_setFParams"); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_contentSizeFlag, fparams.contentSizeFlag != 0), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, fparams.checksumFlag != 0), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_dictIDFlag, fparams.noDictIDFlag == 0), ""); + return 0; +} + +size_t ZSTD_CCtx_setParams(ZSTD_CCtx* cctx, ZSTD_parameters params) +{ + DEBUGLOG(4, "ZSTD_CCtx_setParams"); + /* First check cParams, because we want to update all or none. */ + FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), ""); + /* Next set fParams, because this could fail if the cctx isn't in init stage. */ + FORWARD_IF_ERROR(ZSTD_CCtx_setFParams(cctx, params.fParams), ""); + /* Finally set cParams, which should succeed. */ + FORWARD_IF_ERROR(ZSTD_CCtx_setCParams(cctx, params.cParams), ""); return 0; } @@ -1208,9 +1236,9 @@ static void ZSTD_dedicatedDictSearch_revertCParams( ZSTD_compressionParameters* cParams); /** - * Initializes the local dict using the requested parameters. - * NOTE: This does not use the pledged src size, because it may be used for more - * than one compression. + * Initializes the local dictionary using requested parameters. + * NOTE: Initialization does not employ the pledged src size, + * because the dictionary may be used for multiple compressions. */ static size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx) { @@ -1223,8 +1251,8 @@ static size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx) return 0; } if (dl->cdict != NULL) { - assert(cctx->cdict == dl->cdict); /* Local dictionary already initialized. */ + assert(cctx->cdict == dl->cdict); return 0; } assert(dl->dictSize > 0); @@ -1244,26 +1272,30 @@ static size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx) } size_t ZSTD_CCtx_loadDictionary_advanced( - ZSTD_CCtx* cctx, const void* dict, size_t dictSize, - ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType) + ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType) { - RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, - "Can't load a dictionary when ctx is not in init stage."); DEBUGLOG(4, "ZSTD_CCtx_loadDictionary_advanced (size: %u)", (U32)dictSize); - ZSTD_clearAllDicts(cctx); /* in case one already exists */ - if (dict == NULL || dictSize == 0) /* no dictionary mode */ + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't load a dictionary when cctx is not in init stage."); + ZSTD_clearAllDicts(cctx); /* erase any previously set dictionary */ + if (dict == NULL || dictSize == 0) /* no dictionary */ return 0; if (dictLoadMethod == ZSTD_dlm_byRef) { cctx->localDict.dict = dict; } else { + /* copy dictionary content inside CCtx to own its lifetime */ void* dictBuffer; RETURN_ERROR_IF(cctx->staticSize, memory_allocation, - "no malloc for static CCtx"); + "static CCtx can't allocate for an internal copy of dictionary"); dictBuffer = ZSTD_customMalloc(dictSize, cctx->customMem); - RETURN_ERROR_IF(!dictBuffer, memory_allocation, "NULL pointer!"); + RETURN_ERROR_IF(dictBuffer==NULL, memory_allocation, + "allocation failed for dictionary content"); ZSTD_memcpy(dictBuffer, dict, dictSize); - cctx->localDict.dictBuffer = dictBuffer; - cctx->localDict.dict = dictBuffer; + cctx->localDict.dictBuffer = dictBuffer; /* owned ptr to free */ + cctx->localDict.dict = dictBuffer; /* read-only reference */ } cctx->localDict.dictSize = dictSize; cctx->localDict.dictContentType = dictContentType; @@ -1333,9 +1365,8 @@ size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset) if ( (reset == ZSTD_reset_parameters) || (reset == ZSTD_reset_session_and_parameters) ) { RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, - "Can't reset parameters only when not in init stage."); + "Reset parameters is only possible during init stage."); ZSTD_clearAllDicts(cctx); - ZSTD_memset(&cctx->externalMatchCtx, 0, sizeof(cctx->externalMatchCtx)); return ZSTD_CCtxParams_reset(&cctx->requestedParams); } return 0; @@ -1363,11 +1394,12 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams) static ZSTD_compressionParameters ZSTD_clampCParams(ZSTD_compressionParameters cParams) { -# define CLAMP_TYPE(cParam, val, type) { \ - ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam); \ - if ((int)valbounds.upperBound) val=(type)bounds.upperBound; \ - } +# define CLAMP_TYPE(cParam, val, type) \ + do { \ + ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam); \ + if ((int)valbounds.upperBound) val=(type)bounds.upperBound; \ + } while (0) # define CLAMP(cParam, val) CLAMP_TYPE(cParam, val, unsigned) CLAMP(ZSTD_c_windowLog, cParams.windowLog); CLAMP(ZSTD_c_chainLog, cParams.chainLog); @@ -1439,6 +1471,48 @@ ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar, const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1); assert(ZSTD_checkCParams(cPar)==0); + /* Cascade the selected strategy down to the next-highest one built into + * this binary. */ +#ifdef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_btultra2) { + cPar.strategy = ZSTD_btultra; + } + if (cPar.strategy == ZSTD_btultra) { + cPar.strategy = ZSTD_btopt; + } +#endif +#ifdef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_btopt) { + cPar.strategy = ZSTD_btlazy2; + } +#endif +#ifdef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_btlazy2) { + cPar.strategy = ZSTD_lazy2; + } +#endif +#ifdef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_lazy2) { + cPar.strategy = ZSTD_lazy; + } +#endif +#ifdef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_lazy) { + cPar.strategy = ZSTD_greedy; + } +#endif +#ifdef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_greedy) { + cPar.strategy = ZSTD_dfast; + } +#endif +#ifdef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_dfast) { + cPar.strategy = ZSTD_fast; + cPar.targetLength = 0; + } +#endif + switch (mode) { case ZSTD_cpm_unknown: case ZSTD_cpm_noAttachDict: @@ -1589,10 +1663,10 @@ ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams, + ZSTD_cwksp_aligned_alloc_size((MaxLL+1) * sizeof(U32)) + ZSTD_cwksp_aligned_alloc_size((MaxOff+1) * sizeof(U32)) + ZSTD_cwksp_aligned_alloc_size((1<strategy, useRowMatchFinder) - ? ZSTD_cwksp_aligned_alloc_size(hSize*sizeof(U16)) + ? ZSTD_cwksp_aligned_alloc_size(hSize) : 0; size_t const optSpace = (forCCtx && (cParams->strategy >= ZSTD_btopt)) ? optPotentialSpace @@ -1679,7 +1753,7 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params) * be needed. However, we still allocate two 0-sized buffers, which can * take space under ASAN. */ return ZSTD_estimateCCtxSize_usingCCtxParams_internal( - &cParams, ¶ms->ldmParams, 1, useRowMatchFinder, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN, params->useSequenceProducer, params->maxBlockSize); + &cParams, ¶ms->ldmParams, 1, useRowMatchFinder, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN, ZSTD_hasExtSeqProd(params), params->maxBlockSize); } size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams) @@ -1740,7 +1814,7 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params) return ZSTD_estimateCCtxSize_usingCCtxParams_internal( &cParams, ¶ms->ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize, - ZSTD_CONTENTSIZE_UNKNOWN, params->useSequenceProducer, params->maxBlockSize); + ZSTD_CONTENTSIZE_UNKNOWN, ZSTD_hasExtSeqProd(params), params->maxBlockSize); } } @@ -1883,6 +1957,19 @@ typedef enum { ZSTD_resetTarget_CCtx } ZSTD_resetTarget_e; +/* Mixes bits in a 64 bits in a value, based on XXH3_rrmxmx */ +static U64 ZSTD_bitmix(U64 val, U64 len) { + val ^= ZSTD_rotateRight_U64(val, 49) ^ ZSTD_rotateRight_U64(val, 24); + val *= 0x9FB21C651E98DF25ULL; + val ^= (val >> 35) + len ; + val *= 0x9FB21C651E98DF25ULL; + return val ^ (val >> 28); +} + +/* Mixes in the hashSalt and hashSaltEntropy to create a new hashSalt */ +static void ZSTD_advanceHashSalt(ZSTD_matchState_t* ms) { + ms->hashSalt = ZSTD_bitmix(ms->hashSalt, 8) ^ ZSTD_bitmix((U64) ms->hashSaltEntropy, 4); +} static size_t ZSTD_reset_matchState(ZSTD_matchState_t* ms, @@ -1910,6 +1997,7 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms, } ms->hashLog3 = hashLog3; + ms->lazySkipping = 0; ZSTD_invalidateMatchState(ms); @@ -1931,6 +2019,27 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms, ZSTD_cwksp_clean_tables(ws); } + if (ZSTD_rowMatchFinderUsed(cParams->strategy, useRowMatchFinder)) { + /* Row match finder needs an additional table of hashes ("tags") */ + size_t const tagTableSize = hSize; + /* We want to generate a new salt in case we reset a Cctx, but we always want to use + * 0 when we reset a Cdict */ + if(forWho == ZSTD_resetTarget_CCtx) { + ms->tagTable = (BYTE*) ZSTD_cwksp_reserve_aligned_init_once(ws, tagTableSize); + ZSTD_advanceHashSalt(ms); + } else { + /* When we are not salting we want to always memset the memory */ + ms->tagTable = (BYTE*) ZSTD_cwksp_reserve_aligned(ws, tagTableSize); + ZSTD_memset(ms->tagTable, 0, tagTableSize); + ms->hashSalt = 0; + } + { /* Switch to 32-entry rows if searchLog is 5 (or more) */ + U32 const rowLog = BOUNDED(4, cParams->searchLog, 6); + assert(cParams->hashLog >= rowLog); + ms->rowHashLog = cParams->hashLog - rowLog; + } + } + /* opt parser space */ if ((forWho == ZSTD_resetTarget_CCtx) && (cParams->strategy >= ZSTD_btopt)) { DEBUGLOG(4, "reserving optimal parser space"); @@ -1938,21 +2047,8 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms, ms->opt.litLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxLL+1) * sizeof(unsigned)); ms->opt.matchLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxML+1) * sizeof(unsigned)); ms->opt.offCodeFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxOff+1) * sizeof(unsigned)); - ms->opt.matchTable = (ZSTD_match_t*)ZSTD_cwksp_reserve_aligned(ws, (ZSTD_OPT_NUM+1) * sizeof(ZSTD_match_t)); - ms->opt.priceTable = (ZSTD_optimal_t*)ZSTD_cwksp_reserve_aligned(ws, (ZSTD_OPT_NUM+1) * sizeof(ZSTD_optimal_t)); - } - - if (ZSTD_rowMatchFinderUsed(cParams->strategy, useRowMatchFinder)) { - { /* Row match finder needs an additional table of hashes ("tags") */ - size_t const tagTableSize = hSize*sizeof(U16); - ms->tagTable = (U16*)ZSTD_cwksp_reserve_aligned(ws, tagTableSize); - if (ms->tagTable) ZSTD_memset(ms->tagTable, 0, tagTableSize); - } - { /* Switch to 32-entry rows if searchLog is 5 (or more) */ - U32 const rowLog = BOUNDED(4, cParams->searchLog, 6); - assert(cParams->hashLog >= rowLog); - ms->rowHashLog = cParams->hashLog - rowLog; - } + ms->opt.matchTable = (ZSTD_match_t*)ZSTD_cwksp_reserve_aligned(ws, ZSTD_OPT_SIZE * sizeof(ZSTD_match_t)); + ms->opt.priceTable = (ZSTD_optimal_t*)ZSTD_cwksp_reserve_aligned(ws, ZSTD_OPT_SIZE * sizeof(ZSTD_optimal_t)); } ms->cParams = *cParams; @@ -2024,7 +2120,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, { size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params->cParams.windowLog), pledgedSrcSize)); size_t const blockSize = MIN(params->maxBlockSize, windowSize); - size_t const maxNbSeq = ZSTD_maxNbSeq(blockSize, params->cParams.minMatch, params->useSequenceProducer); + size_t const maxNbSeq = ZSTD_maxNbSeq(blockSize, params->cParams.minMatch, ZSTD_hasExtSeqProd(params)); size_t const buffOutSize = (zbuff == ZSTDb_buffered && params->outBufferMode == ZSTD_bm_buffered) ? ZSTD_compressBound(blockSize) + 1 : 0; @@ -2041,8 +2137,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, size_t const neededSpace = ZSTD_estimateCCtxSize_usingCCtxParams_internal( ¶ms->cParams, ¶ms->ldmParams, zc->staticSize != 0, params->useRowMatchFinder, - buffInSize, buffOutSize, pledgedSrcSize, params->useSequenceProducer, params->maxBlockSize); - int resizeWorkspace; + buffInSize, buffOutSize, pledgedSrcSize, ZSTD_hasExtSeqProd(params), params->maxBlockSize); FORWARD_IF_ERROR(neededSpace, "cctx size estimate failed!"); @@ -2051,7 +2146,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, { /* Check if workspace is large enough, alloc a new one if needed */ int const workspaceTooSmall = ZSTD_cwksp_sizeof(ws) < neededSpace; int const workspaceWasteful = ZSTD_cwksp_check_wasteful(ws, neededSpace); - resizeWorkspace = workspaceTooSmall || workspaceWasteful; + int resizeWorkspace = workspaceTooSmall || workspaceWasteful; DEBUGLOG(4, "Need %zu B workspace", neededSpace); DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize); @@ -2101,13 +2196,46 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, ZSTD_reset_compressedBlockState(zc->blockState.prevCBlock); + FORWARD_IF_ERROR(ZSTD_reset_matchState( + &zc->blockState.matchState, + ws, + ¶ms->cParams, + params->useRowMatchFinder, + crp, + needsIndexReset, + ZSTD_resetTarget_CCtx), ""); + + zc->seqStore.sequencesStart = (seqDef*)ZSTD_cwksp_reserve_aligned(ws, maxNbSeq * sizeof(seqDef)); + + /* ldm hash table */ + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { + /* TODO: avoid memset? */ + size_t const ldmHSize = ((size_t)1) << params->ldmParams.hashLog; + zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned(ws, ldmHSize * sizeof(ldmEntry_t)); + ZSTD_memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t)); + zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned(ws, maxNbLdmSeq * sizeof(rawSeq)); + zc->maxNbLdmSequences = maxNbLdmSeq; + + ZSTD_window_init(&zc->ldmState.window); + zc->ldmState.loadedDictEnd = 0; + } + + /* reserve space for block-level external sequences */ + if (ZSTD_hasExtSeqProd(params)) { + size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize); + zc->extSeqBufCapacity = maxNbExternalSeq; + zc->extSeqBuf = + (ZSTD_Sequence*)ZSTD_cwksp_reserve_aligned(ws, maxNbExternalSeq * sizeof(ZSTD_Sequence)); + } + + /* buffers */ + /* ZSTD_wildcopy() is used to copy into the literals buffer, * so we have to oversize the buffer by WILDCOPY_OVERLENGTH bytes. */ zc->seqStore.litStart = ZSTD_cwksp_reserve_buffer(ws, blockSize + WILDCOPY_OVERLENGTH); zc->seqStore.maxNbLit = blockSize; - /* buffers */ zc->bufferedPolicy = zbuff; zc->inBuffSize = buffInSize; zc->inBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffInSize); @@ -2130,40 +2258,9 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, zc->seqStore.llCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE)); zc->seqStore.mlCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE)); zc->seqStore.ofCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE)); - zc->seqStore.sequencesStart = (seqDef*)ZSTD_cwksp_reserve_aligned(ws, maxNbSeq * sizeof(seqDef)); - - FORWARD_IF_ERROR(ZSTD_reset_matchState( - &zc->blockState.matchState, - ws, - ¶ms->cParams, - params->useRowMatchFinder, - crp, - needsIndexReset, - ZSTD_resetTarget_CCtx), ""); - - /* ldm hash table */ - if (params->ldmParams.enableLdm == ZSTD_ps_enable) { - /* TODO: avoid memset? */ - size_t const ldmHSize = ((size_t)1) << params->ldmParams.hashLog; - zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned(ws, ldmHSize * sizeof(ldmEntry_t)); - ZSTD_memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t)); - zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned(ws, maxNbLdmSeq * sizeof(rawSeq)); - zc->maxNbLdmSequences = maxNbLdmSeq; - - ZSTD_window_init(&zc->ldmState.window); - zc->ldmState.loadedDictEnd = 0; - } - - /* reserve space for block-level external sequences */ - if (params->useSequenceProducer) { - size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize); - zc->externalMatchCtx.seqBufferCapacity = maxNbExternalSeq; - zc->externalMatchCtx.seqBuffer = - (ZSTD_Sequence*)ZSTD_cwksp_reserve_aligned(ws, maxNbExternalSeq * sizeof(ZSTD_Sequence)); - } DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws)); - assert(ZSTD_cwksp_estimated_space_within_bounds(ws, neededSpace, resizeWorkspace)); + assert(ZSTD_cwksp_estimated_space_within_bounds(ws, neededSpace)); zc->initialized = 1; @@ -2338,10 +2435,11 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, } /* copy tag table */ if (ZSTD_rowMatchFinderUsed(cdict_cParams->strategy, cdict->useRowMatchFinder)) { - size_t const tagTableSize = hSize*sizeof(U16); + size_t const tagTableSize = hSize; ZSTD_memcpy(cctx->blockState.matchState.tagTable, - cdict->matchState.tagTable, - tagTableSize); + cdict->matchState.tagTable, + tagTableSize); + cctx->blockState.matchState.hashSalt = cdict->matchState.hashSalt; } } @@ -2511,7 +2609,7 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa assert(size < (1U<<31)); /* can be casted to int */ #if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) - /* To validate that the table re-use logic is sound, and that we don't + /* To validate that the table reuse logic is sound, and that we don't * access table space that we haven't cleaned, we re-"poison" the table * space every time we mark it dirty. * @@ -2939,40 +3037,43 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramS static const ZSTD_blockCompressor blockCompressor[4][ZSTD_STRATEGY_MAX+1] = { { ZSTD_compressBlock_fast /* default for 0 */, ZSTD_compressBlock_fast, - ZSTD_compressBlock_doubleFast, - ZSTD_compressBlock_greedy, - ZSTD_compressBlock_lazy, - ZSTD_compressBlock_lazy2, - ZSTD_compressBlock_btlazy2, - ZSTD_compressBlock_btopt, - ZSTD_compressBlock_btultra, - ZSTD_compressBlock_btultra2 }, + ZSTD_COMPRESSBLOCK_DOUBLEFAST, + ZSTD_COMPRESSBLOCK_GREEDY, + ZSTD_COMPRESSBLOCK_LAZY, + ZSTD_COMPRESSBLOCK_LAZY2, + ZSTD_COMPRESSBLOCK_BTLAZY2, + ZSTD_COMPRESSBLOCK_BTOPT, + ZSTD_COMPRESSBLOCK_BTULTRA, + ZSTD_COMPRESSBLOCK_BTULTRA2 + }, { ZSTD_compressBlock_fast_extDict /* default for 0 */, ZSTD_compressBlock_fast_extDict, - ZSTD_compressBlock_doubleFast_extDict, - ZSTD_compressBlock_greedy_extDict, - ZSTD_compressBlock_lazy_extDict, - ZSTD_compressBlock_lazy2_extDict, - ZSTD_compressBlock_btlazy2_extDict, - ZSTD_compressBlock_btopt_extDict, - ZSTD_compressBlock_btultra_extDict, - ZSTD_compressBlock_btultra_extDict }, + ZSTD_COMPRESSBLOCK_DOUBLEFAST_EXTDICT, + ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT, + ZSTD_COMPRESSBLOCK_LAZY_EXTDICT, + ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT, + ZSTD_COMPRESSBLOCK_BTLAZY2_EXTDICT, + ZSTD_COMPRESSBLOCK_BTOPT_EXTDICT, + ZSTD_COMPRESSBLOCK_BTULTRA_EXTDICT, + ZSTD_COMPRESSBLOCK_BTULTRA_EXTDICT + }, { ZSTD_compressBlock_fast_dictMatchState /* default for 0 */, ZSTD_compressBlock_fast_dictMatchState, - ZSTD_compressBlock_doubleFast_dictMatchState, - ZSTD_compressBlock_greedy_dictMatchState, - ZSTD_compressBlock_lazy_dictMatchState, - ZSTD_compressBlock_lazy2_dictMatchState, - ZSTD_compressBlock_btlazy2_dictMatchState, - ZSTD_compressBlock_btopt_dictMatchState, - ZSTD_compressBlock_btultra_dictMatchState, - ZSTD_compressBlock_btultra_dictMatchState }, + ZSTD_COMPRESSBLOCK_DOUBLEFAST_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_BTLAZY2_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_BTOPT_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_BTULTRA_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_BTULTRA_DICTMATCHSTATE + }, { NULL /* default for 0 */, NULL, NULL, - ZSTD_compressBlock_greedy_dedicatedDictSearch, - ZSTD_compressBlock_lazy_dedicatedDictSearch, - ZSTD_compressBlock_lazy2_dedicatedDictSearch, + ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH, + ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH, + ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH, NULL, NULL, NULL, @@ -2985,18 +3086,26 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramS DEBUGLOG(4, "Selected block compressor: dictMode=%d strat=%d rowMatchfinder=%d", (int)dictMode, (int)strat, (int)useRowMatchFinder); if (ZSTD_rowMatchFinderUsed(strat, useRowMatchFinder)) { static const ZSTD_blockCompressor rowBasedBlockCompressors[4][3] = { - { ZSTD_compressBlock_greedy_row, - ZSTD_compressBlock_lazy_row, - ZSTD_compressBlock_lazy2_row }, - { ZSTD_compressBlock_greedy_extDict_row, - ZSTD_compressBlock_lazy_extDict_row, - ZSTD_compressBlock_lazy2_extDict_row }, - { ZSTD_compressBlock_greedy_dictMatchState_row, - ZSTD_compressBlock_lazy_dictMatchState_row, - ZSTD_compressBlock_lazy2_dictMatchState_row }, - { ZSTD_compressBlock_greedy_dedicatedDictSearch_row, - ZSTD_compressBlock_lazy_dedicatedDictSearch_row, - ZSTD_compressBlock_lazy2_dedicatedDictSearch_row } + { + ZSTD_COMPRESSBLOCK_GREEDY_ROW, + ZSTD_COMPRESSBLOCK_LAZY_ROW, + ZSTD_COMPRESSBLOCK_LAZY2_ROW + }, + { + ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT_ROW, + ZSTD_COMPRESSBLOCK_LAZY_EXTDICT_ROW, + ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT_ROW + }, + { + ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE_ROW, + ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE_ROW, + ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE_ROW + }, + { + ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH_ROW, + ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH_ROW, + ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW + } }; DEBUGLOG(4, "Selecting a row-based matchfinder"); assert(useRowMatchFinder != ZSTD_ps_auto); @@ -3139,7 +3248,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) /* External matchfinder + LDM is technically possible, just not implemented yet. * We need to revisit soon and implement it. */ RETURN_ERROR_IF( - zc->appliedParams.useSequenceProducer, + ZSTD_hasExtSeqProd(&zc->appliedParams), parameter_combination_unsupported, "Long-distance matching with external sequence producer enabled is not currently supported." ); @@ -3158,7 +3267,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) /* External matchfinder + LDM is technically possible, just not implemented yet. * We need to revisit soon and implement it. */ RETURN_ERROR_IF( - zc->appliedParams.useSequenceProducer, + ZSTD_hasExtSeqProd(&zc->appliedParams), parameter_combination_unsupported, "Long-distance matching with external sequence producer enabled is not currently supported." ); @@ -3177,18 +3286,18 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) zc->appliedParams.useRowMatchFinder, src, srcSize); assert(ldmSeqStore.pos == ldmSeqStore.size); - } else if (zc->appliedParams.useSequenceProducer) { + } else if (ZSTD_hasExtSeqProd(&zc->appliedParams)) { assert( - zc->externalMatchCtx.seqBufferCapacity >= ZSTD_sequenceBound(srcSize) + zc->extSeqBufCapacity >= ZSTD_sequenceBound(srcSize) ); - assert(zc->externalMatchCtx.mFinder != NULL); + assert(zc->appliedParams.extSeqProdFunc != NULL); { U32 const windowSize = (U32)1 << zc->appliedParams.cParams.windowLog; - size_t const nbExternalSeqs = (zc->externalMatchCtx.mFinder)( - zc->externalMatchCtx.mState, - zc->externalMatchCtx.seqBuffer, - zc->externalMatchCtx.seqBufferCapacity, + size_t const nbExternalSeqs = (zc->appliedParams.extSeqProdFunc)( + zc->appliedParams.extSeqProdState, + zc->extSeqBuf, + zc->extSeqBufCapacity, src, srcSize, NULL, 0, /* dict and dictSize, currently not supported */ zc->appliedParams.compressionLevel, @@ -3196,21 +3305,21 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) ); size_t const nbPostProcessedSeqs = ZSTD_postProcessSequenceProducerResult( - zc->externalMatchCtx.seqBuffer, + zc->extSeqBuf, nbExternalSeqs, - zc->externalMatchCtx.seqBufferCapacity, + zc->extSeqBufCapacity, srcSize ); /* Return early if there is no error, since we don't need to worry about last literals */ if (!ZSTD_isError(nbPostProcessedSeqs)) { ZSTD_sequencePosition seqPos = {0,0,0}; - size_t const seqLenSum = ZSTD_fastSequenceLengthSum(zc->externalMatchCtx.seqBuffer, nbPostProcessedSeqs); + size_t const seqLenSum = ZSTD_fastSequenceLengthSum(zc->extSeqBuf, nbPostProcessedSeqs); RETURN_ERROR_IF(seqLenSum > srcSize, externalSequences_invalid, "External sequences imply too large a block!"); FORWARD_IF_ERROR( ZSTD_copySequencesToSeqStoreExplicitBlockDelim( zc, &seqPos, - zc->externalMatchCtx.seqBuffer, nbPostProcessedSeqs, + zc->extSeqBuf, nbPostProcessedSeqs, src, srcSize, zc->appliedParams.searchForExternalRepcodes ), @@ -3227,9 +3336,11 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) } /* Fallback to software matchfinder */ - { ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, - zc->appliedParams.useRowMatchFinder, - dictMode); + { ZSTD_blockCompressor const blockCompressor = + ZSTD_selectBlockCompressor( + zc->appliedParams.cParams.strategy, + zc->appliedParams.useRowMatchFinder, + dictMode); ms->ldmSeqStore = NULL; DEBUGLOG( 5, @@ -3239,9 +3350,10 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize); } } } else { /* not long range mode and no external matchfinder */ - ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, - zc->appliedParams.useRowMatchFinder, - dictMode); + ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor( + zc->appliedParams.cParams.strategy, + zc->appliedParams.useRowMatchFinder, + dictMode); ms->ldmSeqStore = NULL; lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize); } @@ -3251,29 +3363,38 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) return ZSTDbss_compress; } -static void ZSTD_copyBlockSequences(ZSTD_CCtx* zc) +static size_t ZSTD_copyBlockSequences(SeqCollector* seqCollector, const seqStore_t* seqStore, const U32 prevRepcodes[ZSTD_REP_NUM]) { - const seqStore_t* seqStore = ZSTD_getSeqStore(zc); - const seqDef* seqStoreSeqs = seqStore->sequencesStart; - size_t seqStoreSeqSize = seqStore->sequences - seqStoreSeqs; - size_t seqStoreLiteralsSize = (size_t)(seqStore->lit - seqStore->litStart); - size_t literalsRead = 0; - size_t lastLLSize; + const seqDef* inSeqs = seqStore->sequencesStart; + const size_t nbInSequences = seqStore->sequences - inSeqs; + const size_t nbInLiterals = (size_t)(seqStore->lit - seqStore->litStart); - ZSTD_Sequence* outSeqs = &zc->seqCollector.seqStart[zc->seqCollector.seqIndex]; + ZSTD_Sequence* outSeqs = seqCollector->seqIndex == 0 ? seqCollector->seqStart : seqCollector->seqStart + seqCollector->seqIndex; + const size_t nbOutSequences = nbInSequences + 1; + size_t nbOutLiterals = 0; + repcodes_t repcodes; size_t i; - repcodes_t updatedRepcodes; - assert(zc->seqCollector.seqIndex + 1 < zc->seqCollector.maxSequences); - /* Ensure we have enough space for last literals "sequence" */ - assert(zc->seqCollector.maxSequences >= seqStoreSeqSize + 1); - ZSTD_memcpy(updatedRepcodes.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t)); - for (i = 0; i < seqStoreSeqSize; ++i) { - U32 rawOffset = seqStoreSeqs[i].offBase - ZSTD_REP_NUM; - outSeqs[i].litLength = seqStoreSeqs[i].litLength; - outSeqs[i].matchLength = seqStoreSeqs[i].mlBase + MINMATCH; + /* Bounds check that we have enough space for every input sequence + * and the block delimiter + */ + assert(seqCollector->seqIndex <= seqCollector->maxSequences); + RETURN_ERROR_IF( + nbOutSequences > (size_t)(seqCollector->maxSequences - seqCollector->seqIndex), + dstSize_tooSmall, + "Not enough space to copy sequences"); + + ZSTD_memcpy(&repcodes, prevRepcodes, sizeof(repcodes)); + for (i = 0; i < nbInSequences; ++i) { + U32 rawOffset; + outSeqs[i].litLength = inSeqs[i].litLength; + outSeqs[i].matchLength = inSeqs[i].mlBase + MINMATCH; outSeqs[i].rep = 0; + /* Handle the possible single length >= 64K + * There can only be one because we add MINMATCH to every match length, + * and blocks are at most 128K. + */ if (i == seqStore->longLengthPos) { if (seqStore->longLengthType == ZSTD_llt_literalLength) { outSeqs[i].litLength += 0x10000; @@ -3282,41 +3403,55 @@ static void ZSTD_copyBlockSequences(ZSTD_CCtx* zc) } } - if (seqStoreSeqs[i].offBase <= ZSTD_REP_NUM) { - /* Derive the correct offset corresponding to a repcode */ - outSeqs[i].rep = seqStoreSeqs[i].offBase; + /* Determine the raw offset given the offBase, which may be a repcode. */ + if (OFFBASE_IS_REPCODE(inSeqs[i].offBase)) { + const U32 repcode = OFFBASE_TO_REPCODE(inSeqs[i].offBase); + assert(repcode > 0); + outSeqs[i].rep = repcode; if (outSeqs[i].litLength != 0) { - rawOffset = updatedRepcodes.rep[outSeqs[i].rep - 1]; + rawOffset = repcodes.rep[repcode - 1]; } else { - if (outSeqs[i].rep == 3) { - rawOffset = updatedRepcodes.rep[0] - 1; + if (repcode == 3) { + assert(repcodes.rep[0] > 1); + rawOffset = repcodes.rep[0] - 1; } else { - rawOffset = updatedRepcodes.rep[outSeqs[i].rep]; + rawOffset = repcodes.rep[repcode]; } } + } else { + rawOffset = OFFBASE_TO_OFFSET(inSeqs[i].offBase); } outSeqs[i].offset = rawOffset; - /* seqStoreSeqs[i].offset == offCode+1, and ZSTD_updateRep() expects offCode - so we provide seqStoreSeqs[i].offset - 1 */ - ZSTD_updateRep(updatedRepcodes.rep, - seqStoreSeqs[i].offBase, - seqStoreSeqs[i].litLength == 0); - literalsRead += outSeqs[i].litLength; + + /* Update repcode history for the sequence */ + ZSTD_updateRep(repcodes.rep, + inSeqs[i].offBase, + inSeqs[i].litLength == 0); + + nbOutLiterals += outSeqs[i].litLength; } /* Insert last literals (if any exist) in the block as a sequence with ml == off == 0. * If there are no last literals, then we'll emit (of: 0, ml: 0, ll: 0), which is a marker * for the block boundary, according to the API. */ - assert(seqStoreLiteralsSize >= literalsRead); - lastLLSize = seqStoreLiteralsSize - literalsRead; - outSeqs[i].litLength = (U32)lastLLSize; - outSeqs[i].matchLength = outSeqs[i].offset = outSeqs[i].rep = 0; - seqStoreSeqSize++; - zc->seqCollector.seqIndex += seqStoreSeqSize; + assert(nbInLiterals >= nbOutLiterals); + { + const size_t lastLLSize = nbInLiterals - nbOutLiterals; + outSeqs[nbInSequences].litLength = (U32)lastLLSize; + outSeqs[nbInSequences].matchLength = 0; + outSeqs[nbInSequences].offset = 0; + assert(nbOutSequences == nbInSequences + 1); + } + seqCollector->seqIndex += nbOutSequences; + assert(seqCollector->seqIndex <= seqCollector->maxSequences); + + return 0; } size_t ZSTD_sequenceBound(size_t srcSize) { - return (srcSize / ZSTD_MINMATCH_MIN) + 1; + const size_t maxNbSeq = (srcSize / ZSTD_MINMATCH_MIN) + 1; + const size_t maxNbDelims = (srcSize / ZSTD_BLOCKSIZE_MAX_MIN) + 1; + return maxNbSeq + maxNbDelims; } size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs, @@ -3325,6 +3460,16 @@ size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs, const size_t dstCapacity = ZSTD_compressBound(srcSize); void* dst = ZSTD_customMalloc(dstCapacity, ZSTD_defaultCMem); SeqCollector seqCollector; + { + int targetCBlockSize; + FORWARD_IF_ERROR(ZSTD_CCtx_getParameter(zc, ZSTD_c_targetCBlockSize, &targetCBlockSize), ""); + RETURN_ERROR_IF(targetCBlockSize != 0, parameter_unsupported, "targetCBlockSize != 0"); + } + { + int nbWorkers; + FORWARD_IF_ERROR(ZSTD_CCtx_getParameter(zc, ZSTD_c_nbWorkers, &nbWorkers), ""); + RETURN_ERROR_IF(nbWorkers != 0, parameter_unsupported, "nbWorkers != 0"); + } RETURN_ERROR_IF(dst == NULL, memory_allocation, "NULL pointer!"); @@ -3334,8 +3479,12 @@ size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs, seqCollector.maxSequences = outSeqsSize; zc->seqCollector = seqCollector; - ZSTD_compress2(zc, dst, dstCapacity, src, srcSize); - ZSTD_customFree(dst, ZSTD_defaultCMem); + { + const size_t ret = ZSTD_compress2(zc, dst, dstCapacity, src, srcSize); + ZSTD_customFree(dst, ZSTD_defaultCMem); + FORWARD_IF_ERROR(ret, "ZSTD_compress2 failed"); + } + assert(zc->seqCollector.seqIndex <= ZSTD_sequenceBound(srcSize)); return zc->seqCollector.seqIndex; } @@ -3858,9 +4007,10 @@ ZSTD_seqStore_resolveOffCodes(repcodes_t* const dRepcodes, repcodes_t* const cRe const seqStore_t* const seqStore, U32 const nbSeq) { U32 idx = 0; + U32 const longLitLenIdx = seqStore->longLengthType == ZSTD_llt_literalLength ? seqStore->longLengthPos : nbSeq; for (; idx < nbSeq; ++idx) { seqDef* const seq = seqStore->sequencesStart + idx; - U32 const ll0 = (seq->litLength == 0); + U32 const ll0 = (seq->litLength == 0) && (idx != longLitLenIdx); U32 const offBase = seq->offBase; assert(offBase > 0); if (OFFBASE_IS_REPCODE(offBase)) { @@ -3927,8 +4077,9 @@ ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, cSeqsSize = 1; } + /* Sequence collection not supported when block splitting */ if (zc->seqCollector.collectSequences) { - ZSTD_copyBlockSequences(zc); + FORWARD_IF_ERROR(ZSTD_copyBlockSequences(&zc->seqCollector, seqStore, dRepOriginal.rep), "copyBlockSequences failed"); ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); return 0; } @@ -4150,6 +4301,7 @@ ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc, if (bss == ZSTDbss_noCompress) { if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + RETURN_ERROR_IF(zc->seqCollector.collectSequences, sequenceProducer_failed, "Uncompressible block"); cSize = ZSTD_noCompressBlock(dst, dstCapacity, src, srcSize, lastBlock); FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed"); DEBUGLOG(4, "ZSTD_compressBlock_splitBlock: Nocompress block"); @@ -4182,11 +4334,15 @@ ZSTD_compressBlock_internal(ZSTD_CCtx* zc, { const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize); FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed"); - if (bss == ZSTDbss_noCompress) { cSize = 0; goto out; } + if (bss == ZSTDbss_noCompress) { + RETURN_ERROR_IF(zc->seqCollector.collectSequences, sequenceProducer_failed, "Uncompressible block"); + cSize = 0; + goto out; + } } if (zc->seqCollector.collectSequences) { - ZSTD_copyBlockSequences(zc); + FORWARD_IF_ERROR(ZSTD_copyBlockSequences(&zc->seqCollector, ZSTD_getSeqStore(zc), zc->blockState.prevCBlock->rep), "copyBlockSequences failed"); ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); return 0; } @@ -4499,19 +4655,15 @@ size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity) } } -size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq) +void ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq) { - RETURN_ERROR_IF(cctx->stage != ZSTDcs_init, stage_wrong, - "wrong cctx stage"); - RETURN_ERROR_IF(cctx->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable, - parameter_unsupported, - "incompatible with ldm"); + assert(cctx->stage == ZSTDcs_init); + assert(nbSeq == 0 || cctx->appliedParams.ldmParams.enableLdm != ZSTD_ps_enable); cctx->externSeqStore.seq = seq; cctx->externSeqStore.size = nbSeq; cctx->externSeqStore.capacity = nbSeq; cctx->externSeqStore.pos = 0; cctx->externSeqStore.posInSequence = 0; - return 0; } @@ -4576,31 +4728,51 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx, } } -size_t ZSTD_compressContinue (ZSTD_CCtx* cctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize) +size_t ZSTD_compressContinue_public(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) { DEBUGLOG(5, "ZSTD_compressContinue (srcSize=%u)", (unsigned)srcSize); return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1 /* frame mode */, 0 /* last chunk */); } +/* NOTE: Must just wrap ZSTD_compressContinue_public() */ +size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + return ZSTD_compressContinue_public(cctx, dst, dstCapacity, src, srcSize); +} -size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx) +static size_t ZSTD_getBlockSize_deprecated(const ZSTD_CCtx* cctx) { ZSTD_compressionParameters const cParams = cctx->appliedParams.cParams; assert(!ZSTD_checkCParams(cParams)); return MIN(cctx->appliedParams.maxBlockSize, (size_t)1 << cParams.windowLog); } -size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) +/* NOTE: Must just wrap ZSTD_getBlockSize_deprecated() */ +size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx) +{ + return ZSTD_getBlockSize_deprecated(cctx); +} + +/* NOTE: Must just wrap ZSTD_compressBlock_deprecated() */ +size_t ZSTD_compressBlock_deprecated(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) { DEBUGLOG(5, "ZSTD_compressBlock: srcSize = %u", (unsigned)srcSize); - { size_t const blockSizeMax = ZSTD_getBlockSize(cctx); + { size_t const blockSizeMax = ZSTD_getBlockSize_deprecated(cctx); RETURN_ERROR_IF(srcSize > blockSizeMax, srcSize_wrong, "input is larger than a block"); } return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */); } +/* NOTE: Must just wrap ZSTD_compressBlock_deprecated() */ +size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_deprecated(cctx, dst, dstCapacity, src, srcSize); +} + /*! ZSTD_loadDictionaryContent() : * @return : 0, or an error code */ @@ -4644,43 +4816,61 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, ip = iend - maxDictSize; src = ip; srcSize = maxDictSize; - } } + } + } if (srcSize > ZSTD_CHUNKSIZE_MAX) { /* We must have cleared our windows when our source is this large. */ assert(ZSTD_window_isEmpty(ms->window)); if (loadLdmDict) assert(ZSTD_window_isEmpty(ls->window)); } + ZSTD_window_update(&ms->window, src, srcSize, /* forceNonContiguous */ 0); DEBUGLOG(4, "ZSTD_loadDictionaryContent(): useRowMatchFinder=%d", (int)params->useRowMatchFinder); - ZSTD_window_update(&ms->window, src, srcSize, /* forceNonContiguous */ 0); - ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base); - ms->forceNonContiguous = params->deterministicRefPrefix; - if (loadLdmDict) { + if (loadLdmDict) { /* Load the entire dict into LDM matchfinders. */ ZSTD_window_update(&ls->window, src, srcSize, /* forceNonContiguous */ 0); ls->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ls->window.base); + ZSTD_ldm_fillHashTable(ls, ip, iend, ¶ms->ldmParams); } + /* If the dict is larger than we can reasonably index in our tables, only load the suffix. */ + if (params->cParams.strategy < ZSTD_btultra) { + U32 maxDictSize = 8U << MIN(MAX(params->cParams.hashLog, params->cParams.chainLog), 28); + if (srcSize > maxDictSize) { + ip = iend - maxDictSize; + src = ip; + srcSize = maxDictSize; + } + } + + ms->nextToUpdate = (U32)(ip - ms->window.base); + ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base); + ms->forceNonContiguous = params->deterministicRefPrefix; + if (srcSize <= HASH_READ_SIZE) return 0; ZSTD_overflowCorrectIfNeeded(ms, ws, params, ip, iend); - if (loadLdmDict) - ZSTD_ldm_fillHashTable(ls, ip, iend, ¶ms->ldmParams); - switch(params->cParams.strategy) { case ZSTD_fast: ZSTD_fillHashTable(ms, iend, dtlm, tfp); break; case ZSTD_dfast: +#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR ZSTD_fillDoubleHashTable(ms, iend, dtlm, tfp); +#else + assert(0); /* shouldn't be called: cparams should've been adjusted. */ +#endif break; case ZSTD_greedy: case ZSTD_lazy: case ZSTD_lazy2: +#if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) assert(srcSize >= HASH_READ_SIZE); if (ms->dedicatedDictSearch) { assert(ms->chainTable != NULL); @@ -4688,7 +4878,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, } else { assert(params->useRowMatchFinder != ZSTD_ps_auto); if (params->useRowMatchFinder == ZSTD_ps_enable) { - size_t const tagTableSize = ((size_t)1 << params->cParams.hashLog) * sizeof(U16); + size_t const tagTableSize = ((size_t)1 << params->cParams.hashLog); ZSTD_memset(ms->tagTable, 0, tagTableSize); ZSTD_row_update(ms, iend-HASH_READ_SIZE); DEBUGLOG(4, "Using row-based hash table for lazy dict"); @@ -4697,14 +4887,23 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, DEBUGLOG(4, "Using chain-based hash table for lazy dict"); } } +#else + assert(0); /* shouldn't be called: cparams should've been adjusted. */ +#endif break; case ZSTD_btlazy2: /* we want the dictionary table fully sorted */ case ZSTD_btopt: case ZSTD_btultra: case ZSTD_btultra2: +#if !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR) assert(srcSize >= HASH_READ_SIZE); ZSTD_updateTree(ms, iend-HASH_READ_SIZE, iend); +#else + assert(0); /* shouldn't be called: cparams should've been adjusted. */ +#endif break; default: @@ -4751,11 +4950,10 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, /* We only set the loaded table as valid if it contains all non-zero * weights. Otherwise, we set it to check */ - if (!hasZeroWeights) + if (!hasZeroWeights && maxSymbolValue == 255) bs->entropy.huf.repeatMode = HUF_repeat_valid; RETURN_ERROR_IF(HUF_isError(hufHeaderSize), dictionary_corrupted, ""); - RETURN_ERROR_IF(maxSymbolValue < 255, dictionary_corrupted, ""); dictPtr += hufHeaderSize; } @@ -4991,8 +5189,8 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, &cctxParams, pledgedSrcSize); } -size_t -ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel) +static size_t +ZSTD_compressBegin_usingDict_deprecated(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel) { ZSTD_CCtx_params cctxParams; { ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_noAttachDict); @@ -5003,9 +5201,15 @@ ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered); } +size_t +ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel) +{ + return ZSTD_compressBegin_usingDict_deprecated(cctx, dict, dictSize, compressionLevel); +} + size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel) { - return ZSTD_compressBegin_usingDict(cctx, NULL, 0, compressionLevel); + return ZSTD_compressBegin_usingDict_deprecated(cctx, NULL, 0, compressionLevel); } @@ -5016,14 +5220,13 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity) { BYTE* const ostart = (BYTE*)dst; BYTE* op = ostart; - size_t fhSize = 0; DEBUGLOG(4, "ZSTD_writeEpilogue"); RETURN_ERROR_IF(cctx->stage == ZSTDcs_created, stage_wrong, "init missing"); /* special case : empty frame */ if (cctx->stage == ZSTDcs_init) { - fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams, 0, 0); + size_t fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams, 0, 0); FORWARD_IF_ERROR(fhSize, "ZSTD_writeFrameHeader failed"); dstCapacity -= fhSize; op += fhSize; @@ -5033,8 +5236,9 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity) if (cctx->stage != ZSTDcs_ending) { /* write one last empty block, make it the "last" block */ U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0; - RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for epilogue"); - MEM_writeLE32(op, cBlockHeader24); + ZSTD_STATIC_ASSERT(ZSTD_BLOCKHEADERSIZE == 3); + RETURN_ERROR_IF(dstCapacity<3, dstSize_tooSmall, "no room for epilogue"); + MEM_writeLE24(op, cBlockHeader24); op += ZSTD_blockHeaderSize; dstCapacity -= ZSTD_blockHeaderSize; } @@ -5075,9 +5279,9 @@ void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize) #endif } -size_t ZSTD_compressEnd (ZSTD_CCtx* cctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize) +size_t ZSTD_compressEnd_public(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) { size_t endResult; size_t const cSize = ZSTD_compressContinue_internal(cctx, @@ -5101,6 +5305,14 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx, return cSize + endResult; } +/* NOTE: Must just wrap ZSTD_compressEnd_public() */ +size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + return ZSTD_compressEnd_public(cctx, dst, dstCapacity, src, srcSize); +} + size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, @@ -5129,7 +5341,7 @@ size_t ZSTD_compress_advanced_internal( FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL, params, srcSize, ZSTDb_not_buffered) , ""); - return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize); + return ZSTD_compressEnd_public(cctx, dst, dstCapacity, src, srcSize); } size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx, @@ -5356,7 +5568,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced2( cctxParams.useRowMatchFinder, cctxParams.enableDedicatedDictSearch, customMem); - if (ZSTD_isError( ZSTD_initCDict_internal(cdict, + if (!cdict || ZSTD_isError( ZSTD_initCDict_internal(cdict, dict, dictSize, dictLoadMethod, dictContentType, cctxParams) )) { @@ -5451,6 +5663,7 @@ const ZSTD_CDict* ZSTD_initStaticCDict( params.cParams = cParams; params.useRowMatchFinder = useRowMatchFinder; cdict->useRowMatchFinder = useRowMatchFinder; + cdict->compressionLevel = ZSTD_NO_CLEVEL; if (ZSTD_isError( ZSTD_initCDict_internal(cdict, dict, dictSize, @@ -5530,12 +5743,17 @@ size_t ZSTD_compressBegin_usingCDict_advanced( /* ZSTD_compressBegin_usingCDict() : * cdict must be != NULL */ -size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) +size_t ZSTD_compressBegin_usingCDict_deprecated(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) { ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ }; return ZSTD_compressBegin_usingCDict_internal(cctx, cdict, fParams, ZSTD_CONTENTSIZE_UNKNOWN); } +size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) +{ + return ZSTD_compressBegin_usingCDict_deprecated(cctx, cdict); +} + /*! ZSTD_compress_usingCDict_internal(): * Implementation of various ZSTD_compress_usingCDict* functions. */ @@ -5545,7 +5763,7 @@ static size_t ZSTD_compress_usingCDict_internal(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict, ZSTD_frameParameters fParams) { FORWARD_IF_ERROR(ZSTD_compressBegin_usingCDict_internal(cctx, cdict, fParams, srcSize), ""); /* will check if cdict != NULL */ - return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize); + return ZSTD_compressEnd_public(cctx, dst, dstCapacity, src, srcSize); } /*! ZSTD_compress_usingCDict_advanced(): @@ -5774,7 +5992,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, if (zcs->appliedParams.inBufferMode == ZSTD_bm_stable) { assert(input->pos >= zcs->stableIn_notConsumed); input->pos -= zcs->stableIn_notConsumed; - ip -= zcs->stableIn_notConsumed; + if (ip) ip -= zcs->stableIn_notConsumed; zcs->stableIn_notConsumed = 0; } if (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered) { @@ -5803,7 +6021,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, || zcs->appliedParams.outBufferMode == ZSTD_bm_stable) /* OR we are allowed to return dstSizeTooSmall */ && (zcs->inBuffPos == 0) ) { /* shortcut to compression pass directly into output buffer */ - size_t const cSize = ZSTD_compressEnd(zcs, + size_t const cSize = ZSTD_compressEnd_public(zcs, op, oend-op, ip, iend-ip); DEBUGLOG(4, "ZSTD_compressEnd : cSize=%u", (unsigned)cSize); FORWARD_IF_ERROR(cSize, "ZSTD_compressEnd failed"); @@ -5861,9 +6079,9 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, if (inputBuffered) { unsigned const lastBlock = (flushMode == ZSTD_e_end) && (ip==iend); cSize = lastBlock ? - ZSTD_compressEnd(zcs, cDst, oSize, + ZSTD_compressEnd_public(zcs, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize) : - ZSTD_compressContinue(zcs, cDst, oSize, + ZSTD_compressContinue_public(zcs, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize); FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed"); zcs->frameEnded = lastBlock; @@ -5879,8 +6097,8 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, } else { /* !inputBuffered, hence ZSTD_bm_stable */ unsigned const lastBlock = (flushMode == ZSTD_e_end) && (ip + iSize == iend); cSize = lastBlock ? - ZSTD_compressEnd(zcs, cDst, oSize, ip, iSize) : - ZSTD_compressContinue(zcs, cDst, oSize, ip, iSize); + ZSTD_compressEnd_public(zcs, cDst, oSize, ip, iSize) : + ZSTD_compressContinue_public(zcs, cDst, oSize, ip, iSize); /* Consume the input prior to error checking to mirror buffered mode. */ if (ip) ip += iSize; FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed"); @@ -6033,7 +6251,7 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx, #ifdef ZSTD_MULTITHREAD /* If external matchfinder is enabled, make sure to fail before checking job size (for consistency) */ RETURN_ERROR_IF( - params.useSequenceProducer == 1 && params.nbWorkers >= 1, + ZSTD_hasExtSeqProd(¶ms) && params.nbWorkers >= 1, parameter_combination_unsupported, "External sequence producer isn't supported with nbWorkers >= 1" ); @@ -6325,7 +6543,7 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx, if (cctx->appliedParams.validateSequences) { seqPos->posInSrc += litLength + matchLength; FORWARD_IF_ERROR(ZSTD_validateSequence(offBase, matchLength, cctx->appliedParams.cParams.minMatch, seqPos->posInSrc, - cctx->appliedParams.cParams.windowLog, dictSize, cctx->appliedParams.useSequenceProducer), + cctx->appliedParams.cParams.windowLog, dictSize, ZSTD_hasExtSeqProd(&cctx->appliedParams)), "Sequence validation failed"); } RETURN_ERROR_IF(idx - seqPos->idx >= cctx->seqStore.maxNbSeq, externalSequences_invalid, @@ -6463,7 +6681,7 @@ ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* if (cctx->appliedParams.validateSequences) { seqPos->posInSrc += litLength + matchLength; FORWARD_IF_ERROR(ZSTD_validateSequence(offBase, matchLength, cctx->appliedParams.cParams.minMatch, seqPos->posInSrc, - cctx->appliedParams.cParams.windowLog, dictSize, cctx->appliedParams.useSequenceProducer), + cctx->appliedParams.cParams.windowLog, dictSize, ZSTD_hasExtSeqProd(&cctx->appliedParams)), "Sequence validation failed"); } DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offBase, matchLength, litLength); @@ -6909,19 +7127,27 @@ ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeH } void ZSTD_registerSequenceProducer( - ZSTD_CCtx* zc, void* mState, - ZSTD_sequenceProducer_F* mFinder + ZSTD_CCtx* zc, + void* extSeqProdState, + ZSTD_sequenceProducer_F extSeqProdFunc ) { - if (mFinder != NULL) { - ZSTD_externalMatchCtx emctx; - emctx.mState = mState; - emctx.mFinder = mFinder; - emctx.seqBuffer = NULL; - emctx.seqBufferCapacity = 0; - zc->externalMatchCtx = emctx; - zc->requestedParams.useSequenceProducer = 1; + assert(zc != NULL); + ZSTD_CCtxParams_registerSequenceProducer( + &zc->requestedParams, extSeqProdState, extSeqProdFunc + ); +} + +void ZSTD_CCtxParams_registerSequenceProducer( + ZSTD_CCtx_params* params, + void* extSeqProdState, + ZSTD_sequenceProducer_F extSeqProdFunc +) { + assert(params != NULL); + if (extSeqProdFunc != NULL) { + params->extSeqProdFunc = extSeqProdFunc; + params->extSeqProdState = extSeqProdState; } else { - ZSTD_memset(&zc->externalMatchCtx, 0, sizeof(zc->externalMatchCtx)); - zc->requestedParams.useSequenceProducer = 0; + params->extSeqProdFunc = NULL; + params->extSeqProdState = NULL; } } diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_compress_internal.h b/src/dependencies/zstd-1.5.6/lib/compress/zstd_compress_internal.h similarity index 92% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_compress_internal.h rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_compress_internal.h index cbb85e5..e41d7b7 100644 --- a/src/dependencies/zstd-1.5.4/lib/compress/zstd_compress_internal.h +++ b/src/dependencies/zstd-1.5.6/lib/compress/zstd_compress_internal.h @@ -39,7 +39,7 @@ extern "C" { It's not a big deal though : candidate will just be sorted again. Additionally, candidate position 1 will be lost. But candidate 1 cannot hide a large tree of candidates, so it's a minimal loss. - The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table re-use with a different strategy. + The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table reuse with a different strategy. This constant is required by ZSTD_compressBlock_btlazy2() and ZSTD_reduceTable_internal() */ @@ -159,23 +159,24 @@ typedef struct { UNUSED_ATTR static const rawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0, 0}; typedef struct { - int price; - U32 off; - U32 mlen; - U32 litlen; - U32 rep[ZSTD_REP_NUM]; + int price; /* price from beginning of segment to this position */ + U32 off; /* offset of previous match */ + U32 mlen; /* length of previous match */ + U32 litlen; /* nb of literals since previous match */ + U32 rep[ZSTD_REP_NUM]; /* offset history after previous match */ } ZSTD_optimal_t; typedef enum { zop_dynamic=0, zop_predef } ZSTD_OptPrice_e; +#define ZSTD_OPT_SIZE (ZSTD_OPT_NUM+3) typedef struct { /* All tables are allocated inside cctx->workspace by ZSTD_resetCCtx_internal() */ unsigned* litFreq; /* table of literals statistics, of size 256 */ unsigned* litLengthFreq; /* table of litLength statistics, of size (MaxLL+1) */ unsigned* matchLengthFreq; /* table of matchLength statistics, of size (MaxML+1) */ unsigned* offCodeFreq; /* table of offCode statistics, of size (MaxOff+1) */ - ZSTD_match_t* matchTable; /* list of found matches, of size ZSTD_OPT_NUM+1 */ - ZSTD_optimal_t* priceTable; /* All positions tracked by optimal parser, of size ZSTD_OPT_NUM+1 */ + ZSTD_match_t* matchTable; /* list of found matches, of size ZSTD_OPT_SIZE */ + ZSTD_optimal_t* priceTable; /* All positions tracked by optimal parser, of size ZSTD_OPT_SIZE */ U32 litSum; /* nb of literals */ U32 litLengthSum; /* nb of litLength codes */ @@ -226,8 +227,10 @@ struct ZSTD_matchState_t { U32 hashLog3; /* dispatch table for matches of len==3 : larger == faster, more memory */ U32 rowHashLog; /* For row-based matchfinder: Hashlog based on nb of rows in the hashTable.*/ - U16* tagTable; /* For row-based matchFinder: A row-based table containing the hashes and head index. */ + BYTE* tagTable; /* For row-based matchFinder: A row-based table containing the hashes and head index. */ U32 hashCache[ZSTD_ROW_HASH_CACHE_SIZE]; /* For row-based matchFinder: a cache of hashes to improve speed */ + U64 hashSalt; /* For row-based matchFinder: salts the hash for reuse of tag table */ + U32 hashSaltEntropy; /* For row-based matchFinder: collects entropy for salt generation */ U32* hashTable; U32* hashTable3; @@ -247,6 +250,13 @@ struct ZSTD_matchState_t { * This behavior is controlled from the cctx ms. * This parameter has no effect in the cdict ms. */ int prefetchCDictTables; + + /* When == 0, lazy match finders insert every position. + * When != 0, lazy match finders only insert positions they search. + * This allows them to skip much faster over incompressible data, + * at a small cost to compression ratio. + */ + int lazySkipping; }; typedef struct { @@ -351,10 +361,11 @@ struct ZSTD_CCtx_params_s { * if the external matchfinder returns an error code. */ int enableMatchFinderFallback; - /* Indicates whether an external matchfinder has been referenced. - * Users can't set this externally. - * It is set internally in ZSTD_registerSequenceProducer(). */ - int useSequenceProducer; + /* Parameters for the external sequence producer API. + * Users set these parameters through ZSTD_registerSequenceProducer(). + * It is not possible to set these parameters individually through the public API. */ + void* extSeqProdState; + ZSTD_sequenceProducer_F extSeqProdFunc; /* Adjust the max block size*/ size_t maxBlockSize; @@ -392,14 +403,6 @@ typedef struct { ZSTD_entropyCTablesMetadata_t entropyMetadata; } ZSTD_blockSplitCtx; -/* Context for block-level external matchfinder API */ -typedef struct { - void* mState; - ZSTD_sequenceProducer_F* mFinder; - ZSTD_Sequence* seqBuffer; - size_t seqBufferCapacity; -} ZSTD_externalMatchCtx; - struct ZSTD_CCtx_s { ZSTD_compressionStage_e stage; int cParamsChanged; /* == 1 if cParams(except wlog) or compression level are changed in requestedParams. Triggers transmission of new params to ZSTDMT (if available) then reset to 0. */ @@ -470,8 +473,9 @@ struct ZSTD_CCtx_s { /* Workspace for block splitter */ ZSTD_blockSplitCtx blockSplitCtx; - /* Workspace for external matchfinder */ - ZSTD_externalMatchCtx externalMatchCtx; + /* Buffer for output from external sequence producer */ + ZSTD_Sequence* extSeqBuf; + size_t extSeqBufCapacity; }; typedef enum { ZSTD_dtlm_fast, ZSTD_dtlm_full } ZSTD_dictTableLoadMethod_e; @@ -787,28 +791,35 @@ ZSTD_count_2segments(const BYTE* ip, const BYTE* match, * Hashes ***************************************/ static const U32 prime3bytes = 506832829U; -static U32 ZSTD_hash3(U32 u, U32 h) { assert(h <= 32); return ((u << (32-24)) * prime3bytes) >> (32-h) ; } -MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h); } /* only in zstd_opt.h */ +static U32 ZSTD_hash3(U32 u, U32 h, U32 s) { assert(h <= 32); return (((u << (32-24)) * prime3bytes) ^ s) >> (32-h) ; } +MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h, 0); } /* only in zstd_opt.h */ +MEM_STATIC size_t ZSTD_hash3PtrS(const void* ptr, U32 h, U32 s) { return ZSTD_hash3(MEM_readLE32(ptr), h, s); } static const U32 prime4bytes = 2654435761U; -static U32 ZSTD_hash4(U32 u, U32 h) { assert(h <= 32); return (u * prime4bytes) >> (32-h) ; } -static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_readLE32(ptr), h); } +static U32 ZSTD_hash4(U32 u, U32 h, U32 s) { assert(h <= 32); return ((u * prime4bytes) ^ s) >> (32-h) ; } +static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_readLE32(ptr), h, 0); } +static size_t ZSTD_hash4PtrS(const void* ptr, U32 h, U32 s) { return ZSTD_hash4(MEM_readLE32(ptr), h, s); } static const U64 prime5bytes = 889523592379ULL; -static size_t ZSTD_hash5(U64 u, U32 h) { assert(h <= 64); return (size_t)(((u << (64-40)) * prime5bytes) >> (64-h)) ; } -static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h); } +static size_t ZSTD_hash5(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-40)) * prime5bytes) ^ s) >> (64-h)) ; } +static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h, 0); } +static size_t ZSTD_hash5PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash5(MEM_readLE64(p), h, s); } static const U64 prime6bytes = 227718039650203ULL; -static size_t ZSTD_hash6(U64 u, U32 h) { assert(h <= 64); return (size_t)(((u << (64-48)) * prime6bytes) >> (64-h)) ; } -static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h); } +static size_t ZSTD_hash6(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-48)) * prime6bytes) ^ s) >> (64-h)) ; } +static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h, 0); } +static size_t ZSTD_hash6PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash6(MEM_readLE64(p), h, s); } static const U64 prime7bytes = 58295818150454627ULL; -static size_t ZSTD_hash7(U64 u, U32 h) { assert(h <= 64); return (size_t)(((u << (64-56)) * prime7bytes) >> (64-h)) ; } -static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h); } +static size_t ZSTD_hash7(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-56)) * prime7bytes) ^ s) >> (64-h)) ; } +static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h, 0); } +static size_t ZSTD_hash7PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash7(MEM_readLE64(p), h, s); } static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL; -static size_t ZSTD_hash8(U64 u, U32 h) { assert(h <= 64); return (size_t)(((u) * prime8bytes) >> (64-h)) ; } -static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); } +static size_t ZSTD_hash8(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u) * prime8bytes) ^ s) >> (64-h)) ; } +static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h, 0); } +static size_t ZSTD_hash8PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash8(MEM_readLE64(p), h, s); } + MEM_STATIC FORCE_INLINE_ATTR size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls) @@ -828,6 +839,24 @@ size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls) } } +MEM_STATIC FORCE_INLINE_ATTR +size_t ZSTD_hashPtrSalted(const void* p, U32 hBits, U32 mls, const U64 hashSalt) { + /* Although some of these hashes do support hBits up to 64, some do not. + * To be on the safe side, always avoid hBits > 32. */ + assert(hBits <= 32); + + switch(mls) + { + default: + case 4: return ZSTD_hash4PtrS(p, hBits, (U32)hashSalt); + case 5: return ZSTD_hash5PtrS(p, hBits, hashSalt); + case 6: return ZSTD_hash6PtrS(p, hBits, hashSalt); + case 7: return ZSTD_hash7PtrS(p, hBits, hashSalt); + case 8: return ZSTD_hash8PtrS(p, hBits, hashSalt); + } +} + + /** ZSTD_ipow() : * Return base^exponent. */ @@ -1019,7 +1048,9 @@ MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window, * The least significant cycleLog bits of the indices must remain the same, * which may be 0. Every index up to maxDist in the past must be valid. */ -MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog, +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog, U32 maxDist, void const* src) { /* preemptive overflow correction: @@ -1212,7 +1243,9 @@ MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) { * forget about the extDict. Handles overlap of the prefix and extDict. * Returns non-zero if the segment is contiguous. */ -MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window, +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_window_update(ZSTD_window_t* window, void const* src, size_t srcSize, int forceNonContiguous) { @@ -1433,11 +1466,10 @@ size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity); * This cannot be used when long range matching is enabled. * Zstd will use these sequences, and pass the literals to a secondary block * compressor. - * @return : An error code on failure. * NOTE: seqs are not verified! Invalid sequences can cause out-of-bounds memory * access and data corruption. */ -size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq); +void ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq); /** ZSTD_cycleLog() : * condition for correct operation : hashLog > 1 */ @@ -1475,4 +1507,28 @@ ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* const ZSTD_Sequence* const inSeqs, size_t inSeqsSize, const void* src, size_t blockSize, ZSTD_paramSwitch_e externalRepSearch); +/* Returns 1 if an external sequence producer is registered, otherwise returns 0. */ +MEM_STATIC int ZSTD_hasExtSeqProd(const ZSTD_CCtx_params* params) { + return params->extSeqProdFunc != NULL; +} + +/* =============================================================== + * Deprecated definitions that are still used internally to avoid + * deprecation warnings. These functions are exactly equivalent to + * their public variants, but avoid the deprecation warnings. + * =============================================================== */ + +size_t ZSTD_compressBegin_usingCDict_deprecated(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); + +size_t ZSTD_compressContinue_public(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + +size_t ZSTD_compressEnd_public(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + +size_t ZSTD_compressBlock_deprecated(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); + + #endif /* ZSTD_COMPRESS_H */ diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_compress_literals.c b/src/dependencies/zstd-1.5.6/lib/compress/zstd_compress_literals.c similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_compress_literals.c rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_compress_literals.c diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_compress_literals.h b/src/dependencies/zstd-1.5.6/lib/compress/zstd_compress_literals.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_compress_literals.h rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_compress_literals.h diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_compress_sequences.c b/src/dependencies/zstd-1.5.6/lib/compress/zstd_compress_sequences.c similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_compress_sequences.c rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_compress_sequences.c diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_compress_sequences.h b/src/dependencies/zstd-1.5.6/lib/compress/zstd_compress_sequences.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_compress_sequences.h rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_compress_sequences.h diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_compress_superblock.c b/src/dependencies/zstd-1.5.6/lib/compress/zstd_compress_superblock.c similarity index 66% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_compress_superblock.c rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_compress_superblock.c index 638c4ac..628a2dc 100644 --- a/src/dependencies/zstd-1.5.4/lib/compress/zstd_compress_superblock.c +++ b/src/dependencies/zstd-1.5.6/lib/compress/zstd_compress_superblock.c @@ -76,8 +76,8 @@ ZSTD_compressSubBlock_literal(const HUF_CElt* hufTable, } { int const flags = bmi2 ? HUF_flags_bmi2 : 0; - const size_t cSize = singleStream ? HUF_compress1X_usingCTable(op, oend-op, literals, litSize, hufTable, flags) - : HUF_compress4X_usingCTable(op, oend-op, literals, litSize, hufTable, flags); + const size_t cSize = singleStream ? HUF_compress1X_usingCTable(op, (size_t)(oend-op), literals, litSize, hufTable, flags) + : HUF_compress4X_usingCTable(op, (size_t)(oend-op), literals, litSize, hufTable, flags); op += cSize; cLitSize += cSize; if (cSize == 0 || ERR_isError(cSize)) { @@ -102,7 +102,7 @@ ZSTD_compressSubBlock_literal(const HUF_CElt* hufTable, switch(lhSize) { case 3: /* 2 - 2 - 10 - 10 */ - { U32 const lhc = hType + ((!singleStream) << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<14); + { U32 const lhc = hType + ((U32)(!singleStream) << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<14); MEM_writeLE24(ostart, lhc); break; } @@ -122,30 +122,30 @@ ZSTD_compressSubBlock_literal(const HUF_CElt* hufTable, } *entropyWritten = 1; DEBUGLOG(5, "Compressed literals: %u -> %u", (U32)litSize, (U32)(op-ostart)); - return op-ostart; + return (size_t)(op-ostart); } static size_t ZSTD_seqDecompressedSize(seqStore_t const* seqStore, - const seqDef* sequences, size_t nbSeq, - size_t litSize, int lastSequence) + const seqDef* sequences, size_t nbSeqs, + size_t litSize, int lastSubBlock) { - const seqDef* const sstart = sequences; - const seqDef* const send = sequences + nbSeq; - const seqDef* sp = sstart; size_t matchLengthSum = 0; size_t litLengthSum = 0; - (void)(litLengthSum); /* suppress unused variable warning on some environments */ - while (send-sp > 0) { - ZSTD_sequenceLength const seqLen = ZSTD_getSequenceLength(seqStore, sp); + size_t n; + for (n=0; n>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2; else op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3; if (nbSeq==0) { - return op - ostart; + return (size_t)(op - ostart); } /* seqHead : flags for FSE encoding type */ @@ -209,7 +209,7 @@ ZSTD_compressSubBlock_sequences(const ZSTD_fseCTables_t* fseTables, } { size_t const bitstreamSize = ZSTD_encodeSequences( - op, oend - op, + op, (size_t)(oend - op), fseTables->matchlengthCTable, mlCode, fseTables->offcodeCTable, ofCode, fseTables->litlengthCTable, llCode, @@ -253,7 +253,7 @@ ZSTD_compressSubBlock_sequences(const ZSTD_fseCTables_t* fseTables, #endif *entropyWritten = 1; - return op - ostart; + return (size_t)(op - ostart); } /** ZSTD_compressSubBlock() : @@ -279,7 +279,8 @@ static size_t ZSTD_compressSubBlock(const ZSTD_entropyCTables_t* entropy, litSize, nbSeq, writeLitEntropy, writeSeqEntropy, lastBlock); { size_t cLitSize = ZSTD_compressSubBlock_literal((const HUF_CElt*)entropy->huf.CTable, &entropyMetadata->hufMetadata, literals, litSize, - op, oend-op, bmi2, writeLitEntropy, litEntropyWritten); + op, (size_t)(oend-op), + bmi2, writeLitEntropy, litEntropyWritten); FORWARD_IF_ERROR(cLitSize, "ZSTD_compressSubBlock_literal failed"); if (cLitSize == 0) return 0; op += cLitSize; @@ -289,18 +290,18 @@ static size_t ZSTD_compressSubBlock(const ZSTD_entropyCTables_t* entropy, sequences, nbSeq, llCode, mlCode, ofCode, cctxParams, - op, oend-op, + op, (size_t)(oend-op), bmi2, writeSeqEntropy, seqEntropyWritten); FORWARD_IF_ERROR(cSeqSize, "ZSTD_compressSubBlock_sequences failed"); if (cSeqSize == 0) return 0; op += cSeqSize; } /* Write block header */ - { size_t cSize = (op-ostart)-ZSTD_blockHeaderSize; + { size_t cSize = (size_t)(op-ostart) - ZSTD_blockHeaderSize; U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3); MEM_writeLE24(ostart, cBlockHeader24); } - return op-ostart; + return (size_t)(op-ostart); } static size_t ZSTD_estimateSubBlockSize_literal(const BYTE* literals, size_t litSize, @@ -389,7 +390,11 @@ static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE* ofCodeTable, return cSeqSizeEstimate + sequencesSectionHeaderSize; } -static size_t ZSTD_estimateSubBlockSize(const BYTE* literals, size_t litSize, +typedef struct { + size_t estLitSize; + size_t estBlockSize; +} EstimatedBlockSize; +static EstimatedBlockSize ZSTD_estimateSubBlockSize(const BYTE* literals, size_t litSize, const BYTE* ofCodeTable, const BYTE* llCodeTable, const BYTE* mlCodeTable, @@ -397,15 +402,17 @@ static size_t ZSTD_estimateSubBlockSize(const BYTE* literals, size_t litSize, const ZSTD_entropyCTables_t* entropy, const ZSTD_entropyCTablesMetadata_t* entropyMetadata, void* workspace, size_t wkspSize, - int writeLitEntropy, int writeSeqEntropy) { - size_t cSizeEstimate = 0; - cSizeEstimate += ZSTD_estimateSubBlockSize_literal(literals, litSize, - &entropy->huf, &entropyMetadata->hufMetadata, - workspace, wkspSize, writeLitEntropy); - cSizeEstimate += ZSTD_estimateSubBlockSize_sequences(ofCodeTable, llCodeTable, mlCodeTable, + int writeLitEntropy, int writeSeqEntropy) +{ + EstimatedBlockSize ebs; + ebs.estLitSize = ZSTD_estimateSubBlockSize_literal(literals, litSize, + &entropy->huf, &entropyMetadata->hufMetadata, + workspace, wkspSize, writeLitEntropy); + ebs.estBlockSize = ZSTD_estimateSubBlockSize_sequences(ofCodeTable, llCodeTable, mlCodeTable, nbSeq, &entropy->fse, &entropyMetadata->fseMetadata, workspace, wkspSize, writeSeqEntropy); - return cSizeEstimate + ZSTD_blockHeaderSize; + ebs.estBlockSize += ebs.estLitSize + ZSTD_blockHeaderSize; + return ebs; } static int ZSTD_needSequenceEntropyTables(ZSTD_fseCTablesMetadata_t const* fseMetadata) @@ -419,13 +426,56 @@ static int ZSTD_needSequenceEntropyTables(ZSTD_fseCTablesMetadata_t const* fseMe return 0; } +static size_t countLiterals(seqStore_t const* seqStore, const seqDef* sp, size_t seqCount) +{ + size_t n, total = 0; + assert(sp != NULL); + for (n=0; n %zu bytes", seqCount, (const void*)sp, total); + return total; +} + +#define BYTESCALE 256 + +static size_t sizeBlockSequences(const seqDef* sp, size_t nbSeqs, + size_t targetBudget, size_t avgLitCost, size_t avgSeqCost, + int firstSubBlock) +{ + size_t n, budget = 0, inSize=0; + /* entropy headers */ + size_t const headerSize = (size_t)firstSubBlock * 120 * BYTESCALE; /* generous estimate */ + assert(firstSubBlock==0 || firstSubBlock==1); + budget += headerSize; + + /* first sequence => at least one sequence*/ + budget += sp[0].litLength * avgLitCost + avgSeqCost; + if (budget > targetBudget) return 1; + inSize = sp[0].litLength + (sp[0].mlBase+MINMATCH); + + /* loop over sequences */ + for (n=1; n targetBudget) + /* though continue to expand until the sub-block is deemed compressible */ + && (budget < inSize * BYTESCALE) ) + break; + } + + return n; +} + /** ZSTD_compressSubBlock_multi() : * Breaks super-block into multiple sub-blocks and compresses them. - * Entropy will be written to the first block. - * The following blocks will use repeat mode to compress. - * All sub-blocks are compressed blocks (no raw or rle blocks). - * @return : compressed size of the super block (which is multiple ZSTD blocks) - * Or 0 if it failed to compress. */ + * Entropy will be written into the first block. + * The following blocks use repeat_mode to compress. + * Sub-blocks are all compressed, except the last one when beneficial. + * @return : compressed size of the super block (which features multiple ZSTD blocks) + * or 0 if it failed to compress. */ static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr, const ZSTD_compressedBlockState_t* prevCBlock, ZSTD_compressedBlockState_t* nextCBlock, @@ -438,10 +488,12 @@ static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr, { const seqDef* const sstart = seqStorePtr->sequencesStart; const seqDef* const send = seqStorePtr->sequences; - const seqDef* sp = sstart; + const seqDef* sp = sstart; /* tracks progresses within seqStorePtr->sequences */ + size_t const nbSeqs = (size_t)(send - sstart); const BYTE* const lstart = seqStorePtr->litStart; const BYTE* const lend = seqStorePtr->lit; const BYTE* lp = lstart; + size_t const nbLiterals = (size_t)(lend - lstart); BYTE const* ip = (BYTE const*)src; BYTE const* const iend = ip + srcSize; BYTE* const ostart = (BYTE*)dst; @@ -450,96 +502,152 @@ static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr, const BYTE* llCodePtr = seqStorePtr->llCode; const BYTE* mlCodePtr = seqStorePtr->mlCode; const BYTE* ofCodePtr = seqStorePtr->ofCode; - size_t targetCBlockSize = cctxParams->targetCBlockSize; - size_t litSize, seqCount; - int writeLitEntropy = entropyMetadata->hufMetadata.hType == set_compressed; + size_t const minTarget = ZSTD_TARGETCBLOCKSIZE_MIN; /* enforce minimum size, to reduce undesirable side effects */ + size_t const targetCBlockSize = MAX(minTarget, cctxParams->targetCBlockSize); + int writeLitEntropy = (entropyMetadata->hufMetadata.hType == set_compressed); int writeSeqEntropy = 1; - int lastSequence = 0; - DEBUGLOG(5, "ZSTD_compressSubBlock_multi (litSize=%u, nbSeq=%u)", - (unsigned)(lend-lp), (unsigned)(send-sstart)); + DEBUGLOG(5, "ZSTD_compressSubBlock_multi (srcSize=%u, litSize=%u, nbSeq=%u)", + (unsigned)srcSize, (unsigned)(lend-lstart), (unsigned)(send-sstart)); - litSize = 0; - seqCount = 0; - do { - size_t cBlockSizeEstimate = 0; - if (sstart == send) { - lastSequence = 1; - } else { - const seqDef* const sequence = sp + seqCount; - lastSequence = sequence == send - 1; - litSize += ZSTD_getSequenceLength(seqStorePtr, sequence).litLength; - seqCount++; + /* let's start by a general estimation for the full block */ + if (nbSeqs > 0) { + EstimatedBlockSize const ebs = + ZSTD_estimateSubBlockSize(lp, nbLiterals, + ofCodePtr, llCodePtr, mlCodePtr, nbSeqs, + &nextCBlock->entropy, entropyMetadata, + workspace, wkspSize, + writeLitEntropy, writeSeqEntropy); + /* quick estimation */ + size_t const avgLitCost = nbLiterals ? (ebs.estLitSize * BYTESCALE) / nbLiterals : BYTESCALE; + size_t const avgSeqCost = ((ebs.estBlockSize - ebs.estLitSize) * BYTESCALE) / nbSeqs; + const size_t nbSubBlocks = MAX((ebs.estBlockSize + (targetCBlockSize/2)) / targetCBlockSize, 1); + size_t n, avgBlockBudget, blockBudgetSupp=0; + avgBlockBudget = (ebs.estBlockSize * BYTESCALE) / nbSubBlocks; + DEBUGLOG(5, "estimated fullblock size=%u bytes ; avgLitCost=%.2f ; avgSeqCost=%.2f ; targetCBlockSize=%u, nbSubBlocks=%u ; avgBlockBudget=%.0f bytes", + (unsigned)ebs.estBlockSize, (double)avgLitCost/BYTESCALE, (double)avgSeqCost/BYTESCALE, + (unsigned)targetCBlockSize, (unsigned)nbSubBlocks, (double)avgBlockBudget/BYTESCALE); + /* simplification: if estimates states that the full superblock doesn't compress, just bail out immediately + * this will result in the production of a single uncompressed block covering @srcSize.*/ + if (ebs.estBlockSize > srcSize) return 0; + + /* compress and write sub-blocks */ + assert(nbSubBlocks>0); + for (n=0; n < nbSubBlocks-1; n++) { + /* determine nb of sequences for current sub-block + nbLiterals from next sequence */ + size_t const seqCount = sizeBlockSequences(sp, (size_t)(send-sp), + avgBlockBudget + blockBudgetSupp, avgLitCost, avgSeqCost, n==0); + /* if reached last sequence : break to last sub-block (simplification) */ + assert(seqCount <= (size_t)(send-sp)); + if (sp + seqCount == send) break; + assert(seqCount > 0); + /* compress sub-block */ + { int litEntropyWritten = 0; + int seqEntropyWritten = 0; + size_t litSize = countLiterals(seqStorePtr, sp, seqCount); + const size_t decompressedSize = + ZSTD_seqDecompressedSize(seqStorePtr, sp, seqCount, litSize, 0); + size_t const cSize = ZSTD_compressSubBlock(&nextCBlock->entropy, entropyMetadata, + sp, seqCount, + lp, litSize, + llCodePtr, mlCodePtr, ofCodePtr, + cctxParams, + op, (size_t)(oend-op), + bmi2, writeLitEntropy, writeSeqEntropy, + &litEntropyWritten, &seqEntropyWritten, + 0); + FORWARD_IF_ERROR(cSize, "ZSTD_compressSubBlock failed"); + + /* check compressibility, update state components */ + if (cSize > 0 && cSize < decompressedSize) { + DEBUGLOG(5, "Committed sub-block compressing %u bytes => %u bytes", + (unsigned)decompressedSize, (unsigned)cSize); + assert(ip + decompressedSize <= iend); + ip += decompressedSize; + lp += litSize; + op += cSize; + llCodePtr += seqCount; + mlCodePtr += seqCount; + ofCodePtr += seqCount; + /* Entropy only needs to be written once */ + if (litEntropyWritten) { + writeLitEntropy = 0; + } + if (seqEntropyWritten) { + writeSeqEntropy = 0; + } + sp += seqCount; + blockBudgetSupp = 0; + } } + /* otherwise : do not compress yet, coalesce current sub-block with following one */ } - if (lastSequence) { - assert(lp <= lend); - assert(litSize <= (size_t)(lend - lp)); - litSize = (size_t)(lend - lp); - } - /* I think there is an optimization opportunity here. - * Calling ZSTD_estimateSubBlockSize for every sequence can be wasteful - * since it recalculates estimate from scratch. - * For example, it would recount literal distribution and symbol codes every time. - */ - cBlockSizeEstimate = ZSTD_estimateSubBlockSize(lp, litSize, ofCodePtr, llCodePtr, mlCodePtr, seqCount, - &nextCBlock->entropy, entropyMetadata, - workspace, wkspSize, writeLitEntropy, writeSeqEntropy); - if (cBlockSizeEstimate > targetCBlockSize || lastSequence) { - int litEntropyWritten = 0; - int seqEntropyWritten = 0; - const size_t decompressedSize = ZSTD_seqDecompressedSize(seqStorePtr, sp, seqCount, litSize, lastSequence); - const size_t cSize = ZSTD_compressSubBlock(&nextCBlock->entropy, entropyMetadata, - sp, seqCount, - lp, litSize, - llCodePtr, mlCodePtr, ofCodePtr, - cctxParams, - op, oend-op, - bmi2, writeLitEntropy, writeSeqEntropy, - &litEntropyWritten, &seqEntropyWritten, - lastBlock && lastSequence); - FORWARD_IF_ERROR(cSize, "ZSTD_compressSubBlock failed"); - if (cSize > 0 && cSize < decompressedSize) { - DEBUGLOG(5, "Committed the sub-block"); - assert(ip + decompressedSize <= iend); - ip += decompressedSize; - sp += seqCount; - lp += litSize; - op += cSize; - llCodePtr += seqCount; - mlCodePtr += seqCount; - ofCodePtr += seqCount; - litSize = 0; - seqCount = 0; - /* Entropy only needs to be written once */ - if (litEntropyWritten) { - writeLitEntropy = 0; - } - if (seqEntropyWritten) { - writeSeqEntropy = 0; - } + } /* if (nbSeqs > 0) */ + + /* write last block */ + DEBUGLOG(5, "Generate last sub-block: %u sequences remaining", (unsigned)(send - sp)); + { int litEntropyWritten = 0; + int seqEntropyWritten = 0; + size_t litSize = (size_t)(lend - lp); + size_t seqCount = (size_t)(send - sp); + const size_t decompressedSize = + ZSTD_seqDecompressedSize(seqStorePtr, sp, seqCount, litSize, 1); + size_t const cSize = ZSTD_compressSubBlock(&nextCBlock->entropy, entropyMetadata, + sp, seqCount, + lp, litSize, + llCodePtr, mlCodePtr, ofCodePtr, + cctxParams, + op, (size_t)(oend-op), + bmi2, writeLitEntropy, writeSeqEntropy, + &litEntropyWritten, &seqEntropyWritten, + lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_compressSubBlock failed"); + + /* update pointers, the nb of literals borrowed from next sequence must be preserved */ + if (cSize > 0 && cSize < decompressedSize) { + DEBUGLOG(5, "Last sub-block compressed %u bytes => %u bytes", + (unsigned)decompressedSize, (unsigned)cSize); + assert(ip + decompressedSize <= iend); + ip += decompressedSize; + lp += litSize; + op += cSize; + llCodePtr += seqCount; + mlCodePtr += seqCount; + ofCodePtr += seqCount; + /* Entropy only needs to be written once */ + if (litEntropyWritten) { + writeLitEntropy = 0; } + if (seqEntropyWritten) { + writeSeqEntropy = 0; + } + sp += seqCount; } - } while (!lastSequence); + } + + if (writeLitEntropy) { - DEBUGLOG(5, "ZSTD_compressSubBlock_multi has literal entropy tables unwritten"); + DEBUGLOG(5, "Literal entropy tables were never written"); ZSTD_memcpy(&nextCBlock->entropy.huf, &prevCBlock->entropy.huf, sizeof(prevCBlock->entropy.huf)); } if (writeSeqEntropy && ZSTD_needSequenceEntropyTables(&entropyMetadata->fseMetadata)) { /* If we haven't written our entropy tables, then we've violated our contract and * must emit an uncompressed block. */ - DEBUGLOG(5, "ZSTD_compressSubBlock_multi has sequence entropy tables unwritten"); + DEBUGLOG(5, "Sequence entropy tables were never written => cancel, emit an uncompressed block"); return 0; } + if (ip < iend) { - size_t const cSize = ZSTD_noCompressBlock(op, oend - op, ip, iend - ip, lastBlock); - DEBUGLOG(5, "ZSTD_compressSubBlock_multi last sub-block uncompressed, %zu bytes", (size_t)(iend - ip)); + /* some data left : last part of the block sent uncompressed */ + size_t const rSize = (size_t)((iend - ip)); + size_t const cSize = ZSTD_noCompressBlock(op, (size_t)(oend - op), ip, rSize, lastBlock); + DEBUGLOG(5, "Generate last uncompressed sub-block of %u bytes", (unsigned)(rSize)); FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed"); assert(cSize != 0); op += cSize; /* We have to regenerate the repcodes because we've skipped some sequences */ if (sp < send) { - seqDef const* seq; + const seqDef* seq; repcodes_t rep; ZSTD_memcpy(&rep, prevCBlock->rep, sizeof(rep)); for (seq = sstart; seq < sp; ++seq) { @@ -548,14 +656,17 @@ static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr, ZSTD_memcpy(nextCBlock->rep, &rep, sizeof(rep)); } } - DEBUGLOG(5, "ZSTD_compressSubBlock_multi compressed"); - return op-ostart; + + DEBUGLOG(5, "ZSTD_compressSubBlock_multi compressed all subBlocks: total compressed size = %u", + (unsigned)(op-ostart)); + return (size_t)(op-ostart); } size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, - void const* src, size_t srcSize, - unsigned lastBlock) { + const void* src, size_t srcSize, + unsigned lastBlock) +{ ZSTD_entropyCTablesMetadata_t entropyMetadata; FORWARD_IF_ERROR(ZSTD_buildBlockEntropyStats(&zc->seqStore, diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_compress_superblock.h b/src/dependencies/zstd-1.5.6/lib/compress/zstd_compress_superblock.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_compress_superblock.h rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_compress_superblock.h diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_cwksp.h b/src/dependencies/zstd-1.5.6/lib/compress/zstd_cwksp.h similarity index 77% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_cwksp.h rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_cwksp.h index 9767669..3eddbd3 100644 --- a/src/dependencies/zstd-1.5.4/lib/compress/zstd_cwksp.h +++ b/src/dependencies/zstd-1.5.6/lib/compress/zstd_cwksp.h @@ -14,7 +14,9 @@ /*-************************************* * Dependencies ***************************************/ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customFree */ #include "../common/zstd_internal.h" +#include "../common/portability_macros.h" #if defined (__cplusplus) extern "C" { @@ -44,8 +46,9 @@ extern "C" { ***************************************/ typedef enum { ZSTD_cwksp_alloc_objects, - ZSTD_cwksp_alloc_buffers, - ZSTD_cwksp_alloc_aligned + ZSTD_cwksp_alloc_aligned_init_once, + ZSTD_cwksp_alloc_aligned, + ZSTD_cwksp_alloc_buffers } ZSTD_cwksp_alloc_phase_e; /** @@ -98,8 +101,8 @@ typedef enum { * * Workspace Layout: * - * [ ... workspace ... ] - * [objects][tables ... ->] free space [<- ... aligned][<- ... buffers] + * [ ... workspace ... ] + * [objects][tables ->] free space [<- buffers][<- aligned][<- init once] * * The various objects that live in the workspace are divided into the * following categories, and are allocated separately: @@ -123,9 +126,18 @@ typedef enum { * uint32_t arrays, all of whose values are between 0 and (nextSrc - base). * Their sizes depend on the cparams. These tables are 64-byte aligned. * - * - Aligned: these buffers are used for various purposes that require 4 byte - * alignment, but don't require any initialization before they're used. These - * buffers are each aligned to 64 bytes. + * - Init once: these buffers require to be initialized at least once before + * use. They should be used when we want to skip memory initialization + * while not triggering memory checkers (like Valgrind) when reading from + * from this memory without writing to it first. + * These buffers should be used carefully as they might contain data + * from previous compressions. + * Buffers are aligned to 64 bytes. + * + * - Aligned: these buffers don't require any initialization before they're + * used. The user of the buffer should make sure they write into a buffer + * location before reading from it. + * Buffers are aligned to 64 bytes. * * - Buffers: these buffers are used for various purposes that don't require * any alignment or initialization before they're used. This means they can @@ -137,8 +149,9 @@ typedef enum { * correctly packed into the workspace buffer. That order is: * * 1. Objects - * 2. Buffers - * 3. Aligned/Tables + * 2. Init once / Tables + * 3. Aligned / Tables + * 4. Buffers / Tables * * Attempts to reserve objects of different types out of order will fail. */ @@ -150,6 +163,7 @@ typedef struct { void* tableEnd; void* tableValidEnd; void* allocStart; + void* initOnceStart; BYTE allocFailed; int workspaceOversizedDuration; @@ -162,6 +176,7 @@ typedef struct { ***************************************/ MEM_STATIC size_t ZSTD_cwksp_available_space(ZSTD_cwksp* ws); +MEM_STATIC void* ZSTD_cwksp_initialAllocStart(ZSTD_cwksp* ws); MEM_STATIC void ZSTD_cwksp_assert_internal_consistency(ZSTD_cwksp* ws) { (void)ws; @@ -171,6 +186,21 @@ MEM_STATIC void ZSTD_cwksp_assert_internal_consistency(ZSTD_cwksp* ws) { assert(ws->tableEnd <= ws->allocStart); assert(ws->tableValidEnd <= ws->allocStart); assert(ws->allocStart <= ws->workspaceEnd); + assert(ws->initOnceStart <= ZSTD_cwksp_initialAllocStart(ws)); + assert(ws->workspace <= ws->initOnceStart); +#if ZSTD_MEMORY_SANITIZER + { + intptr_t const offset = __msan_test_shadow(ws->initOnceStart, + (U8*)ZSTD_cwksp_initialAllocStart(ws) - (U8*)ws->initOnceStart); + (void)offset; +#if defined(ZSTD_MSAN_PRINT) + if(offset!=-1) { + __msan_print_shadow((U8*)ws->initOnceStart + offset - 8, 32); + } +#endif + assert(offset==-1); + }; +#endif } /** @@ -217,14 +247,10 @@ MEM_STATIC size_t ZSTD_cwksp_aligned_alloc_size(size_t size) { * for internal purposes (currently only alignment). */ MEM_STATIC size_t ZSTD_cwksp_slack_space_required(void) { - /* For alignment, the wksp will always allocate an additional n_1=[1, 64] bytes - * to align the beginning of tables section, as well as another n_2=[0, 63] bytes - * to align the beginning of the aligned section. - * - * n_1 + n_2 == 64 bytes if the cwksp is freshly allocated, due to tables and - * aligneds being sized in multiples of 64 bytes. + /* For alignment, the wksp will always allocate an additional 2*ZSTD_CWKSP_ALIGNMENT_BYTES + * bytes to align the beginning of tables section and end of buffers; */ - size_t const slackSpace = ZSTD_CWKSP_ALIGNMENT_BYTES; + size_t const slackSpace = ZSTD_CWKSP_ALIGNMENT_BYTES * 2; return slackSpace; } @@ -237,10 +263,18 @@ MEM_STATIC size_t ZSTD_cwksp_bytes_to_align_ptr(void* ptr, const size_t alignByt size_t const alignBytesMask = alignBytes - 1; size_t const bytes = (alignBytes - ((size_t)ptr & (alignBytesMask))) & alignBytesMask; assert((alignBytes & alignBytesMask) == 0); - assert(bytes != ZSTD_CWKSP_ALIGNMENT_BYTES); + assert(bytes < alignBytes); return bytes; } +/** + * Returns the initial value for allocStart which is used to determine the position from + * which we can allocate from the end of the workspace. + */ +MEM_STATIC void* ZSTD_cwksp_initialAllocStart(ZSTD_cwksp* ws) { + return (void*)((size_t)ws->workspaceEnd & ~(ZSTD_CWKSP_ALIGNMENT_BYTES-1)); +} + /** * Internal function. Do not use directly. * Reserves the given number of bytes within the aligned/buffer segment of the wksp, @@ -281,27 +315,16 @@ ZSTD_cwksp_internal_advance_phase(ZSTD_cwksp* ws, ZSTD_cwksp_alloc_phase_e phase { assert(phase >= ws->phase); if (phase > ws->phase) { - /* Going from allocating objects to allocating buffers */ - if (ws->phase < ZSTD_cwksp_alloc_buffers && - phase >= ZSTD_cwksp_alloc_buffers) { + /* Going from allocating objects to allocating initOnce / tables */ + if (ws->phase < ZSTD_cwksp_alloc_aligned_init_once && + phase >= ZSTD_cwksp_alloc_aligned_init_once) { ws->tableValidEnd = ws->objectEnd; - } + ws->initOnceStart = ZSTD_cwksp_initialAllocStart(ws); - /* Going from allocating buffers to allocating aligneds/tables */ - if (ws->phase < ZSTD_cwksp_alloc_aligned && - phase >= ZSTD_cwksp_alloc_aligned) { - { /* Align the start of the "aligned" to 64 bytes. Use [1, 64] bytes. */ - size_t const bytesToAlign = - ZSTD_CWKSP_ALIGNMENT_BYTES - ZSTD_cwksp_bytes_to_align_ptr(ws->allocStart, ZSTD_CWKSP_ALIGNMENT_BYTES); - DEBUGLOG(5, "reserving aligned alignment addtl space: %zu", bytesToAlign); - ZSTD_STATIC_ASSERT((ZSTD_CWKSP_ALIGNMENT_BYTES & (ZSTD_CWKSP_ALIGNMENT_BYTES - 1)) == 0); /* power of 2 */ - RETURN_ERROR_IF(!ZSTD_cwksp_reserve_internal_buffer_space(ws, bytesToAlign), - memory_allocation, "aligned phase - alignment initial allocation failed!"); - } { /* Align the start of the tables to 64 bytes. Use [0, 63] bytes */ - void* const alloc = ws->objectEnd; + void *const alloc = ws->objectEnd; size_t const bytesToAlign = ZSTD_cwksp_bytes_to_align_ptr(alloc, ZSTD_CWKSP_ALIGNMENT_BYTES); - void* const objectEnd = (BYTE*)alloc + bytesToAlign; + void *const objectEnd = (BYTE *) alloc + bytesToAlign; DEBUGLOG(5, "reserving table alignment addtl space: %zu", bytesToAlign); RETURN_ERROR_IF(objectEnd > ws->workspaceEnd, memory_allocation, "table phase - alignment initial allocation failed!"); @@ -309,7 +332,9 @@ ZSTD_cwksp_internal_advance_phase(ZSTD_cwksp* ws, ZSTD_cwksp_alloc_phase_e phase ws->tableEnd = objectEnd; /* table area starts being empty */ if (ws->tableValidEnd < ws->tableEnd) { ws->tableValidEnd = ws->tableEnd; - } } } + } + } + } ws->phase = phase; ZSTD_cwksp_assert_internal_consistency(ws); } @@ -321,7 +346,7 @@ ZSTD_cwksp_internal_advance_phase(ZSTD_cwksp* ws, ZSTD_cwksp_alloc_phase_e phase */ MEM_STATIC int ZSTD_cwksp_owns_buffer(const ZSTD_cwksp* ws, const void* ptr) { - return (ptr != NULL) && (ws->workspace <= ptr) && (ptr <= ws->workspaceEnd); + return (ptr != NULL) && (ws->workspace <= ptr) && (ptr < ws->workspaceEnd); } /** @@ -366,6 +391,36 @@ MEM_STATIC BYTE* ZSTD_cwksp_reserve_buffer(ZSTD_cwksp* ws, size_t bytes) return (BYTE*)ZSTD_cwksp_reserve_internal(ws, bytes, ZSTD_cwksp_alloc_buffers); } +/** + * Reserves and returns memory sized on and aligned on ZSTD_CWKSP_ALIGNMENT_BYTES (64 bytes). + * This memory has been initialized at least once in the past. + * This doesn't mean it has been initialized this time, and it might contain data from previous + * operations. + * The main usage is for algorithms that might need read access into uninitialized memory. + * The algorithm must maintain safety under these conditions and must make sure it doesn't + * leak any of the past data (directly or in side channels). + */ +MEM_STATIC void* ZSTD_cwksp_reserve_aligned_init_once(ZSTD_cwksp* ws, size_t bytes) +{ + size_t const alignedBytes = ZSTD_cwksp_align(bytes, ZSTD_CWKSP_ALIGNMENT_BYTES); + void* ptr = ZSTD_cwksp_reserve_internal(ws, alignedBytes, ZSTD_cwksp_alloc_aligned_init_once); + assert(((size_t)ptr & (ZSTD_CWKSP_ALIGNMENT_BYTES-1))== 0); + if(ptr && ptr < ws->initOnceStart) { + /* We assume the memory following the current allocation is either: + * 1. Not usable as initOnce memory (end of workspace) + * 2. Another initOnce buffer that has been allocated before (and so was previously memset) + * 3. An ASAN redzone, in which case we don't want to write on it + * For these reasons it should be fine to not explicitly zero every byte up to ws->initOnceStart. + * Note that we assume here that MSAN and ASAN cannot run in the same time. */ + ZSTD_memset(ptr, 0, MIN((size_t)((U8*)ws->initOnceStart - (U8*)ptr), alignedBytes)); + ws->initOnceStart = ptr; + } +#if ZSTD_MEMORY_SANITIZER + assert(__msan_test_shadow(ptr, bytes) == -1); +#endif + return ptr; +} + /** * Reserves and returns memory sized on and aligned on ZSTD_CWKSP_ALIGNMENT_BYTES (64 bytes). */ @@ -379,18 +434,22 @@ MEM_STATIC void* ZSTD_cwksp_reserve_aligned(ZSTD_cwksp* ws, size_t bytes) /** * Aligned on 64 bytes. These buffers have the special property that - * their values remain constrained, allowing us to re-use them without + * their values remain constrained, allowing us to reuse them without * memset()-ing them. */ MEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes) { - const ZSTD_cwksp_alloc_phase_e phase = ZSTD_cwksp_alloc_aligned; + const ZSTD_cwksp_alloc_phase_e phase = ZSTD_cwksp_alloc_aligned_init_once; void* alloc; void* end; void* top; - if (ZSTD_isError(ZSTD_cwksp_internal_advance_phase(ws, phase))) { - return NULL; + /* We can only start allocating tables after we are done reserving space for objects at the + * start of the workspace */ + if(ws->phase < phase) { + if (ZSTD_isError(ZSTD_cwksp_internal_advance_phase(ws, phase))) { + return NULL; + } } alloc = ws->tableEnd; end = (BYTE *)alloc + bytes; @@ -467,13 +526,21 @@ MEM_STATIC void ZSTD_cwksp_mark_tables_dirty(ZSTD_cwksp* ws) DEBUGLOG(4, "cwksp: ZSTD_cwksp_mark_tables_dirty"); #if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) - /* To validate that the table re-use logic is sound, and that we don't + /* To validate that the table reuse logic is sound, and that we don't * access table space that we haven't cleaned, we re-"poison" the table - * space every time we mark it dirty. */ + * space every time we mark it dirty. + * Since tableValidEnd space and initOnce space may overlap we don't poison + * the initOnce portion as it break its promise. This means that this poisoning + * check isn't always applied fully. */ { size_t size = (BYTE*)ws->tableValidEnd - (BYTE*)ws->objectEnd; assert(__msan_test_shadow(ws->objectEnd, size) == -1); - __msan_poison(ws->objectEnd, size); + if((BYTE*)ws->tableValidEnd < (BYTE*)ws->initOnceStart) { + __msan_poison(ws->objectEnd, size); + } else { + assert(ws->initOnceStart >= ws->objectEnd); + __msan_poison(ws->objectEnd, (BYTE*)ws->initOnceStart - (BYTE*)ws->objectEnd); + } } #endif @@ -536,13 +603,16 @@ MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) { DEBUGLOG(4, "cwksp: clearing!"); #if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) - /* To validate that the context re-use logic is sound, and that we don't + /* To validate that the context reuse logic is sound, and that we don't * access stuff that this compression hasn't initialized, we re-"poison" - * the workspace (or at least the non-static, non-table parts of it) - * every time we start a new compression. */ + * the workspace except for the areas in which we expect memory reuse + * without initialization (objects, valid tables area and init once + * memory). */ { - size_t size = (BYTE*)ws->workspaceEnd - (BYTE*)ws->tableValidEnd; - __msan_poison(ws->tableValidEnd, size); + if((BYTE*)ws->tableValidEnd < (BYTE*)ws->initOnceStart) { + size_t size = (BYTE*)ws->initOnceStart - (BYTE*)ws->tableValidEnd; + __msan_poison(ws->tableValidEnd, size); + } } #endif @@ -558,14 +628,23 @@ MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) { #endif ws->tableEnd = ws->objectEnd; - ws->allocStart = ws->workspaceEnd; + ws->allocStart = ZSTD_cwksp_initialAllocStart(ws); ws->allocFailed = 0; - if (ws->phase > ZSTD_cwksp_alloc_buffers) { - ws->phase = ZSTD_cwksp_alloc_buffers; + if (ws->phase > ZSTD_cwksp_alloc_aligned_init_once) { + ws->phase = ZSTD_cwksp_alloc_aligned_init_once; } ZSTD_cwksp_assert_internal_consistency(ws); } +MEM_STATIC size_t ZSTD_cwksp_sizeof(const ZSTD_cwksp* ws) { + return (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->workspace); +} + +MEM_STATIC size_t ZSTD_cwksp_used(const ZSTD_cwksp* ws) { + return (size_t)((BYTE*)ws->tableEnd - (BYTE*)ws->workspace) + + (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->allocStart); +} + /** * The provided workspace takes ownership of the buffer [start, start+size). * Any existing values in the workspace are ignored (the previously managed @@ -578,6 +657,7 @@ MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size, ZSTD_c ws->workspaceEnd = (BYTE*)start + size; ws->objectEnd = ws->workspace; ws->tableValidEnd = ws->objectEnd; + ws->initOnceStart = ZSTD_cwksp_initialAllocStart(ws); ws->phase = ZSTD_cwksp_alloc_objects; ws->isStatic = isStatic; ZSTD_cwksp_clear(ws); @@ -596,6 +676,11 @@ MEM_STATIC size_t ZSTD_cwksp_create(ZSTD_cwksp* ws, size_t size, ZSTD_customMem MEM_STATIC void ZSTD_cwksp_free(ZSTD_cwksp* ws, ZSTD_customMem customMem) { void *ptr = ws->workspace; DEBUGLOG(4, "cwksp: freeing workspace"); +#if ZSTD_MEMORY_SANITIZER && !defined(ZSTD_MSAN_DONT_POISON_WORKSPACE) + if (ptr != NULL && customMem.customFree != NULL) { + __msan_unpoison(ptr, ZSTD_cwksp_sizeof(ws)); + } +#endif ZSTD_memset(ws, 0, sizeof(ZSTD_cwksp)); ZSTD_customFree(ptr, customMem); } @@ -609,15 +694,6 @@ MEM_STATIC void ZSTD_cwksp_move(ZSTD_cwksp* dst, ZSTD_cwksp* src) { ZSTD_memset(src, 0, sizeof(ZSTD_cwksp)); } -MEM_STATIC size_t ZSTD_cwksp_sizeof(const ZSTD_cwksp* ws) { - return (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->workspace); -} - -MEM_STATIC size_t ZSTD_cwksp_used(const ZSTD_cwksp* ws) { - return (size_t)((BYTE*)ws->tableEnd - (BYTE*)ws->workspace) - + (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->allocStart); -} - MEM_STATIC int ZSTD_cwksp_reserve_failed(const ZSTD_cwksp* ws) { return ws->allocFailed; } @@ -630,17 +706,11 @@ MEM_STATIC int ZSTD_cwksp_reserve_failed(const ZSTD_cwksp* ws) { * Returns if the estimated space needed for a wksp is within an acceptable limit of the * actual amount of space used. */ -MEM_STATIC int ZSTD_cwksp_estimated_space_within_bounds(const ZSTD_cwksp* const ws, - size_t const estimatedSpace, int resizedWorkspace) { - if (resizedWorkspace) { - /* Resized/newly allocated wksp should have exact bounds */ - return ZSTD_cwksp_used(ws) == estimatedSpace; - } else { - /* Due to alignment, when reusing a workspace, we can actually consume 63 fewer or more bytes - * than estimatedSpace. See the comments in zstd_cwksp.h for details. - */ - return (ZSTD_cwksp_used(ws) >= estimatedSpace - 63) && (ZSTD_cwksp_used(ws) <= estimatedSpace + 63); - } +MEM_STATIC int ZSTD_cwksp_estimated_space_within_bounds(const ZSTD_cwksp *const ws, size_t const estimatedSpace) { + /* We have an alignment space between objects and tables between tables and buffers, so we can have up to twice + * the alignment bytes difference between estimation and actual usage */ + return (estimatedSpace - ZSTD_cwksp_slack_space_required()) <= ZSTD_cwksp_used(ws) && + ZSTD_cwksp_used(ws) <= estimatedSpace; } diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_double_fast.c b/src/dependencies/zstd-1.5.6/lib/compress/zstd_double_fast.c similarity index 98% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_double_fast.c rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_double_fast.c index 0ad88ff..a4e9c50 100644 --- a/src/dependencies/zstd-1.5.4/lib/compress/zstd_double_fast.c +++ b/src/dependencies/zstd-1.5.6/lib/compress/zstd_double_fast.c @@ -11,7 +11,11 @@ #include "zstd_compress_internal.h" #include "zstd_double_fast.h" -static void ZSTD_fillDoubleHashTableForCDict(ZSTD_matchState_t* ms, +#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_fillDoubleHashTableForCDict(ZSTD_matchState_t* ms, void const* end, ZSTD_dictTableLoadMethod_e dtlm) { const ZSTD_compressionParameters* const cParams = &ms->cParams; @@ -47,7 +51,9 @@ static void ZSTD_fillDoubleHashTableForCDict(ZSTD_matchState_t* ms, } } } -static void ZSTD_fillDoubleHashTableForCCtx(ZSTD_matchState_t* ms, +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_fillDoubleHashTableForCCtx(ZSTD_matchState_t* ms, void const* end, ZSTD_dictTableLoadMethod_e dtlm) { const ZSTD_compressionParameters* const cParams = &ms->cParams; @@ -95,6 +101,7 @@ void ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms, FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR size_t ZSTD_compressBlock_doubleFast_noDict_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize, U32 const mls /* template */) @@ -305,6 +312,7 @@ _match_stored: FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR size_t ZSTD_compressBlock_doubleFast_dictMatchState_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize, @@ -348,8 +356,8 @@ size_t ZSTD_compressBlock_doubleFast_dictMatchState_generic( if (ms->prefetchCDictTables) { size_t const hashTableBytes = (((size_t)1) << dictCParams->hashLog) * sizeof(U32); size_t const chainTableBytes = (((size_t)1) << dictCParams->chainLog) * sizeof(U32); - PREFETCH_AREA(dictHashLong, hashTableBytes) - PREFETCH_AREA(dictHashSmall, chainTableBytes) + PREFETCH_AREA(dictHashLong, hashTableBytes); + PREFETCH_AREA(dictHashSmall, chainTableBytes); } /* init */ @@ -589,7 +597,9 @@ size_t ZSTD_compressBlock_doubleFast_dictMatchState( } -static size_t ZSTD_compressBlock_doubleFast_extDict_generic( +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_doubleFast_extDict_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize, U32 const mls /* template */) @@ -756,3 +766,5 @@ size_t ZSTD_compressBlock_doubleFast_extDict( return ZSTD_compressBlock_doubleFast_extDict_7(ms, seqStore, rep, src, srcSize); } } + +#endif /* ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR */ diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_double_fast.h b/src/dependencies/zstd-1.5.6/lib/compress/zstd_double_fast.h similarity index 72% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_double_fast.h rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_double_fast.h index 6f0047c..ce6ed8c 100644 --- a/src/dependencies/zstd-1.5.4/lib/compress/zstd_double_fast.h +++ b/src/dependencies/zstd-1.5.6/lib/compress/zstd_double_fast.h @@ -18,9 +18,12 @@ extern "C" { #include "../common/mem.h" /* U32 */ #include "zstd_compress_internal.h" /* ZSTD_CCtx, size_t */ +#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + void ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms, void const* end, ZSTD_dictTableLoadMethod_e dtlm, ZSTD_tableFillPurpose_e tfp); + size_t ZSTD_compressBlock_doubleFast( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); @@ -31,6 +34,14 @@ size_t ZSTD_compressBlock_doubleFast_extDict( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST ZSTD_compressBlock_doubleFast +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST_DICTMATCHSTATE ZSTD_compressBlock_doubleFast_dictMatchState +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST_EXTDICT ZSTD_compressBlock_doubleFast_extDict +#else +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST NULL +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST_EXTDICT NULL +#endif /* ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR */ #if defined (__cplusplus) } diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_fast.c b/src/dependencies/zstd-1.5.6/lib/compress/zstd_fast.c similarity index 98% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_fast.c rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_fast.c index 5f2c6a2..6c4554c 100644 --- a/src/dependencies/zstd-1.5.4/lib/compress/zstd_fast.c +++ b/src/dependencies/zstd-1.5.6/lib/compress/zstd_fast.c @@ -11,7 +11,9 @@ #include "zstd_compress_internal.h" /* ZSTD_hashPtr, ZSTD_count, ZSTD_storeSeq */ #include "zstd_fast.h" -static void ZSTD_fillHashTableForCDict(ZSTD_matchState_t* ms, +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_fillHashTableForCDict(ZSTD_matchState_t* ms, const void* const end, ZSTD_dictTableLoadMethod_e dtlm) { @@ -46,7 +48,9 @@ static void ZSTD_fillHashTableForCDict(ZSTD_matchState_t* ms, } } } } } -static void ZSTD_fillHashTableForCCtx(ZSTD_matchState_t* ms, +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_fillHashTableForCCtx(ZSTD_matchState_t* ms, const void* const end, ZSTD_dictTableLoadMethod_e dtlm) { @@ -139,8 +143,9 @@ void ZSTD_fillHashTable(ZSTD_matchState_t* ms, * * This is also the work we do at the beginning to enter the loop initially. */ -FORCE_INLINE_TEMPLATE size_t -ZSTD_compressBlock_fast_noDict_generic( +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_fast_noDict_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize, U32 const mls, U32 const hasStep) @@ -456,6 +461,7 @@ size_t ZSTD_compressBlock_fast( } FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR size_t ZSTD_compressBlock_fast_dictMatchState_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize, U32 const mls, U32 const hasStep) @@ -502,7 +508,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic( if (ms->prefetchCDictTables) { size_t const hashTableBytes = (((size_t)1) << dictCParams->hashLog) * sizeof(U32); - PREFETCH_AREA(dictHashTable, hashTableBytes) + PREFETCH_AREA(dictHashTable, hashTableBytes); } /* init */ @@ -681,7 +687,9 @@ size_t ZSTD_compressBlock_fast_dictMatchState( } -static size_t ZSTD_compressBlock_fast_extDict_generic( +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_fast_extDict_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize, U32 const mls, U32 const hasStep) { diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_fast.h b/src/dependencies/zstd-1.5.6/lib/compress/zstd_fast.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_fast.h rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_fast.h diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_lazy.c b/src/dependencies/zstd-1.5.6/lib/compress/zstd_lazy.c similarity index 92% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_lazy.c rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_lazy.c index a247342..67dd55f 100644 --- a/src/dependencies/zstd-1.5.4/lib/compress/zstd_lazy.c +++ b/src/dependencies/zstd-1.5.6/lib/compress/zstd_lazy.c @@ -12,13 +12,21 @@ #include "zstd_lazy.h" #include "../common/bits.h" /* ZSTD_countTrailingZeros64 */ +#if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) + +#define kLazySkippingStep 8 + /*-************************************* * Binary Tree search ***************************************/ -static void -ZSTD_updateDUBT(ZSTD_matchState_t* ms, +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_updateDUBT(ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* iend, U32 mls) { @@ -61,8 +69,9 @@ ZSTD_updateDUBT(ZSTD_matchState_t* ms, * sort one already inserted but unsorted position * assumption : curr >= btlow == (curr - btmask) * doesn't fail */ -static void -ZSTD_insertDUBT1(const ZSTD_matchState_t* ms, +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_insertDUBT1(const ZSTD_matchState_t* ms, U32 curr, const BYTE* inputEnd, U32 nbCompares, U32 btLow, const ZSTD_dictMode_e dictMode) @@ -150,8 +159,9 @@ ZSTD_insertDUBT1(const ZSTD_matchState_t* ms, } -static size_t -ZSTD_DUBT_findBetterDictMatch ( +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_DUBT_findBetterDictMatch ( const ZSTD_matchState_t* ms, const BYTE* const ip, const BYTE* const iend, size_t* offsetPtr, @@ -228,8 +238,9 @@ ZSTD_DUBT_findBetterDictMatch ( } -static size_t -ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms, +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms, const BYTE* const ip, const BYTE* const iend, size_t* offBasePtr, U32 const mls, @@ -379,8 +390,9 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms, /** ZSTD_BtFindBestMatch() : Tree updater, providing best match */ -FORCE_INLINE_TEMPLATE size_t -ZSTD_BtFindBestMatch( ZSTD_matchState_t* ms, +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_BtFindBestMatch( ZSTD_matchState_t* ms, const BYTE* const ip, const BYTE* const iLimit, size_t* offBasePtr, const U32 mls /* template */, @@ -615,10 +627,12 @@ size_t ZSTD_dedicatedDictSearch_lazy_search(size_t* offsetPtr, size_t ml, U32 nb /* Update chains up to ip (excluded) Assumption : always within prefix (i.e. not within extDict) */ -FORCE_INLINE_TEMPLATE U32 ZSTD_insertAndFindFirstIndex_internal( +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_insertAndFindFirstIndex_internal( ZSTD_matchState_t* ms, const ZSTD_compressionParameters* const cParams, - const BYTE* ip, U32 const mls) + const BYTE* ip, U32 const mls, U32 const lazySkipping) { U32* const hashTable = ms->hashTable; const U32 hashLog = cParams->hashLog; @@ -633,6 +647,9 @@ FORCE_INLINE_TEMPLATE U32 ZSTD_insertAndFindFirstIndex_internal( NEXT_IN_CHAIN(idx, chainMask) = hashTable[h]; hashTable[h] = idx; idx++; + /* Stop inserting every position when in the lazy skipping mode. */ + if (lazySkipping) + break; } ms->nextToUpdate = target; @@ -641,11 +658,12 @@ FORCE_INLINE_TEMPLATE U32 ZSTD_insertAndFindFirstIndex_internal( U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip) { const ZSTD_compressionParameters* const cParams = &ms->cParams; - return ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, ms->cParams.minMatch); + return ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, ms->cParams.minMatch, /* lazySkipping*/ 0); } /* inlining is important to hardwire a hot branch (template emulation) */ FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR size_t ZSTD_HcFindBestMatch( ZSTD_matchState_t* ms, const BYTE* const ip, const BYTE* const iLimit, @@ -685,7 +703,7 @@ size_t ZSTD_HcFindBestMatch( } /* HC4 match finder */ - matchIndex = ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, mls); + matchIndex = ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, mls, ms->lazySkipping); for ( ; (matchIndex>=lowLimit) & (nbAttempts>0) ; nbAttempts--) { size_t currentMl=0; @@ -758,7 +776,6 @@ size_t ZSTD_HcFindBestMatch( * (SIMD) Row-based matchfinder ***********************************/ /* Constants for row-based hash */ -#define ZSTD_ROW_HASH_TAG_OFFSET 16 /* byte offset of hashes in the match state's tagTable from the beginning of a row */ #define ZSTD_ROW_HASH_TAG_MASK ((1u << ZSTD_ROW_HASH_TAG_BITS) - 1) #define ZSTD_ROW_HASH_MAX_ENTRIES 64 /* absolute maximum number of entries per row, for all configurations */ @@ -774,39 +791,15 @@ MEM_STATIC U32 ZSTD_VecMask_next(ZSTD_VecMask val) { return ZSTD_countTrailingZeros64(val); } -/* ZSTD_rotateRight_*(): - * Rotates a bitfield to the right by "count" bits. - * https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts - */ -FORCE_INLINE_TEMPLATE -U64 ZSTD_rotateRight_U64(U64 const value, U32 count) { - assert(count < 64); - count &= 0x3F; /* for fickle pattern recognition */ - return (value >> count) | (U64)(value << ((0U - count) & 0x3F)); -} - -FORCE_INLINE_TEMPLATE -U32 ZSTD_rotateRight_U32(U32 const value, U32 count) { - assert(count < 32); - count &= 0x1F; /* for fickle pattern recognition */ - return (value >> count) | (U32)(value << ((0U - count) & 0x1F)); -} - -FORCE_INLINE_TEMPLATE -U16 ZSTD_rotateRight_U16(U16 const value, U32 count) { - assert(count < 16); - count &= 0x0F; /* for fickle pattern recognition */ - return (value >> count) | (U16)(value << ((0U - count) & 0x0F)); -} - /* ZSTD_row_nextIndex(): * Returns the next index to insert at within a tagTable row, and updates the "head" - * value to reflect the update. Essentially cycles backwards from [0, {entries per row}) + * value to reflect the update. Essentially cycles backwards from [1, {entries per row}) */ FORCE_INLINE_TEMPLATE U32 ZSTD_row_nextIndex(BYTE* const tagRow, U32 const rowMask) { - U32 const next = (*tagRow - 1) & rowMask; - *tagRow = (BYTE)next; - return next; + U32 next = (*tagRow-1) & rowMask; + next += (next == 0) ? rowMask : 0; /* skip first position */ + *tagRow = (BYTE)next; + return next; } /* ZSTD_isAligned(): @@ -820,7 +813,7 @@ MEM_STATIC int ZSTD_isAligned(void const* ptr, size_t align) { /* ZSTD_row_prefetch(): * Performs prefetching for the hashTable and tagTable at a given row. */ -FORCE_INLINE_TEMPLATE void ZSTD_row_prefetch(U32 const* hashTable, U16 const* tagTable, U32 const relRow, U32 const rowLog) { +FORCE_INLINE_TEMPLATE void ZSTD_row_prefetch(U32 const* hashTable, BYTE const* tagTable, U32 const relRow, U32 const rowLog) { PREFETCH_L1(hashTable + relRow); if (rowLog >= 5) { PREFETCH_L1(hashTable + relRow + 16); @@ -839,18 +832,20 @@ FORCE_INLINE_TEMPLATE void ZSTD_row_prefetch(U32 const* hashTable, U16 const* ta * Fill up the hash cache starting at idx, prefetching up to ZSTD_ROW_HASH_CACHE_SIZE entries, * but not beyond iLimit. */ -FORCE_INLINE_TEMPLATE void ZSTD_row_fillHashCache(ZSTD_matchState_t* ms, const BYTE* base, +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_row_fillHashCache(ZSTD_matchState_t* ms, const BYTE* base, U32 const rowLog, U32 const mls, U32 idx, const BYTE* const iLimit) { U32 const* const hashTable = ms->hashTable; - U16 const* const tagTable = ms->tagTable; + BYTE const* const tagTable = ms->tagTable; U32 const hashLog = ms->rowHashLog; U32 const maxElemsToPrefetch = (base + idx) > iLimit ? 0 : (U32)(iLimit - (base + idx) + 1); U32 const lim = idx + MIN(ZSTD_ROW_HASH_CACHE_SIZE, maxElemsToPrefetch); for (; idx < lim; ++idx) { - U32 const hash = (U32)ZSTD_hashPtr(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls); + U32 const hash = (U32)ZSTD_hashPtrSalted(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, ms->hashSalt); U32 const row = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; ZSTD_row_prefetch(hashTable, tagTable, row, rowLog); ms->hashCache[idx & ZSTD_ROW_HASH_CACHE_MASK] = hash; @@ -865,12 +860,15 @@ FORCE_INLINE_TEMPLATE void ZSTD_row_fillHashCache(ZSTD_matchState_t* ms, const B * Returns the hash of base + idx, and replaces the hash in the hash cache with the byte at * base + idx + ZSTD_ROW_HASH_CACHE_SIZE. Also prefetches the appropriate rows from hashTable and tagTable. */ -FORCE_INLINE_TEMPLATE U32 ZSTD_row_nextCachedHash(U32* cache, U32 const* hashTable, - U16 const* tagTable, BYTE const* base, +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_row_nextCachedHash(U32* cache, U32 const* hashTable, + BYTE const* tagTable, BYTE const* base, U32 idx, U32 const hashLog, - U32 const rowLog, U32 const mls) + U32 const rowLog, U32 const mls, + U64 const hashSalt) { - U32 const newHash = (U32)ZSTD_hashPtr(base+idx+ZSTD_ROW_HASH_CACHE_SIZE, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls); + U32 const newHash = (U32)ZSTD_hashPtrSalted(base+idx+ZSTD_ROW_HASH_CACHE_SIZE, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, hashSalt); U32 const row = (newHash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; ZSTD_row_prefetch(hashTable, tagTable, row, rowLog); { U32 const hash = cache[idx & ZSTD_ROW_HASH_CACHE_MASK]; @@ -882,28 +880,29 @@ FORCE_INLINE_TEMPLATE U32 ZSTD_row_nextCachedHash(U32* cache, U32 const* hashTab /* ZSTD_row_update_internalImpl(): * Updates the hash table with positions starting from updateStartIdx until updateEndIdx. */ -FORCE_INLINE_TEMPLATE void ZSTD_row_update_internalImpl(ZSTD_matchState_t* ms, - U32 updateStartIdx, U32 const updateEndIdx, - U32 const mls, U32 const rowLog, - U32 const rowMask, U32 const useCache) +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_row_update_internalImpl(ZSTD_matchState_t* ms, + U32 updateStartIdx, U32 const updateEndIdx, + U32 const mls, U32 const rowLog, + U32 const rowMask, U32 const useCache) { U32* const hashTable = ms->hashTable; - U16* const tagTable = ms->tagTable; + BYTE* const tagTable = ms->tagTable; U32 const hashLog = ms->rowHashLog; const BYTE* const base = ms->window.base; DEBUGLOG(6, "ZSTD_row_update_internalImpl(): updateStartIdx=%u, updateEndIdx=%u", updateStartIdx, updateEndIdx); for (; updateStartIdx < updateEndIdx; ++updateStartIdx) { - U32 const hash = useCache ? ZSTD_row_nextCachedHash(ms->hashCache, hashTable, tagTable, base, updateStartIdx, hashLog, rowLog, mls) - : (U32)ZSTD_hashPtr(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls); + U32 const hash = useCache ? ZSTD_row_nextCachedHash(ms->hashCache, hashTable, tagTable, base, updateStartIdx, hashLog, rowLog, mls, ms->hashSalt) + : (U32)ZSTD_hashPtrSalted(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, ms->hashSalt); U32 const relRow = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; U32* const row = hashTable + relRow; - BYTE* tagRow = (BYTE*)(tagTable + relRow); /* Though tagTable is laid out as a table of U16, each tag is only 1 byte. - Explicit cast allows us to get exact desired position within each row */ + BYTE* tagRow = tagTable + relRow; U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask); - assert(hash == ZSTD_hashPtr(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls)); - ((BYTE*)tagRow)[pos + ZSTD_ROW_HASH_TAG_OFFSET] = hash & ZSTD_ROW_HASH_TAG_MASK; + assert(hash == ZSTD_hashPtrSalted(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, ms->hashSalt)); + tagRow[pos] = hash & ZSTD_ROW_HASH_TAG_MASK; row[pos] = updateStartIdx; } } @@ -912,9 +911,11 @@ FORCE_INLINE_TEMPLATE void ZSTD_row_update_internalImpl(ZSTD_matchState_t* ms, * Inserts the byte at ip into the appropriate position in the hash table, and updates ms->nextToUpdate. * Skips sections of long matches as is necessary. */ -FORCE_INLINE_TEMPLATE void ZSTD_row_update_internal(ZSTD_matchState_t* ms, const BYTE* ip, - U32 const mls, U32 const rowLog, - U32 const rowMask, U32 const useCache) +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_row_update_internal(ZSTD_matchState_t* ms, const BYTE* ip, + U32 const mls, U32 const rowLog, + U32 const rowMask, U32 const useCache) { U32 idx = ms->nextToUpdate; const BYTE* const base = ms->window.base; @@ -1059,7 +1060,7 @@ ZSTD_row_getNEONMask(const U32 rowEntries, const BYTE* const src, const BYTE tag FORCE_INLINE_TEMPLATE ZSTD_VecMask ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, const U32 headGrouped, const U32 rowEntries) { - const BYTE* const src = tagRow + ZSTD_ROW_HASH_TAG_OFFSET; + const BYTE* const src = tagRow; assert((rowEntries == 16) || (rowEntries == 32) || rowEntries == 64); assert(rowEntries <= ZSTD_ROW_HASH_MAX_ENTRIES); assert(ZSTD_row_matchMaskGroupWidth(rowEntries) * rowEntries <= sizeof(ZSTD_VecMask) * 8); @@ -1122,20 +1123,21 @@ ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, const U32 headGr /* The high-level approach of the SIMD row based match finder is as follows: * - Figure out where to insert the new entry: - * - Generate a hash from a byte along with an additional 1-byte "short hash". The additional byte is our "tag" - * - The hashTable is effectively split into groups or "rows" of 16 or 32 entries of U32, and the hash determines + * - Generate a hash for current input posistion and split it into a one byte of tag and `rowHashLog` bits of index. + * - The hash is salted by a value that changes on every contex reset, so when the same table is used + * we will avoid collisions that would otherwise slow us down by intorducing phantom matches. + * - The hashTable is effectively split into groups or "rows" of 15 or 31 entries of U32, and the index determines * which row to insert into. - * - Determine the correct position within the row to insert the entry into. Each row of 16 or 32 can - * be considered as a circular buffer with a "head" index that resides in the tagTable. - * - Also insert the "tag" into the equivalent row and position in the tagTable. - * - Note: The tagTable has 17 or 33 1-byte entries per row, due to 16 or 32 tags, and 1 "head" entry. - * The 17 or 33 entry rows are spaced out to occur every 32 or 64 bytes, respectively, - * for alignment/performance reasons, leaving some bytes unused. - * - Use SIMD to efficiently compare the tags in the tagTable to the 1-byte "short hash" and + * - Determine the correct position within the row to insert the entry into. Each row of 15 or 31 can + * be considered as a circular buffer with a "head" index that resides in the tagTable (overall 16 or 32 bytes + * per row). + * - Use SIMD to efficiently compare the tags in the tagTable to the 1-byte tag calculated for the position and * generate a bitfield that we can cycle through to check the collisions in the hash table. * - Pick the longest match. + * - Insert the tag into the equivalent row and position in the tagTable. */ FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR size_t ZSTD_RowFindBestMatch( ZSTD_matchState_t* ms, const BYTE* const ip, const BYTE* const iLimit, @@ -1144,7 +1146,7 @@ size_t ZSTD_RowFindBestMatch( const U32 rowLog) { U32* const hashTable = ms->hashTable; - U16* const tagTable = ms->tagTable; + BYTE* const tagTable = ms->tagTable; U32* const hashCache = ms->hashCache; const U32 hashLog = ms->rowHashLog; const ZSTD_compressionParameters* const cParams = &ms->cParams; @@ -1163,8 +1165,10 @@ size_t ZSTD_RowFindBestMatch( const U32 rowMask = rowEntries - 1; const U32 cappedSearchLog = MIN(cParams->searchLog, rowLog); /* nb of searches is capped at nb entries per row */ const U32 groupWidth = ZSTD_row_matchMaskGroupWidth(rowEntries); + const U64 hashSalt = ms->hashSalt; U32 nbAttempts = 1U << cappedSearchLog; size_t ml=4-1; + U32 hash; /* DMS/DDS variables that may be referenced laster */ const ZSTD_matchState_t* const dms = ms->dictMatchState; @@ -1188,7 +1192,7 @@ size_t ZSTD_RowFindBestMatch( if (dictMode == ZSTD_dictMatchState) { /* Prefetch DMS rows */ U32* const dmsHashTable = dms->hashTable; - U16* const dmsTagTable = dms->tagTable; + BYTE* const dmsTagTable = dms->tagTable; U32 const dmsHash = (U32)ZSTD_hashPtr(ip, dms->rowHashLog + ZSTD_ROW_HASH_TAG_BITS, mls); U32 const dmsRelRow = (dmsHash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; dmsTag = dmsHash & ZSTD_ROW_HASH_TAG_MASK; @@ -1198,9 +1202,19 @@ size_t ZSTD_RowFindBestMatch( } /* Update the hashTable and tagTable up to (but not including) ip */ - ZSTD_row_update_internal(ms, ip, mls, rowLog, rowMask, 1 /* useCache */); + if (!ms->lazySkipping) { + ZSTD_row_update_internal(ms, ip, mls, rowLog, rowMask, 1 /* useCache */); + hash = ZSTD_row_nextCachedHash(hashCache, hashTable, tagTable, base, curr, hashLog, rowLog, mls, hashSalt); + } else { + /* Stop inserting every position when in the lazy skipping mode. + * The hash cache is also not kept up to date in this mode. + */ + hash = (U32)ZSTD_hashPtrSalted(ip, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, hashSalt); + ms->nextToUpdate = curr; + } + ms->hashSaltEntropy += hash; /* collect salt entropy */ + { /* Get the hash for ip, compute the appropriate row */ - U32 const hash = ZSTD_row_nextCachedHash(hashCache, hashTable, tagTable, base, curr, hashLog, rowLog, mls); U32 const relRow = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; U32 const tag = hash & ZSTD_ROW_HASH_TAG_MASK; U32* const row = hashTable + relRow; @@ -1212,9 +1226,10 @@ size_t ZSTD_RowFindBestMatch( ZSTD_VecMask matches = ZSTD_row_getMatchMask(tagRow, (BYTE)tag, headGrouped, rowEntries); /* Cycle through the matches and prefetch */ - for (; (matches > 0) && (nbAttempts > 0); --nbAttempts, matches &= (matches - 1)) { + for (; (matches > 0) && (nbAttempts > 0); matches &= (matches - 1)) { U32 const matchPos = ((headGrouped + ZSTD_VecMask_next(matches)) / groupWidth) & rowMask; U32 const matchIndex = row[matchPos]; + if(matchPos == 0) continue; assert(numMatches < rowEntries); if (matchIndex < lowLimit) break; @@ -1224,13 +1239,14 @@ size_t ZSTD_RowFindBestMatch( PREFETCH_L1(dictBase + matchIndex); } matchBuffer[numMatches++] = matchIndex; + --nbAttempts; } /* Speed opt: insert current byte into hashtable too. This allows us to avoid one iteration of the loop in ZSTD_row_update_internal() at the next search. */ { U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask); - tagRow[pos + ZSTD_ROW_HASH_TAG_OFFSET] = (BYTE)tag; + tagRow[pos] = (BYTE)tag; row[pos] = ms->nextToUpdate++; } @@ -1281,13 +1297,15 @@ size_t ZSTD_RowFindBestMatch( size_t currMatch = 0; ZSTD_VecMask matches = ZSTD_row_getMatchMask(dmsTagRow, (BYTE)dmsTag, headGrouped, rowEntries); - for (; (matches > 0) && (nbAttempts > 0); --nbAttempts, matches &= (matches - 1)) { + for (; (matches > 0) && (nbAttempts > 0); matches &= (matches - 1)) { U32 const matchPos = ((headGrouped + ZSTD_VecMask_next(matches)) / groupWidth) & rowMask; U32 const matchIndex = dmsRow[matchPos]; + if(matchPos == 0) continue; if (matchIndex < dmsLowestIndex) break; PREFETCH_L1(dmsBase + matchIndex); matchBuffer[numMatches++] = matchIndex; + --nbAttempts; } /* Return the longest match */ @@ -1493,8 +1511,9 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_searchMax( * Common parser - lazy strategy *********************************/ -FORCE_INLINE_TEMPLATE size_t -ZSTD_compressBlock_lazy_generic( +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_lazy_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize, @@ -1544,10 +1563,11 @@ ZSTD_compressBlock_lazy_generic( assert(offset_2 <= dictAndPrefixLength); } + /* Reset the lazy skipping state */ + ms->lazySkipping = 0; + if (searchMethod == search_rowHash) { - ZSTD_row_fillHashCache(ms, base, rowLog, - MIN(ms->cParams.minMatch, 6 /* mls caps out at 6 */), - ms->nextToUpdate, ilimit); + ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit); } /* Match Loop */ @@ -1591,7 +1611,16 @@ ZSTD_compressBlock_lazy_generic( } if (matchLength < 4) { - ip += ((ip-anchor) >> kSearchStrength) + 1; /* jump faster over incompressible sections */ + size_t const step = ((size_t)(ip-anchor) >> kSearchStrength) + 1; /* jump faster over incompressible sections */; + ip += step; + /* Enter the lazy skipping mode once we are skipping more than 8 bytes at a time. + * In this mode we stop inserting every position into our tables, and only insert + * positions that we search, which is one in step positions. + * The exact cutoff is flexible, I've just chosen a number that is reasonably high, + * so we minimize the compression ratio loss in "normal" scenarios. This mode gets + * triggered once we've gone 2KB without finding any matches. + */ + ms->lazySkipping = step > kLazySkippingStep; continue; } @@ -1695,6 +1724,13 @@ _storeSequence: ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offBase, matchLength); anchor = ip = start + matchLength; } + if (ms->lazySkipping) { + /* We've found a match, disable lazy skipping mode, and refill the hash cache. */ + if (searchMethod == search_rowHash) { + ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit); + } + ms->lazySkipping = 0; + } /* check immediate repcode */ if (isDxS) { @@ -1741,29 +1777,10 @@ _storeSequence: /* Return the last literals size */ return (size_t)(iend - anchor); } +#endif /* build exclusions */ -size_t ZSTD_compressBlock_btlazy2( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize) -{ - return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_noDict); -} - -size_t ZSTD_compressBlock_lazy2( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize) -{ - return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_noDict); -} - -size_t ZSTD_compressBlock_lazy( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize) -{ - return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_noDict); -} - +#ifndef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR size_t ZSTD_compressBlock_greedy( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize) @@ -1771,27 +1788,6 @@ size_t ZSTD_compressBlock_greedy( return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_noDict); } -size_t ZSTD_compressBlock_btlazy2_dictMatchState( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize) -{ - return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_dictMatchState); -} - -size_t ZSTD_compressBlock_lazy2_dictMatchState( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize) -{ - return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dictMatchState); -} - -size_t ZSTD_compressBlock_lazy_dictMatchState( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize) -{ - return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dictMatchState); -} - size_t ZSTD_compressBlock_greedy_dictMatchState( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize) @@ -1799,21 +1795,6 @@ size_t ZSTD_compressBlock_greedy_dictMatchState( return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dictMatchState); } - -size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize) -{ - return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dedicatedDictSearch); -} - -size_t ZSTD_compressBlock_lazy_dedicatedDictSearch( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize) -{ - return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dedicatedDictSearch); -} - size_t ZSTD_compressBlock_greedy_dedicatedDictSearch( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize) @@ -1821,21 +1802,6 @@ size_t ZSTD_compressBlock_greedy_dedicatedDictSearch( return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dedicatedDictSearch); } -/* Row-based matchfinder */ -size_t ZSTD_compressBlock_lazy2_row( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize) -{ - return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_noDict); -} - -size_t ZSTD_compressBlock_lazy_row( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize) -{ - return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_noDict); -} - size_t ZSTD_compressBlock_greedy_row( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize) @@ -1843,11 +1809,48 @@ size_t ZSTD_compressBlock_greedy_row( return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_noDict); } -size_t ZSTD_compressBlock_lazy2_dictMatchState_row( +size_t ZSTD_compressBlock_greedy_dictMatchState_row( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize) { - return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_dictMatchState); + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_greedy_dedicatedDictSearch_row( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_dedicatedDictSearch); +} +#endif + +#ifndef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_lazy_dictMatchState( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dedicatedDictSearch); +} + +size_t ZSTD_compressBlock_lazy_row( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_noDict); } size_t ZSTD_compressBlock_lazy_dictMatchState_row( @@ -1857,13 +1860,49 @@ size_t ZSTD_compressBlock_lazy_dictMatchState_row( return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_dictMatchState); } -size_t ZSTD_compressBlock_greedy_dictMatchState_row( +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch_row( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize) { - return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_dictMatchState); + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_dedicatedDictSearch); +} +#endif + +#ifndef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy2( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_noDict); } +size_t ZSTD_compressBlock_lazy2_dictMatchState( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dedicatedDictSearch); +} + +size_t ZSTD_compressBlock_lazy2_row( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_lazy2_dictMatchState_row( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_dictMatchState); +} size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch_row( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], @@ -1871,22 +1910,30 @@ size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch_row( { return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_dedicatedDictSearch); } +#endif -size_t ZSTD_compressBlock_lazy_dedicatedDictSearch_row( +#ifndef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btlazy2( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize) { - return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_dedicatedDictSearch); + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_noDict); } -size_t ZSTD_compressBlock_greedy_dedicatedDictSearch_row( +size_t ZSTD_compressBlock_btlazy2_dictMatchState( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize) { - return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_dedicatedDictSearch); + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_dictMatchState); } +#endif +#if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR size_t ZSTD_compressBlock_lazy_extDict_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], @@ -1912,12 +1959,13 @@ size_t ZSTD_compressBlock_lazy_extDict_generic( DEBUGLOG(5, "ZSTD_compressBlock_lazy_extDict_generic (searchFunc=%u)", (U32)searchMethod); + /* Reset the lazy skipping state */ + ms->lazySkipping = 0; + /* init */ ip += (ip == prefixStart); if (searchMethod == search_rowHash) { - ZSTD_row_fillHashCache(ms, base, rowLog, - MIN(ms->cParams.minMatch, 6 /* mls caps out at 6 */), - ms->nextToUpdate, ilimit); + ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit); } /* Match Loop */ @@ -1955,7 +2003,16 @@ size_t ZSTD_compressBlock_lazy_extDict_generic( } if (matchLength < 4) { - ip += ((ip-anchor) >> kSearchStrength) + 1; /* jump faster over incompressible sections */ + size_t const step = ((size_t)(ip-anchor) >> kSearchStrength); + ip += step + 1; /* jump faster over incompressible sections */ + /* Enter the lazy skipping mode once we are skipping more than 8 bytes at a time. + * In this mode we stop inserting every position into our tables, and only insert + * positions that we search, which is one in step positions. + * The exact cutoff is flexible, I've just chosen a number that is reasonably high, + * so we minimize the compression ratio loss in "normal" scenarios. This mode gets + * triggered once we've gone 2KB without finding any matches. + */ + ms->lazySkipping = step > kLazySkippingStep; continue; } @@ -2041,6 +2098,13 @@ _storeSequence: ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offBase, matchLength); anchor = ip = start + matchLength; } + if (ms->lazySkipping) { + /* We've found a match, disable lazy skipping mode, and refill the hash cache. */ + if (searchMethod == search_rowHash) { + ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit); + } + ms->lazySkipping = 0; + } /* check immediate repcode */ while (ip <= ilimit) { @@ -2071,8 +2135,9 @@ _storeSequence: /* Return the last literals size */ return (size_t)(iend - anchor); } +#endif /* build exclusions */ - +#ifndef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR size_t ZSTD_compressBlock_greedy_extDict( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize) @@ -2080,6 +2145,15 @@ size_t ZSTD_compressBlock_greedy_extDict( return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0); } +size_t ZSTD_compressBlock_greedy_extDict_row( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0); +} +#endif + +#ifndef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR size_t ZSTD_compressBlock_lazy_extDict( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize) @@ -2088,29 +2162,6 @@ size_t ZSTD_compressBlock_lazy_extDict( return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1); } -size_t ZSTD_compressBlock_lazy2_extDict( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize) - -{ - return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2); -} - -size_t ZSTD_compressBlock_btlazy2_extDict( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize) - -{ - return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2); -} - -size_t ZSTD_compressBlock_greedy_extDict_row( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize) -{ - return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0); -} - size_t ZSTD_compressBlock_lazy_extDict_row( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize) @@ -2118,6 +2169,16 @@ size_t ZSTD_compressBlock_lazy_extDict_row( { return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1); } +#endif + +#ifndef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy2_extDict( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) + +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2); +} size_t ZSTD_compressBlock_lazy2_extDict_row( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], @@ -2125,3 +2186,14 @@ size_t ZSTD_compressBlock_lazy2_extDict_row( { return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2); } +#endif + +#ifndef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btlazy2_extDict( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) + +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2); +} +#endif diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_lazy.h b/src/dependencies/zstd-1.5.6/lib/compress/zstd_lazy.h similarity index 58% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_lazy.h rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_lazy.h index 3bde673..3635813 100644 --- a/src/dependencies/zstd-1.5.4/lib/compress/zstd_lazy.h +++ b/src/dependencies/zstd-1.5.6/lib/compress/zstd_lazy.h @@ -27,98 +27,173 @@ extern "C" { #define ZSTD_ROW_HASH_TAG_BITS 8 /* nb bits to use for the tag */ +#if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip); void ZSTD_row_update(ZSTD_matchState_t* const ms, const BYTE* ip); void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const BYTE* const ip); void ZSTD_preserveUnsortedMark (U32* const table, U32 const size, U32 const reducerValue); /*! used in ZSTD_reduceIndex(). preemptively increase value of ZSTD_DUBT_UNSORTED_MARK */ +#endif -size_t ZSTD_compressBlock_btlazy2( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); -size_t ZSTD_compressBlock_lazy2( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); -size_t ZSTD_compressBlock_lazy( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); +#ifndef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR size_t ZSTD_compressBlock_greedy( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); -size_t ZSTD_compressBlock_lazy2_row( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); -size_t ZSTD_compressBlock_lazy_row( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); size_t ZSTD_compressBlock_greedy_row( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); - -size_t ZSTD_compressBlock_btlazy2_dictMatchState( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); -size_t ZSTD_compressBlock_lazy2_dictMatchState( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); -size_t ZSTD_compressBlock_lazy_dictMatchState( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); size_t ZSTD_compressBlock_greedy_dictMatchState( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); -size_t ZSTD_compressBlock_lazy2_dictMatchState_row( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); -size_t ZSTD_compressBlock_lazy_dictMatchState_row( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); size_t ZSTD_compressBlock_greedy_dictMatchState_row( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); - -size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); -size_t ZSTD_compressBlock_lazy_dedicatedDictSearch( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); size_t ZSTD_compressBlock_greedy_dedicatedDictSearch( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); -size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch_row( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); -size_t ZSTD_compressBlock_lazy_dedicatedDictSearch_row( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); size_t ZSTD_compressBlock_greedy_dedicatedDictSearch_row( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); - size_t ZSTD_compressBlock_greedy_extDict( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); -size_t ZSTD_compressBlock_lazy_extDict( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); -size_t ZSTD_compressBlock_lazy2_extDict( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); size_t ZSTD_compressBlock_greedy_extDict_row( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_GREEDY ZSTD_compressBlock_greedy +#define ZSTD_COMPRESSBLOCK_GREEDY_ROW ZSTD_compressBlock_greedy_row +#define ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE ZSTD_compressBlock_greedy_dictMatchState +#define ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE_ROW ZSTD_compressBlock_greedy_dictMatchState_row +#define ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH ZSTD_compressBlock_greedy_dedicatedDictSearch +#define ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH_ROW ZSTD_compressBlock_greedy_dedicatedDictSearch_row +#define ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT ZSTD_compressBlock_greedy_extDict +#define ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT_ROW ZSTD_compressBlock_greedy_extDict_row +#else +#define ZSTD_COMPRESSBLOCK_GREEDY NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_ROW NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE_ROW NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH_ROW NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT_ROW NULL +#endif + +#ifndef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_row( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dictMatchState( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dictMatchState_row( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch_row( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_extDict( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); size_t ZSTD_compressBlock_lazy_extDict_row( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_LAZY ZSTD_compressBlock_lazy +#define ZSTD_COMPRESSBLOCK_LAZY_ROW ZSTD_compressBlock_lazy_row +#define ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE ZSTD_compressBlock_lazy_dictMatchState +#define ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE_ROW ZSTD_compressBlock_lazy_dictMatchState_row +#define ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH ZSTD_compressBlock_lazy_dedicatedDictSearch +#define ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH_ROW ZSTD_compressBlock_lazy_dedicatedDictSearch_row +#define ZSTD_COMPRESSBLOCK_LAZY_EXTDICT ZSTD_compressBlock_lazy_extDict +#define ZSTD_COMPRESSBLOCK_LAZY_EXTDICT_ROW ZSTD_compressBlock_lazy_extDict_row +#else +#define ZSTD_COMPRESSBLOCK_LAZY NULL +#define ZSTD_COMPRESSBLOCK_LAZY_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH NULL +#define ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY_EXTDICT NULL +#define ZSTD_COMPRESSBLOCK_LAZY_EXTDICT_ROW NULL +#endif + +#ifndef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy2( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_row( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dictMatchState( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dictMatchState_row( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch_row( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_extDict( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); size_t ZSTD_compressBlock_lazy2_extDict_row( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_LAZY2 ZSTD_compressBlock_lazy2 +#define ZSTD_COMPRESSBLOCK_LAZY2_ROW ZSTD_compressBlock_lazy2_row +#define ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE ZSTD_compressBlock_lazy2_dictMatchState +#define ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE_ROW ZSTD_compressBlock_lazy2_dictMatchState_row +#define ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH ZSTD_compressBlock_lazy2_dedicatedDictSearch +#define ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW ZSTD_compressBlock_lazy2_dedicatedDictSearch_row +#define ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT ZSTD_compressBlock_lazy2_extDict +#define ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT_ROW ZSTD_compressBlock_lazy2_extDict_row +#else +#define ZSTD_COMPRESSBLOCK_LAZY2 NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT_ROW NULL +#endif + +#ifndef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btlazy2( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btlazy2_dictMatchState( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); size_t ZSTD_compressBlock_btlazy2_extDict( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); +#define ZSTD_COMPRESSBLOCK_BTLAZY2 ZSTD_compressBlock_btlazy2 +#define ZSTD_COMPRESSBLOCK_BTLAZY2_DICTMATCHSTATE ZSTD_compressBlock_btlazy2_dictMatchState +#define ZSTD_COMPRESSBLOCK_BTLAZY2_EXTDICT ZSTD_compressBlock_btlazy2_extDict +#else +#define ZSTD_COMPRESSBLOCK_BTLAZY2 NULL +#define ZSTD_COMPRESSBLOCK_BTLAZY2_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_BTLAZY2_EXTDICT NULL +#endif + #if defined (__cplusplus) } diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_ldm.c b/src/dependencies/zstd-1.5.6/lib/compress/zstd_ldm.c similarity index 99% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_ldm.c rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_ldm.c index 3d74ff1..17c069f 100644 --- a/src/dependencies/zstd-1.5.4/lib/compress/zstd_ldm.c +++ b/src/dependencies/zstd-1.5.6/lib/compress/zstd_ldm.c @@ -246,7 +246,11 @@ static size_t ZSTD_ldm_fillFastTables(ZSTD_matchState_t* ms, break; case ZSTD_dfast: +#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR ZSTD_fillDoubleHashTable(ms, iend, ZSTD_dtlm_fast, ZSTD_tfp_forCCtx); +#else + assert(0); /* shouldn't be called: cparams should've been adjusted. */ +#endif break; case ZSTD_greedy: @@ -318,7 +322,9 @@ static void ZSTD_ldm_limitTableUpdate(ZSTD_matchState_t* ms, const BYTE* anchor) } } -static size_t ZSTD_ldm_generateSequences_internal( +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_ldm_generateSequences_internal( ldmState_t* ldmState, rawSeqStore_t* rawSeqStore, ldmParams_t const* params, void const* src, size_t srcSize) { @@ -689,7 +695,6 @@ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore, /* maybeSplitSequence updates rawSeqStore->pos */ rawSeq const sequence = maybeSplitSequence(rawSeqStore, (U32)(iend - ip), minMatch); - int i; /* End signal */ if (sequence.offset == 0) break; @@ -702,6 +707,7 @@ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore, /* Run the block compressor */ DEBUGLOG(5, "pos %u : calling block compressor on segment of size %u", (unsigned)(ip-istart), sequence.litLength); { + int i; size_t const newLitLength = blockCompressor(ms, seqStore, rep, ip, sequence.litLength); ip += sequence.litLength; diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_ldm.h b/src/dependencies/zstd-1.5.6/lib/compress/zstd_ldm.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_ldm.h rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_ldm.h diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_ldm_geartab.h b/src/dependencies/zstd-1.5.6/lib/compress/zstd_ldm_geartab.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_ldm_geartab.h rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_ldm_geartab.h diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_opt.c b/src/dependencies/zstd-1.5.6/lib/compress/zstd_opt.c similarity index 84% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_opt.c rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_opt.c index fdd7f9d..e63073e 100644 --- a/src/dependencies/zstd-1.5.4/lib/compress/zstd_opt.c +++ b/src/dependencies/zstd-1.5.6/lib/compress/zstd_opt.c @@ -12,6 +12,9 @@ #include "hist.h" #include "zstd_opt.h" +#if !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR) #define ZSTD_LITFREQ_ADD 2 /* scaling factor for litFreq, so that frequencies adapt faster to new stats */ #define ZSTD_MAX_PRICE (1<<30) @@ -264,6 +267,7 @@ static U32 ZSTD_rawLiteralsCost(const BYTE* const literals, U32 const litLength, const optState_t* const optPtr, int optLevel) { + DEBUGLOG(8, "ZSTD_rawLiteralsCost (%u literals)", litLength); if (litLength == 0) return 0; if (!ZSTD_compressedLiterals(optPtr)) @@ -402,9 +406,11 @@ MEM_STATIC U32 ZSTD_readMINMATCH(const void* memPtr, U32 length) /* Update hashTable3 up to ip (excluded) Assumption : always within prefix (i.e. not within extDict) */ -static U32 ZSTD_insertAndFindFirstIndexHash3 (const ZSTD_matchState_t* ms, - U32* nextToUpdate3, - const BYTE* const ip) +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_insertAndFindFirstIndexHash3 (const ZSTD_matchState_t* ms, + U32* nextToUpdate3, + const BYTE* const ip) { U32* const hashTable3 = ms->hashTable3; U32 const hashLog3 = ms->hashLog3; @@ -431,7 +437,9 @@ static U32 ZSTD_insertAndFindFirstIndexHash3 (const ZSTD_matchState_t* ms, * @param ip assumed <= iend-8 . * @param target The target of ZSTD_updateTree_internal() - we are filling to this position * @return : nb of positions added */ -static U32 ZSTD_insertBt1( +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_insertBt1( const ZSTD_matchState_t* ms, const BYTE* const ip, const BYTE* const iend, U32 const target, @@ -550,6 +558,7 @@ static U32 ZSTD_insertBt1( } FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR void ZSTD_updateTree_internal( ZSTD_matchState_t* ms, const BYTE* const ip, const BYTE* const iend, @@ -558,7 +567,7 @@ void ZSTD_updateTree_internal( const BYTE* const base = ms->window.base; U32 const target = (U32)(ip - base); U32 idx = ms->nextToUpdate; - DEBUGLOG(6, "ZSTD_updateTree_internal, from %u to %u (dictMode:%u)", + DEBUGLOG(7, "ZSTD_updateTree_internal, from %u to %u (dictMode:%u)", idx, target, dictMode); while(idx < target) { @@ -575,7 +584,9 @@ void ZSTD_updateTree(ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* iend) { ZSTD_updateTree_internal(ms, ip, iend, ms->cParams.minMatch, ZSTD_noDict); } -FORCE_INLINE_TEMPLATE U32 +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_insertBtAndGetAllMatches ( ZSTD_match_t* matches, /* store result (found matches) in this table (presumed large enough) */ ZSTD_matchState_t* ms, @@ -816,7 +827,9 @@ typedef U32 (*ZSTD_getAllMatchesFn)( U32 const ll0, U32 const lengthToBeat); -FORCE_INLINE_TEMPLATE U32 ZSTD_btGetAllMatches_internal( +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_btGetAllMatches_internal( ZSTD_match_t* matches, ZSTD_matchState_t* ms, U32* nextToUpdate3, @@ -1035,11 +1048,6 @@ ZSTD_optLdm_processMatchCandidate(ZSTD_optLdm_t* optLdm, * Optimal parser *********************************/ -static U32 ZSTD_totalLen(ZSTD_optimal_t sol) -{ - return sol.litlen + sol.mlen; -} - #if 0 /* debug */ static void @@ -1057,7 +1065,13 @@ listStats(const U32* table, int lastEltID) #endif -FORCE_INLINE_TEMPLATE size_t +#define LIT_PRICE(_p) (int)ZSTD_rawLiteralsCost(_p, 1, optStatePtr, optLevel) +#define LL_PRICE(_l) (int)ZSTD_litLengthPrice(_l, optStatePtr, optLevel) +#define LL_INCPRICE(_l) (LL_PRICE(_l) - LL_PRICE(_l-1)) + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], @@ -1083,9 +1097,11 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, ZSTD_optimal_t* const opt = optStatePtr->priceTable; ZSTD_match_t* const matches = optStatePtr->matchTable; - ZSTD_optimal_t lastSequence; + ZSTD_optimal_t lastStretch; ZSTD_optLdm_t optLdm; + ZSTD_memset(&lastStretch, 0, sizeof(ZSTD_optimal_t)); + optLdm.seqStore = ms->ldmSeqStore ? *ms->ldmSeqStore : kNullRawSeqStore; optLdm.endPosInBlock = optLdm.startPosInBlock = optLdm.offset = 0; ZSTD_opt_getNextMatchAndUpdateSeqStore(&optLdm, (U32)(ip-istart), (U32)(iend-ip)); @@ -1106,19 +1122,31 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, U32 const ll0 = !litlen; U32 nbMatches = getAllMatches(matches, ms, &nextToUpdate3, ip, iend, rep, ll0, minMatch); ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches, - (U32)(ip-istart), (U32)(iend - ip)); - if (!nbMatches) { ip++; continue; } + (U32)(ip-istart), (U32)(iend-ip)); + if (!nbMatches) { + DEBUGLOG(8, "no match found at cPos %u", (unsigned)(ip-istart)); + ip++; + continue; + } + + /* Match found: let's store this solution, and eventually find more candidates. + * During this forward pass, @opt is used to store stretches, + * defined as "a match followed by N literals". + * Note how this is different from a Sequence, which is "N literals followed by a match". + * Storing stretches allows us to store different match predecessors + * for each literal position part of a literals run. */ /* initialize opt[0] */ - { U32 i ; for (i=0; i immediate encoding */ { U32 const maxML = matches[nbMatches-1].len; @@ -1127,82 +1155,106 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, nbMatches, maxML, maxOffBase, (U32)(ip-prefixStart)); if (maxML > sufficient_len) { - lastSequence.litlen = litlen; - lastSequence.mlen = maxML; - lastSequence.off = maxOffBase; - DEBUGLOG(6, "large match (%u>%u), immediate encoding", + lastStretch.litlen = 0; + lastStretch.mlen = maxML; + lastStretch.off = maxOffBase; + DEBUGLOG(6, "large match (%u>%u) => immediate encoding", maxML, sufficient_len); cur = 0; - last_pos = ZSTD_totalLen(lastSequence); + last_pos = maxML; goto _shortestPath; } } /* set prices for first matches starting position == 0 */ assert(opt[0].price >= 0); - { U32 const literalsPrice = (U32)opt[0].price + ZSTD_litLengthPrice(0, optStatePtr, optLevel); - U32 pos; + { U32 pos; U32 matchNb; for (pos = 1; pos < minMatch; pos++) { - opt[pos].price = ZSTD_MAX_PRICE; /* mlen, litlen and price will be fixed during forward scanning */ + opt[pos].price = ZSTD_MAX_PRICE; + opt[pos].mlen = 0; + opt[pos].litlen = litlen + pos; } for (matchNb = 0; matchNb < nbMatches; matchNb++) { U32 const offBase = matches[matchNb].off; U32 const end = matches[matchNb].len; for ( ; pos <= end ; pos++ ) { - U32 const matchPrice = ZSTD_getMatchPrice(offBase, pos, optStatePtr, optLevel); - U32 const sequencePrice = literalsPrice + matchPrice; + int const matchPrice = (int)ZSTD_getMatchPrice(offBase, pos, optStatePtr, optLevel); + int const sequencePrice = opt[0].price + matchPrice; DEBUGLOG(7, "rPos:%u => set initial price : %.2f", - pos, ZSTD_fCost((int)sequencePrice)); + pos, ZSTD_fCost(sequencePrice)); opt[pos].mlen = pos; opt[pos].off = offBase; - opt[pos].litlen = litlen; - opt[pos].price = (int)sequencePrice; - } } + opt[pos].litlen = 0; /* end of match */ + opt[pos].price = sequencePrice + LL_PRICE(0); + } + } last_pos = pos-1; + opt[pos].price = ZSTD_MAX_PRICE; } } /* check further positions */ for (cur = 1; cur <= last_pos; cur++) { const BYTE* const inr = ip + cur; - assert(cur < ZSTD_OPT_NUM); - DEBUGLOG(7, "cPos:%zi==rPos:%u", inr-istart, cur) + assert(cur <= ZSTD_OPT_NUM); + DEBUGLOG(7, "cPos:%zi==rPos:%u", inr-istart, cur); /* Fix current position with one literal if cheaper */ - { U32 const litlen = (opt[cur-1].mlen == 0) ? opt[cur-1].litlen + 1 : 1; + { U32 const litlen = opt[cur-1].litlen + 1; int const price = opt[cur-1].price - + (int)ZSTD_rawLiteralsCost(ip+cur-1, 1, optStatePtr, optLevel) - + (int)ZSTD_litLengthPrice(litlen, optStatePtr, optLevel) - - (int)ZSTD_litLengthPrice(litlen-1, optStatePtr, optLevel); + + LIT_PRICE(ip+cur-1) + + LL_INCPRICE(litlen); assert(price < 1000000000); /* overflow check */ if (price <= opt[cur].price) { + ZSTD_optimal_t const prevMatch = opt[cur]; DEBUGLOG(7, "cPos:%zi==rPos:%u : better price (%.2f<=%.2f) using literal (ll==%u) (hist:%u,%u,%u)", inr-istart, cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price), litlen, opt[cur-1].rep[0], opt[cur-1].rep[1], opt[cur-1].rep[2]); - opt[cur].mlen = 0; - opt[cur].off = 0; + opt[cur] = opt[cur-1]; opt[cur].litlen = litlen; opt[cur].price = price; + if ( (optLevel >= 1) /* additional check only for higher modes */ + && (prevMatch.litlen == 0) /* replace a match */ + && (LL_INCPRICE(1) < 0) /* ll1 is cheaper than ll0 */ + && LIKELY(ip + cur < iend) + ) { + /* check next position, in case it would be cheaper */ + int with1literal = prevMatch.price + LIT_PRICE(ip+cur) + LL_INCPRICE(1); + int withMoreLiterals = price + LIT_PRICE(ip+cur) + LL_INCPRICE(litlen+1); + DEBUGLOG(7, "then at next rPos %u : match+1lit %.2f vs %ulits %.2f", + cur+1, ZSTD_fCost(with1literal), litlen+1, ZSTD_fCost(withMoreLiterals)); + if ( (with1literal < withMoreLiterals) + && (with1literal < opt[cur+1].price) ) { + /* update offset history - before it disappears */ + U32 const prev = cur - prevMatch.mlen; + repcodes_t const newReps = ZSTD_newRep(opt[prev].rep, prevMatch.off, opt[prev].litlen==0); + assert(cur >= prevMatch.mlen); + DEBUGLOG(7, "==> match+1lit is cheaper (%.2f < %.2f) (hist:%u,%u,%u) !", + ZSTD_fCost(with1literal), ZSTD_fCost(withMoreLiterals), + newReps.rep[0], newReps.rep[1], newReps.rep[2] ); + opt[cur+1] = prevMatch; /* mlen & offbase */ + ZSTD_memcpy(opt[cur+1].rep, &newReps, sizeof(repcodes_t)); + opt[cur+1].litlen = 1; + opt[cur+1].price = with1literal; + if (last_pos < cur+1) last_pos = cur+1; + } + } } else { - DEBUGLOG(7, "cPos:%zi==rPos:%u : literal would cost more (%.2f>%.2f) (hist:%u,%u,%u)", - inr-istart, cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price), - opt[cur].rep[0], opt[cur].rep[1], opt[cur].rep[2]); + DEBUGLOG(7, "cPos:%zi==rPos:%u : literal would cost more (%.2f>%.2f)", + inr-istart, cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price)); } } - /* Set the repcodes of the current position. We must do it here - * because we rely on the repcodes of the 2nd to last sequence being - * correct to set the next chunks repcodes during the backward - * traversal. + /* Offset history is not updated during match comparison. + * Do it here, now that the match is selected and confirmed. */ ZSTD_STATIC_ASSERT(sizeof(opt[cur].rep) == sizeof(repcodes_t)); assert(cur >= opt[cur].mlen); - if (opt[cur].mlen != 0) { + if (opt[cur].litlen == 0) { + /* just finished a match => alter offset history */ U32 const prev = cur - opt[cur].mlen; - repcodes_t const newReps = ZSTD_newRep(opt[prev].rep, opt[cur].off, opt[cur].litlen==0); + repcodes_t const newReps = ZSTD_newRep(opt[prev].rep, opt[cur].off, opt[prev].litlen==0); ZSTD_memcpy(opt[cur].rep, &newReps, sizeof(repcodes_t)); - } else { - ZSTD_memcpy(opt[cur].rep, opt[cur - 1].rep, sizeof(repcodes_t)); } /* last match must start at a minimum distance of 8 from oend */ @@ -1212,15 +1264,14 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, if ( (optLevel==0) /*static_test*/ && (opt[cur+1].price <= opt[cur].price + (BITCOST_MULTIPLIER/2)) ) { - DEBUGLOG(7, "move to next rPos:%u : price is <=", cur+1); + DEBUGLOG(7, "skip current position : next rPos(%u) price is cheaper", cur+1); continue; /* skip unpromising positions; about ~+6% speed, -0.01 ratio */ } assert(opt[cur].price >= 0); - { U32 const ll0 = (opt[cur].mlen != 0); - U32 const litlen = (opt[cur].mlen == 0) ? opt[cur].litlen : 0; - U32 const previousPrice = (U32)opt[cur].price; - U32 const basePrice = previousPrice + ZSTD_litLengthPrice(0, optStatePtr, optLevel); + { U32 const ll0 = (opt[cur].litlen == 0); + int const previousPrice = opt[cur].price; + int const basePrice = previousPrice + LL_PRICE(0); U32 nbMatches = getAllMatches(matches, ms, &nextToUpdate3, inr, iend, opt[cur].rep, ll0, minMatch); U32 matchNb; @@ -1232,18 +1283,17 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, continue; } - { U32 const maxML = matches[nbMatches-1].len; - DEBUGLOG(7, "cPos:%zi==rPos:%u, found %u matches, of maxLength=%u", - inr-istart, cur, nbMatches, maxML); + { U32 const longestML = matches[nbMatches-1].len; + DEBUGLOG(7, "cPos:%zi==rPos:%u, found %u matches, of longest ML=%u", + inr-istart, cur, nbMatches, longestML); - if ( (maxML > sufficient_len) - || (cur + maxML >= ZSTD_OPT_NUM) ) { - lastSequence.mlen = maxML; - lastSequence.off = matches[nbMatches-1].off; - lastSequence.litlen = litlen; - cur -= (opt[cur].mlen==0) ? opt[cur].litlen : 0; /* last sequence is actually only literals, fix cur to last match - note : may underflow, in which case, it's first sequence, and it's okay */ - last_pos = cur + ZSTD_totalLen(lastSequence); - if (cur > ZSTD_OPT_NUM) cur = 0; /* underflow => first match */ + if ( (longestML > sufficient_len) + || (cur + longestML >= ZSTD_OPT_NUM) + || (ip + cur + longestML >= iend) ) { + lastStretch.mlen = longestML; + lastStretch.off = matches[nbMatches-1].off; + lastStretch.litlen = 0; + last_pos = cur + longestML; goto _shortestPath; } } @@ -1255,19 +1305,24 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, U32 mlen; DEBUGLOG(7, "testing match %u => offBase=%4u, mlen=%2u, llen=%2u", - matchNb, matches[matchNb].off, lastML, litlen); + matchNb, matches[matchNb].off, lastML, opt[cur].litlen); for (mlen = lastML; mlen >= startML; mlen--) { /* scan downward */ U32 const pos = cur + mlen; - int const price = (int)basePrice + (int)ZSTD_getMatchPrice(offset, mlen, optStatePtr, optLevel); + int const price = basePrice + (int)ZSTD_getMatchPrice(offset, mlen, optStatePtr, optLevel); if ((pos > last_pos) || (price < opt[pos].price)) { DEBUGLOG(7, "rPos:%u (ml=%2u) => new better price (%.2f<%.2f)", pos, mlen, ZSTD_fCost(price), ZSTD_fCost(opt[pos].price)); - while (last_pos < pos) { opt[last_pos+1].price = ZSTD_MAX_PRICE; last_pos++; } /* fill empty positions */ + while (last_pos < pos) { + /* fill empty positions, for future comparisons */ + last_pos++; + opt[last_pos].price = ZSTD_MAX_PRICE; + opt[last_pos].litlen = !0; /* just needs to be != 0, to mean "not an end of match" */ + } opt[pos].mlen = mlen; opt[pos].off = offset; - opt[pos].litlen = litlen; + opt[pos].litlen = 0; opt[pos].price = price; } else { DEBUGLOG(7, "rPos:%u (ml=%2u) => new price is worse (%.2f>=%.2f)", @@ -1275,47 +1330,81 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, if (optLevel==0) break; /* early update abort; gets ~+10% speed for about -0.01 ratio loss */ } } } } + opt[last_pos+1].price = ZSTD_MAX_PRICE; } /* for (cur = 1; cur <= last_pos; cur++) */ - lastSequence = opt[last_pos]; - cur = last_pos > ZSTD_totalLen(lastSequence) ? last_pos - ZSTD_totalLen(lastSequence) : 0; /* single sequence, and it starts before `ip` */ - assert(cur < ZSTD_OPT_NUM); /* control overflow*/ + lastStretch = opt[last_pos]; + assert(cur >= lastStretch.mlen); + cur = last_pos - lastStretch.mlen; _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */ assert(opt[0].mlen == 0); + assert(last_pos >= lastStretch.mlen); + assert(cur == last_pos - lastStretch.mlen); - /* Set the next chunk's repcodes based on the repcodes of the beginning - * of the last match, and the last sequence. This avoids us having to - * update them while traversing the sequences. - */ - if (lastSequence.mlen != 0) { - repcodes_t const reps = ZSTD_newRep(opt[cur].rep, lastSequence.off, lastSequence.litlen==0); - ZSTD_memcpy(rep, &reps, sizeof(reps)); + if (lastStretch.mlen==0) { + /* no solution : all matches have been converted into literals */ + assert(lastStretch.litlen == (ip - anchor) + last_pos); + ip += last_pos; + continue; + } + assert(lastStretch.off > 0); + + /* Update offset history */ + if (lastStretch.litlen == 0) { + /* finishing on a match : update offset history */ + repcodes_t const reps = ZSTD_newRep(opt[cur].rep, lastStretch.off, opt[cur].litlen==0); + ZSTD_memcpy(rep, &reps, sizeof(repcodes_t)); } else { - ZSTD_memcpy(rep, opt[cur].rep, sizeof(repcodes_t)); + ZSTD_memcpy(rep, lastStretch.rep, sizeof(repcodes_t)); + assert(cur >= lastStretch.litlen); + cur -= lastStretch.litlen; } - { U32 const storeEnd = cur + 1; + /* Let's write the shortest path solution. + * It is stored in @opt in reverse order, + * starting from @storeEnd (==cur+2), + * effectively partially @opt overwriting. + * Content is changed too: + * - So far, @opt stored stretches, aka a match followed by literals + * - Now, it will store sequences, aka literals followed by a match + */ + { U32 const storeEnd = cur + 2; U32 storeStart = storeEnd; - U32 seqPos = cur; + U32 stretchPos = cur; DEBUGLOG(6, "start reverse traversal (last_pos:%u, cur:%u)", last_pos, cur); (void)last_pos; - assert(storeEnd < ZSTD_OPT_NUM); - DEBUGLOG(6, "last sequence copied into pos=%u (llen=%u,mlen=%u,ofc=%u)", - storeEnd, lastSequence.litlen, lastSequence.mlen, lastSequence.off); - opt[storeEnd] = lastSequence; - while (seqPos > 0) { - U32 const backDist = ZSTD_totalLen(opt[seqPos]); + assert(storeEnd < ZSTD_OPT_SIZE); + DEBUGLOG(6, "last stretch copied into pos=%u (llen=%u,mlen=%u,ofc=%u)", + storeEnd, lastStretch.litlen, lastStretch.mlen, lastStretch.off); + if (lastStretch.litlen > 0) { + /* last "sequence" is unfinished: just a bunch of literals */ + opt[storeEnd].litlen = lastStretch.litlen; + opt[storeEnd].mlen = 0; + storeStart = storeEnd-1; + opt[storeStart] = lastStretch; + } { + opt[storeEnd] = lastStretch; /* note: litlen will be fixed */ + storeStart = storeEnd; + } + while (1) { + ZSTD_optimal_t nextStretch = opt[stretchPos]; + opt[storeStart].litlen = nextStretch.litlen; + DEBUGLOG(6, "selected sequence (llen=%u,mlen=%u,ofc=%u)", + opt[storeStart].litlen, opt[storeStart].mlen, opt[storeStart].off); + if (nextStretch.mlen == 0) { + /* reaching beginning of segment */ + break; + } storeStart--; - DEBUGLOG(6, "sequence from rPos=%u copied into pos=%u (llen=%u,mlen=%u,ofc=%u)", - seqPos, storeStart, opt[seqPos].litlen, opt[seqPos].mlen, opt[seqPos].off); - opt[storeStart] = opt[seqPos]; - seqPos = (seqPos > backDist) ? seqPos - backDist : 0; + opt[storeStart] = nextStretch; /* note: litlen will be fixed */ + assert(nextStretch.litlen + nextStretch.mlen <= stretchPos); + stretchPos -= nextStretch.litlen + nextStretch.mlen; } /* save sequences */ - DEBUGLOG(6, "sending selected sequences into seqStore") + DEBUGLOG(6, "sending selected sequences into seqStore"); { U32 storePos; for (storePos=storeStart; storePos <= storeEnd; storePos++) { U32 const llen = opt[storePos].litlen; @@ -1337,6 +1426,9 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */ anchor += advance; ip = anchor; } } + DEBUGLOG(7, "new offset history : %u, %u, %u", rep[0], rep[1], rep[2]); + + /* update all costs */ ZSTD_setBasePrices(optStatePtr, optLevel); } } /* while (ip < ilimit) */ @@ -1344,21 +1436,27 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */ /* Return the last literals size */ return (size_t)(iend - anchor); } +#endif /* build exclusions */ +#ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR static size_t ZSTD_compressBlock_opt0( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize, const ZSTD_dictMode_e dictMode) { return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /* optLevel */, dictMode); } +#endif +#ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR static size_t ZSTD_compressBlock_opt2( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize, const ZSTD_dictMode_e dictMode) { return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /* optLevel */, dictMode); } +#endif +#ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR size_t ZSTD_compressBlock_btopt( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize) @@ -1366,20 +1464,23 @@ size_t ZSTD_compressBlock_btopt( DEBUGLOG(5, "ZSTD_compressBlock_btopt"); return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_noDict); } +#endif +#ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR /* ZSTD_initStats_ultra(): * make a first compression pass, just to seed stats with more accurate starting values. * only works on first block, with no dictionary and no ldm. * this function cannot error out, its narrow contract must be respected. */ -static void -ZSTD_initStats_ultra(ZSTD_matchState_t* ms, - seqStore_t* seqStore, - U32 rep[ZSTD_REP_NUM], - const void* src, size_t srcSize) +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_initStats_ultra(ZSTD_matchState_t* ms, + seqStore_t* seqStore, + U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) { U32 tmpRep[ZSTD_REP_NUM]; /* updated rep codes will sink here */ ZSTD_memcpy(tmpRep, rep, sizeof(tmpRep)); @@ -1423,7 +1524,7 @@ size_t ZSTD_compressBlock_btultra2( * Consequently, this can only work if no data has been previously loaded in tables, * aka, no dictionary, no prefix, no ldm preprocessing. * The compression ratio gain is generally small (~0.5% on first block), - ** the cost is 2x cpu time on first block. */ + * the cost is 2x cpu time on first block. */ assert(srcSize <= ZSTD_BLOCKSIZE_MAX); if ( (ms->opt.litLengthSum==0) /* first block */ && (seqStore->sequences == seqStore->sequencesStart) /* no ldm */ @@ -1436,7 +1537,9 @@ size_t ZSTD_compressBlock_btultra2( return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict); } +#endif +#ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR size_t ZSTD_compressBlock_btopt_dictMatchState( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize) @@ -1444,19 +1547,21 @@ size_t ZSTD_compressBlock_btopt_dictMatchState( return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState); } -size_t ZSTD_compressBlock_btultra_dictMatchState( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - const void* src, size_t srcSize) -{ - return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState); -} - size_t ZSTD_compressBlock_btopt_extDict( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize) { return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_extDict); } +#endif + +#ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btultra_dictMatchState( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState); +} size_t ZSTD_compressBlock_btultra_extDict( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], @@ -1464,6 +1569,7 @@ size_t ZSTD_compressBlock_btultra_extDict( { return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_extDict); } +#endif /* note : no btultra2 variant for extDict nor dictMatchState, * because btultra2 is not meant to work with dictionaries diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstd_opt.h b/src/dependencies/zstd-1.5.6/lib/compress/zstd_opt.h similarity index 64% rename from src/dependencies/zstd-1.5.4/lib/compress/zstd_opt.h rename to src/dependencies/zstd-1.5.6/lib/compress/zstd_opt.h index 342e5a3..d4e7113 100644 --- a/src/dependencies/zstd-1.5.4/lib/compress/zstd_opt.h +++ b/src/dependencies/zstd-1.5.6/lib/compress/zstd_opt.h @@ -17,28 +17,38 @@ extern "C" { #include "zstd_compress_internal.h" +#if !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR) /* used in ZSTD_loadDictionaryContent() */ void ZSTD_updateTree(ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* iend); +#endif +#ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR size_t ZSTD_compressBlock_btopt( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); -size_t ZSTD_compressBlock_btultra( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); -size_t ZSTD_compressBlock_btultra2( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize); - - size_t ZSTD_compressBlock_btopt_dictMatchState( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); -size_t ZSTD_compressBlock_btultra_dictMatchState( +size_t ZSTD_compressBlock_btopt_extDict( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); -size_t ZSTD_compressBlock_btopt_extDict( +#define ZSTD_COMPRESSBLOCK_BTOPT ZSTD_compressBlock_btopt +#define ZSTD_COMPRESSBLOCK_BTOPT_DICTMATCHSTATE ZSTD_compressBlock_btopt_dictMatchState +#define ZSTD_COMPRESSBLOCK_BTOPT_EXTDICT ZSTD_compressBlock_btopt_extDict +#else +#define ZSTD_COMPRESSBLOCK_BTOPT NULL +#define ZSTD_COMPRESSBLOCK_BTOPT_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_BTOPT_EXTDICT NULL +#endif + +#ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btultra( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btultra_dictMatchState( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); size_t ZSTD_compressBlock_btultra_extDict( @@ -48,6 +58,20 @@ size_t ZSTD_compressBlock_btultra_extDict( /* note : no btultra2 variant for extDict nor dictMatchState, * because btultra2 is not meant to work with dictionaries * and is only specific for the first block (no prefix) */ +size_t ZSTD_compressBlock_btultra2( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_BTULTRA ZSTD_compressBlock_btultra +#define ZSTD_COMPRESSBLOCK_BTULTRA_DICTMATCHSTATE ZSTD_compressBlock_btultra_dictMatchState +#define ZSTD_COMPRESSBLOCK_BTULTRA_EXTDICT ZSTD_compressBlock_btultra_extDict +#define ZSTD_COMPRESSBLOCK_BTULTRA2 ZSTD_compressBlock_btultra2 +#else +#define ZSTD_COMPRESSBLOCK_BTULTRA NULL +#define ZSTD_COMPRESSBLOCK_BTULTRA_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_BTULTRA_EXTDICT NULL +#define ZSTD_COMPRESSBLOCK_BTULTRA2 NULL +#endif #if defined (__cplusplus) } diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstdmt_compress.c b/src/dependencies/zstd-1.5.6/lib/compress/zstdmt_compress.c similarity index 93% rename from src/dependencies/zstd-1.5.4/lib/compress/zstdmt_compress.c rename to src/dependencies/zstd-1.5.6/lib/compress/zstdmt_compress.c index 7a2c717..86ccce3 100644 --- a/src/dependencies/zstd-1.5.4/lib/compress/zstdmt_compress.c +++ b/src/dependencies/zstd-1.5.6/lib/compress/zstdmt_compress.c @@ -15,16 +15,13 @@ #endif -/* ====== Constants ====== */ -#define ZSTDMT_OVERLAPLOG_DEFAULT 0 - - /* ====== Dependencies ====== */ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */ #include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset, INT_MAX, UINT_MAX */ #include "../common/mem.h" /* MEM_STATIC */ #include "../common/pool.h" /* threadpool */ #include "../common/threading.h" /* mutex */ -#include "zstd_compress_internal.h" /* MIN, ERROR, ZSTD_*, ZSTD_highbit32 */ +#include "zstd_compress_internal.h" /* MIN, ERROR, ZSTD_*, ZSTD_highbit32 */ #include "zstd_ldm.h" #include "zstdmt_compress.h" @@ -43,12 +40,13 @@ # include # include -# define DEBUG_PRINTHEX(l,p,n) { \ - unsigned debug_u; \ - for (debug_u=0; debug_u<(n); debug_u++) \ - RAWLOG(l, "%02X ", ((const unsigned char*)(p))[debug_u]); \ - RAWLOG(l, " \n"); \ -} +# define DEBUG_PRINTHEX(l,p,n) \ + do { \ + unsigned debug_u; \ + for (debug_u=0; debug_u<(n); debug_u++) \ + RAWLOG(l, "%02X ", ((const unsigned char*)(p))[debug_u]); \ + RAWLOG(l, " \n"); \ + } while (0) static unsigned long long GetCurrentClockTimeMicroseconds(void) { @@ -60,25 +58,28 @@ static unsigned long long GetCurrentClockTimeMicroseconds(void) } } #define MUTEX_WAIT_TIME_DLEVEL 6 -#define ZSTD_PTHREAD_MUTEX_LOCK(mutex) { \ - if (DEBUGLEVEL >= MUTEX_WAIT_TIME_DLEVEL) { \ - unsigned long long const beforeTime = GetCurrentClockTimeMicroseconds(); \ - ZSTD_pthread_mutex_lock(mutex); \ - { unsigned long long const afterTime = GetCurrentClockTimeMicroseconds(); \ - unsigned long long const elapsedTime = (afterTime-beforeTime); \ - if (elapsedTime > 1000) { /* or whatever threshold you like; I'm using 1 millisecond here */ \ - DEBUGLOG(MUTEX_WAIT_TIME_DLEVEL, "Thread took %llu microseconds to acquire mutex %s \n", \ - elapsedTime, #mutex); \ - } } \ - } else { \ - ZSTD_pthread_mutex_lock(mutex); \ - } \ -} +#define ZSTD_PTHREAD_MUTEX_LOCK(mutex) \ + do { \ + if (DEBUGLEVEL >= MUTEX_WAIT_TIME_DLEVEL) { \ + unsigned long long const beforeTime = GetCurrentClockTimeMicroseconds(); \ + ZSTD_pthread_mutex_lock(mutex); \ + { unsigned long long const afterTime = GetCurrentClockTimeMicroseconds(); \ + unsigned long long const elapsedTime = (afterTime-beforeTime); \ + if (elapsedTime > 1000) { \ + /* or whatever threshold you like; I'm using 1 millisecond here */ \ + DEBUGLOG(MUTEX_WAIT_TIME_DLEVEL, \ + "Thread took %llu microseconds to acquire mutex %s \n", \ + elapsedTime, #mutex); \ + } } \ + } else { \ + ZSTD_pthread_mutex_lock(mutex); \ + } \ + } while (0) #else # define ZSTD_PTHREAD_MUTEX_LOCK(m) ZSTD_pthread_mutex_lock(m) -# define DEBUG_PRINTHEX(l,p,n) {} +# define DEBUG_PRINTHEX(l,p,n) do { } while (0) #endif @@ -99,18 +100,39 @@ typedef struct ZSTDMT_bufferPool_s { unsigned totalBuffers; unsigned nbBuffers; ZSTD_customMem cMem; - buffer_t bTable[1]; /* variable size */ + buffer_t* buffers; } ZSTDMT_bufferPool; +static void ZSTDMT_freeBufferPool(ZSTDMT_bufferPool* bufPool) +{ + DEBUGLOG(3, "ZSTDMT_freeBufferPool (address:%08X)", (U32)(size_t)bufPool); + if (!bufPool) return; /* compatibility with free on NULL */ + if (bufPool->buffers) { + unsigned u; + for (u=0; utotalBuffers; u++) { + DEBUGLOG(4, "free buffer %2u (address:%08X)", u, (U32)(size_t)bufPool->buffers[u].start); + ZSTD_customFree(bufPool->buffers[u].start, bufPool->cMem); + } + ZSTD_customFree(bufPool->buffers, bufPool->cMem); + } + ZSTD_pthread_mutex_destroy(&bufPool->poolMutex); + ZSTD_customFree(bufPool, bufPool->cMem); +} + static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned maxNbBuffers, ZSTD_customMem cMem) { - ZSTDMT_bufferPool* const bufPool = (ZSTDMT_bufferPool*)ZSTD_customCalloc( - sizeof(ZSTDMT_bufferPool) + (maxNbBuffers-1) * sizeof(buffer_t), cMem); + ZSTDMT_bufferPool* const bufPool = + (ZSTDMT_bufferPool*)ZSTD_customCalloc(sizeof(ZSTDMT_bufferPool), cMem); if (bufPool==NULL) return NULL; if (ZSTD_pthread_mutex_init(&bufPool->poolMutex, NULL)) { ZSTD_customFree(bufPool, cMem); return NULL; } + bufPool->buffers = (buffer_t*)ZSTD_customCalloc(maxNbBuffers * sizeof(buffer_t), cMem); + if (bufPool->buffers==NULL) { + ZSTDMT_freeBufferPool(bufPool); + return NULL; + } bufPool->bufferSize = 64 KB; bufPool->totalBuffers = maxNbBuffers; bufPool->nbBuffers = 0; @@ -118,32 +140,19 @@ static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned maxNbBuffers, ZSTD_cu return bufPool; } -static void ZSTDMT_freeBufferPool(ZSTDMT_bufferPool* bufPool) -{ - unsigned u; - DEBUGLOG(3, "ZSTDMT_freeBufferPool (address:%08X)", (U32)(size_t)bufPool); - if (!bufPool) return; /* compatibility with free on NULL */ - for (u=0; utotalBuffers; u++) { - DEBUGLOG(4, "free buffer %2u (address:%08X)", u, (U32)(size_t)bufPool->bTable[u].start); - ZSTD_customFree(bufPool->bTable[u].start, bufPool->cMem); - } - ZSTD_pthread_mutex_destroy(&bufPool->poolMutex); - ZSTD_customFree(bufPool, bufPool->cMem); -} - /* only works at initialization, not during compression */ static size_t ZSTDMT_sizeof_bufferPool(ZSTDMT_bufferPool* bufPool) { - size_t const poolSize = sizeof(*bufPool) - + (bufPool->totalBuffers - 1) * sizeof(buffer_t); + size_t const poolSize = sizeof(*bufPool); + size_t const arraySize = bufPool->totalBuffers * sizeof(buffer_t); unsigned u; size_t totalBufferSize = 0; ZSTD_pthread_mutex_lock(&bufPool->poolMutex); for (u=0; utotalBuffers; u++) - totalBufferSize += bufPool->bTable[u].capacity; + totalBufferSize += bufPool->buffers[u].capacity; ZSTD_pthread_mutex_unlock(&bufPool->poolMutex); - return poolSize + totalBufferSize; + return poolSize + arraySize + totalBufferSize; } /* ZSTDMT_setBufferSize() : @@ -186,9 +195,9 @@ static buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool* bufPool) DEBUGLOG(5, "ZSTDMT_getBuffer: bSize = %u", (U32)bufPool->bufferSize); ZSTD_pthread_mutex_lock(&bufPool->poolMutex); if (bufPool->nbBuffers) { /* try to use an existing buffer */ - buffer_t const buf = bufPool->bTable[--(bufPool->nbBuffers)]; + buffer_t const buf = bufPool->buffers[--(bufPool->nbBuffers)]; size_t const availBufferSize = buf.capacity; - bufPool->bTable[bufPool->nbBuffers] = g_nullBuffer; + bufPool->buffers[bufPool->nbBuffers] = g_nullBuffer; if ((availBufferSize >= bSize) & ((availBufferSize>>3) <= bSize)) { /* large enough, but not too much */ DEBUGLOG(5, "ZSTDMT_getBuffer: provide buffer %u of size %u", @@ -249,14 +258,14 @@ static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf) if (buf.start == NULL) return; /* compatible with release on NULL */ ZSTD_pthread_mutex_lock(&bufPool->poolMutex); if (bufPool->nbBuffers < bufPool->totalBuffers) { - bufPool->bTable[bufPool->nbBuffers++] = buf; /* stored for later use */ + bufPool->buffers[bufPool->nbBuffers++] = buf; /* stored for later use */ DEBUGLOG(5, "ZSTDMT_releaseBuffer: stored buffer of size %u in slot %u", (U32)buf.capacity, (U32)(bufPool->nbBuffers-1)); ZSTD_pthread_mutex_unlock(&bufPool->poolMutex); return; } ZSTD_pthread_mutex_unlock(&bufPool->poolMutex); - /* Reached bufferPool capacity (should not happen) */ + /* Reached bufferPool capacity (note: should not happen) */ DEBUGLOG(5, "ZSTDMT_releaseBuffer: pool capacity reached => freeing "); ZSTD_customFree(buf.start, bufPool->cMem); } @@ -349,16 +358,20 @@ typedef struct { int totalCCtx; int availCCtx; ZSTD_customMem cMem; - ZSTD_CCtx* cctx[1]; /* variable size */ + ZSTD_CCtx** cctxs; } ZSTDMT_CCtxPool; -/* note : all CCtx borrowed from the pool should be released back to the pool _before_ freeing the pool */ +/* note : all CCtx borrowed from the pool must be reverted back to the pool _before_ freeing the pool */ static void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool* pool) { - int cid; - for (cid=0; cidtotalCCtx; cid++) - ZSTD_freeCCtx(pool->cctx[cid]); /* note : compatible with free on NULL */ + if (!pool) return; ZSTD_pthread_mutex_destroy(&pool->poolMutex); + if (pool->cctxs) { + int cid; + for (cid=0; cidtotalCCtx; cid++) + ZSTD_freeCCtx(pool->cctxs[cid]); /* free compatible with NULL */ + ZSTD_customFree(pool->cctxs, pool->cMem); + } ZSTD_customFree(pool, pool->cMem); } @@ -367,19 +380,24 @@ static void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool* pool) static ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(int nbWorkers, ZSTD_customMem cMem) { - ZSTDMT_CCtxPool* const cctxPool = (ZSTDMT_CCtxPool*) ZSTD_customCalloc( - sizeof(ZSTDMT_CCtxPool) + (nbWorkers-1)*sizeof(ZSTD_CCtx*), cMem); + ZSTDMT_CCtxPool* const cctxPool = + (ZSTDMT_CCtxPool*) ZSTD_customCalloc(sizeof(ZSTDMT_CCtxPool), cMem); assert(nbWorkers > 0); if (!cctxPool) return NULL; if (ZSTD_pthread_mutex_init(&cctxPool->poolMutex, NULL)) { ZSTD_customFree(cctxPool, cMem); return NULL; } - cctxPool->cMem = cMem; cctxPool->totalCCtx = nbWorkers; + cctxPool->cctxs = (ZSTD_CCtx**)ZSTD_customCalloc(nbWorkers * sizeof(ZSTD_CCtx*), cMem); + if (!cctxPool->cctxs) { + ZSTDMT_freeCCtxPool(cctxPool); + return NULL; + } + cctxPool->cMem = cMem; + cctxPool->cctxs[0] = ZSTD_createCCtx_advanced(cMem); + if (!cctxPool->cctxs[0]) { ZSTDMT_freeCCtxPool(cctxPool); return NULL; } cctxPool->availCCtx = 1; /* at least one cctx for single-thread mode */ - cctxPool->cctx[0] = ZSTD_createCCtx_advanced(cMem); - if (!cctxPool->cctx[0]) { ZSTDMT_freeCCtxPool(cctxPool); return NULL; } DEBUGLOG(3, "cctxPool created, with %u workers", nbWorkers); return cctxPool; } @@ -401,16 +419,16 @@ static size_t ZSTDMT_sizeof_CCtxPool(ZSTDMT_CCtxPool* cctxPool) { ZSTD_pthread_mutex_lock(&cctxPool->poolMutex); { unsigned const nbWorkers = cctxPool->totalCCtx; - size_t const poolSize = sizeof(*cctxPool) - + (nbWorkers-1) * sizeof(ZSTD_CCtx*); - unsigned u; + size_t const poolSize = sizeof(*cctxPool); + size_t const arraySize = cctxPool->totalCCtx * sizeof(ZSTD_CCtx*); size_t totalCCtxSize = 0; + unsigned u; for (u=0; ucctx[u]); + totalCCtxSize += ZSTD_sizeof_CCtx(cctxPool->cctxs[u]); } ZSTD_pthread_mutex_unlock(&cctxPool->poolMutex); assert(nbWorkers > 0); - return poolSize + totalCCtxSize; + return poolSize + arraySize + totalCCtxSize; } } @@ -420,7 +438,7 @@ static ZSTD_CCtx* ZSTDMT_getCCtx(ZSTDMT_CCtxPool* cctxPool) ZSTD_pthread_mutex_lock(&cctxPool->poolMutex); if (cctxPool->availCCtx) { cctxPool->availCCtx--; - { ZSTD_CCtx* const cctx = cctxPool->cctx[cctxPool->availCCtx]; + { ZSTD_CCtx* const cctx = cctxPool->cctxs[cctxPool->availCCtx]; ZSTD_pthread_mutex_unlock(&cctxPool->poolMutex); return cctx; } } @@ -434,7 +452,7 @@ static void ZSTDMT_releaseCCtx(ZSTDMT_CCtxPool* pool, ZSTD_CCtx* cctx) if (cctx==NULL) return; /* compatibility with release on NULL */ ZSTD_pthread_mutex_lock(&pool->poolMutex); if (pool->availCCtx < pool->totalCCtx) - pool->cctx[pool->availCCtx++] = cctx; + pool->cctxs[pool->availCCtx++] = cctx; else { /* pool overflow : should not happen, since totalCCtx==nbWorkers */ DEBUGLOG(4, "CCtx pool overflow : free cctx"); @@ -600,11 +618,8 @@ static void ZSTDMT_serialState_update(serialState_t* serialState, ZSTD_pthread_mutex_unlock(&serialState->mutex); if (seqStore.size > 0) { - size_t const err = ZSTD_referenceExternalSequences( - jobCCtx, seqStore.seq, seqStore.size); + ZSTD_referenceExternalSequences(jobCCtx, seqStore.seq, seqStore.size); assert(serialState->params.ldmParams.enableLdm == ZSTD_ps_enable); - assert(!ZSTD_isError(err)); - (void)err; } } @@ -656,12 +671,13 @@ typedef struct { unsigned frameChecksumNeeded; /* used only by mtctx */ } ZSTDMT_jobDescription; -#define JOB_ERROR(e) { \ - ZSTD_PTHREAD_MUTEX_LOCK(&job->job_mutex); \ - job->cSize = e; \ - ZSTD_pthread_mutex_unlock(&job->job_mutex); \ - goto _endJob; \ -} +#define JOB_ERROR(e) \ + do { \ + ZSTD_PTHREAD_MUTEX_LOCK(&job->job_mutex); \ + job->cSize = e; \ + ZSTD_pthread_mutex_unlock(&job->job_mutex); \ + goto _endJob; \ + } while (0) /* ZSTDMT_compressionJob() is a POOL_function type */ static void ZSTDMT_compressionJob(void* jobDescription) @@ -719,7 +735,7 @@ static void ZSTDMT_compressionJob(void* jobDescription) ZSTDMT_serialState_update(job->serial, cctx, rawSeqStore, job->src, job->jobID); if (!job->firstJob) { /* flush and overwrite frame header when it's not first job */ - size_t const hSize = ZSTD_compressContinue(cctx, dstBuff.start, dstBuff.capacity, job->src.start, 0); + size_t const hSize = ZSTD_compressContinue_public(cctx, dstBuff.start, dstBuff.capacity, job->src.start, 0); if (ZSTD_isError(hSize)) JOB_ERROR(hSize); DEBUGLOG(5, "ZSTDMT_compressionJob: flush and overwrite %u bytes of frame header (not first job)", (U32)hSize); ZSTD_invalidateRepCodes(cctx); @@ -737,7 +753,7 @@ static void ZSTDMT_compressionJob(void* jobDescription) DEBUGLOG(5, "ZSTDMT_compressionJob: compress %u bytes in %i blocks", (U32)job->src.size, nbChunks); assert(job->cSize == 0); for (chunkNb = 1; chunkNb < nbChunks; chunkNb++) { - size_t const cSize = ZSTD_compressContinue(cctx, op, oend-op, ip, chunkSize); + size_t const cSize = ZSTD_compressContinue_public(cctx, op, oend-op, ip, chunkSize); if (ZSTD_isError(cSize)) JOB_ERROR(cSize); ip += chunkSize; op += cSize; assert(op < oend); @@ -757,8 +773,8 @@ static void ZSTDMT_compressionJob(void* jobDescription) size_t const lastBlockSize1 = job->src.size & (chunkSize-1); size_t const lastBlockSize = ((lastBlockSize1==0) & (job->src.size>=chunkSize)) ? chunkSize : lastBlockSize1; size_t const cSize = (job->lastJob) ? - ZSTD_compressEnd (cctx, op, oend-op, ip, lastBlockSize) : - ZSTD_compressContinue(cctx, op, oend-op, ip, lastBlockSize); + ZSTD_compressEnd_public(cctx, op, oend-op, ip, lastBlockSize) : + ZSTD_compressContinue_public(cctx, op, oend-op, ip, lastBlockSize); if (ZSTD_isError(cSize)) JOB_ERROR(cSize); lastCBlockSize = cSize; } } @@ -1090,7 +1106,7 @@ ZSTD_frameProgression ZSTDMT_getFrameProgression(ZSTDMT_CCtx* mtctx) { unsigned jobNb; unsigned lastJobNb = mtctx->nextJobID + mtctx->jobReady; assert(mtctx->jobReady <= 1); DEBUGLOG(6, "ZSTDMT_getFrameProgression: jobs: from %u to <%u (jobReady:%u)", - mtctx->doneJobID, lastJobNb, mtctx->jobReady) + mtctx->doneJobID, lastJobNb, mtctx->jobReady); for (jobNb = mtctx->doneJobID ; jobNb < lastJobNb ; jobNb++) { unsigned const wJobID = jobNb & mtctx->jobIDMask; ZSTDMT_jobDescription* jobPtr = &mtctx->jobs[wJobID]; diff --git a/src/dependencies/zstd-1.5.4/lib/compress/zstdmt_compress.h b/src/dependencies/zstd-1.5.6/lib/compress/zstdmt_compress.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/compress/zstdmt_compress.h rename to src/dependencies/zstd-1.5.6/lib/compress/zstdmt_compress.h diff --git a/src/dependencies/zstd-1.5.4/lib/decompress/huf_decompress.c b/src/dependencies/zstd-1.5.6/lib/decompress/huf_decompress.c similarity index 87% rename from src/dependencies/zstd-1.5.4/lib/decompress/huf_decompress.c rename to src/dependencies/zstd-1.5.6/lib/decompress/huf_decompress.c index c2d1f63..f85dd0b 100644 --- a/src/dependencies/zstd-1.5.4/lib/decompress/huf_decompress.c +++ b/src/dependencies/zstd-1.5.6/lib/decompress/huf_decompress.c @@ -34,6 +34,12 @@ * Macros ****************************************************************/ +#ifdef HUF_DISABLE_FAST_DECODE +# define HUF_ENABLE_FAST_DECODE 0 +#else +# define HUF_ENABLE_FAST_DECODE 1 +#endif + /* These two optional macros force the use one way or another of the two * Huffman decompression implementations. You can't force in both directions * at the same time. @@ -158,17 +164,18 @@ static size_t HUF_initFastDStream(BYTE const* ip) { * op [in/out] - The output pointers, must be updated to reflect what is written. * bits [in/out] - The bitstream containers, must be updated to reflect the current state. * dt [in] - The decoding table. - * ilimit [in] - The input limit, stop when any input pointer is below ilimit. + * ilowest [in] - The beginning of the valid range of the input. Decoders may read + * down to this pointer. It may be below iend[0]. * oend [in] - The end of the output stream. op[3] must not cross oend. * iend [in] - The end of each input stream. ip[i] may cross iend[i], - * as long as it is above ilimit, but that indicates corruption. + * as long as it is above ilowest, but that indicates corruption. */ typedef struct { BYTE const* ip[4]; BYTE* op[4]; U64 bits[4]; void const* dt; - BYTE const* ilimit; + BYTE const* ilowest; BYTE* oend; BYTE const* iend[4]; } HUF_DecompressFastArgs; @@ -186,9 +193,9 @@ static size_t HUF_DecompressFastArgs_init(HUF_DecompressFastArgs* args, void* ds void const* dt = DTable + 1; U32 const dtLog = HUF_getDTableDesc(DTable).tableLog; - const BYTE* const ilimit = (const BYTE*)src + 6 + 8; + const BYTE* const istart = (const BYTE*)src; - BYTE* const oend = (BYTE*)dst + dstSize; + BYTE* const oend = ZSTD_maybeNullPtrAdd((BYTE*)dst, dstSize); /* The fast decoding loop assumes 64-bit little-endian. * This condition is false on x32. @@ -196,6 +203,11 @@ static size_t HUF_DecompressFastArgs_init(HUF_DecompressFastArgs* args, void* ds if (!MEM_isLittleEndian() || MEM_32bits()) return 0; + /* Avoid nullptr addition */ + if (dstSize == 0) + return 0; + assert(dst != NULL); + /* strict minimum : jump table + 1 byte per stream */ if (srcSize < 10) return ERROR(corruption_detected); @@ -209,7 +221,6 @@ static size_t HUF_DecompressFastArgs_init(HUF_DecompressFastArgs* args, void* ds /* Read the jump table. */ { - const BYTE* const istart = (const BYTE*)src; size_t const length1 = MEM_readLE16(istart); size_t const length2 = MEM_readLE16(istart+2); size_t const length3 = MEM_readLE16(istart+4); @@ -221,10 +232,8 @@ static size_t HUF_DecompressFastArgs_init(HUF_DecompressFastArgs* args, void* ds /* HUF_initFastDStream() requires this, and this small of an input * won't benefit from the ASM loop anyways. - * length1 must be >= 16 so that ip[0] >= ilimit before the loop - * starts. */ - if (length1 < 16 || length2 < 8 || length3 < 8 || length4 < 8) + if (length1 < 8 || length2 < 8 || length3 < 8 || length4 < 8) return 0; if (length4 > srcSize) return ERROR(corruption_detected); /* overflow */ } @@ -256,11 +265,12 @@ static size_t HUF_DecompressFastArgs_init(HUF_DecompressFastArgs* args, void* ds args->bits[2] = HUF_initFastDStream(args->ip[2]); args->bits[3] = HUF_initFastDStream(args->ip[3]); - /* If ip[] >= ilimit, it is guaranteed to be safe to - * reload bits[]. It may be beyond its section, but is - * guaranteed to be valid (>= istart). - */ - args->ilimit = ilimit; + /* The decoders must be sure to never read beyond ilowest. + * This is lower than iend[0], but allowing decoders to read + * down to ilowest can allow an extra iteration or two in the + * fast loop. + */ + args->ilowest = istart; args->oend = oend; args->dt = dt; @@ -285,13 +295,31 @@ static size_t HUF_initRemainingDStream(BIT_DStream_t* bit, HUF_DecompressFastArg assert(sizeof(size_t) == 8); bit->bitContainer = MEM_readLEST(args->ip[stream]); bit->bitsConsumed = ZSTD_countTrailingZeros64(args->bits[stream]); - bit->start = (const char*)args->iend[0]; + bit->start = (const char*)args->ilowest; bit->limitPtr = bit->start + sizeof(size_t); bit->ptr = (const char*)args->ip[stream]; return 0; } +/* Calls X(N) for each stream 0, 1, 2, 3. */ +#define HUF_4X_FOR_EACH_STREAM(X) \ + do { \ + X(0); \ + X(1); \ + X(2); \ + X(3); \ + } while (0) + +/* Calls X(N, var) for each stream 0, 1, 2, 3. */ +#define HUF_4X_FOR_EACH_STREAM_WITH_VAR(X, var) \ + do { \ + X(0, (var)); \ + X(1, (var)); \ + X(2, (var)); \ + X(3, (var)); \ + } while (0) + #ifndef HUF_FORCE_DECOMPRESS_X2 @@ -500,15 +528,19 @@ HUF_decodeSymbolX1(BIT_DStream_t* Dstream, const HUF_DEltX1* dt, const U32 dtLog } #define HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) \ - *ptr++ = HUF_decodeSymbolX1(DStreamPtr, dt, dtLog) + do { *ptr++ = HUF_decodeSymbolX1(DStreamPtr, dt, dtLog); } while (0) -#define HUF_DECODE_SYMBOLX1_1(ptr, DStreamPtr) \ - if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \ - HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) +#define HUF_DECODE_SYMBOLX1_1(ptr, DStreamPtr) \ + do { \ + if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \ + HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr); \ + } while (0) -#define HUF_DECODE_SYMBOLX1_2(ptr, DStreamPtr) \ - if (MEM_64bits()) \ - HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) +#define HUF_DECODE_SYMBOLX1_2(ptr, DStreamPtr) \ + do { \ + if (MEM_64bits()) \ + HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr); \ + } while (0) HINT_INLINE size_t HUF_decodeStreamX1(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX1* const dt, const U32 dtLog) @@ -546,7 +578,7 @@ HUF_decompress1X1_usingDTable_internal_body( const HUF_DTable* DTable) { BYTE* op = (BYTE*)dst; - BYTE* const oend = op + dstSize; + BYTE* const oend = ZSTD_maybeNullPtrAdd(op, dstSize); const void* dtPtr = DTable + 1; const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr; BIT_DStream_t bitD; @@ -574,6 +606,7 @@ HUF_decompress4X1_usingDTable_internal_body( { /* Check */ if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ + if (dstSize < 6) return ERROR(corruption_detected); /* stream 4-split doesn't work */ { const BYTE* const istart = (const BYTE*) cSrc; BYTE* const ostart = (BYTE*) dst; @@ -609,7 +642,7 @@ HUF_decompress4X1_usingDTable_internal_body( if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */ - if (dstSize < 6) return ERROR(corruption_detected); /* stream 4-split doesn't work */ + assert(dstSize >= 6); /* validated above */ CHECK_F( BIT_initDStream(&bitD1, istart1, length1) ); CHECK_F( BIT_initDStream(&bitD2, istart2, length2) ); CHECK_F( BIT_initDStream(&bitD3, istart3, length3) ); @@ -692,11 +725,11 @@ void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* BYTE* op[4]; U16 const* const dtable = (U16 const*)args->dt; BYTE* const oend = args->oend; - BYTE const* const ilimit = args->ilimit; + BYTE const* const ilowest = args->ilowest; /* Copy the arguments to local variables */ ZSTD_memcpy(&bits, &args->bits, sizeof(bits)); - ZSTD_memcpy(&ip, &args->ip, sizeof(ip)); + ZSTD_memcpy((void*)(&ip), &args->ip, sizeof(ip)); ZSTD_memcpy(&op, &args->op, sizeof(op)); assert(MEM_isLittleEndian()); @@ -705,13 +738,12 @@ void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* for (;;) { BYTE* olimit; int stream; - int symbol; /* Assert loop preconditions */ #ifndef NDEBUG for (stream = 0; stream < 4; ++stream) { assert(op[stream] <= (stream == 3 ? oend : op[stream + 1])); - assert(ip[stream] >= ilimit); + assert(ip[stream] >= ilowest); } #endif /* Compute olimit */ @@ -721,7 +753,7 @@ void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* /* Each iteration consumes up to 11 bits * 5 = 55 bits < 7 bytes * per stream. */ - size_t const iiters = (size_t)(ip[0] - ilimit) / 7; + size_t const iiters = (size_t)(ip[0] - ilowest) / 7; /* We can safely run iters iterations before running bounds checks */ size_t const iters = MIN(oiters, iiters); size_t const symbols = iters * 5; @@ -732,8 +764,8 @@ void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* */ olimit = op[3] + symbols; - /* Exit fast decoding loop once we get close to the end. */ - if (op[3] + 20 > olimit) + /* Exit fast decoding loop once we reach the end. */ + if (op[3] == olimit) break; /* Exit the decoding loop if any input pointer has crossed the @@ -752,34 +784,49 @@ void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* } #endif +#define HUF_4X1_DECODE_SYMBOL(_stream, _symbol) \ + do { \ + int const index = (int)(bits[(_stream)] >> 53); \ + int const entry = (int)dtable[index]; \ + bits[(_stream)] <<= (entry & 0x3F); \ + op[(_stream)][(_symbol)] = (BYTE)((entry >> 8) & 0xFF); \ + } while (0) + +#define HUF_4X1_RELOAD_STREAM(_stream) \ + do { \ + int const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \ + int const nbBits = ctz & 7; \ + int const nbBytes = ctz >> 3; \ + op[(_stream)] += 5; \ + ip[(_stream)] -= nbBytes; \ + bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1; \ + bits[(_stream)] <<= nbBits; \ + } while (0) + + /* Manually unroll the loop because compilers don't consistently + * unroll the inner loops, which destroys performance. + */ do { /* Decode 5 symbols in each of the 4 streams */ - for (symbol = 0; symbol < 5; ++symbol) { - for (stream = 0; stream < 4; ++stream) { - int const index = (int)(bits[stream] >> 53); - int const entry = (int)dtable[index]; - bits[stream] <<= (entry & 63); - op[stream][symbol] = (BYTE)((entry >> 8) & 0xFF); - } - } - /* Reload the bitstreams */ - for (stream = 0; stream < 4; ++stream) { - int const ctz = ZSTD_countTrailingZeros64(bits[stream]); - int const nbBits = ctz & 7; - int const nbBytes = ctz >> 3; - op[stream] += 5; - ip[stream] -= nbBytes; - bits[stream] = MEM_read64(ip[stream]) | 1; - bits[stream] <<= nbBits; - } + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 1); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 2); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 3); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 4); + + /* Reload each of the 4 the bitstreams */ + HUF_4X_FOR_EACH_STREAM(HUF_4X1_RELOAD_STREAM); } while (op[3] < olimit); + +#undef HUF_4X1_DECODE_SYMBOL +#undef HUF_4X1_RELOAD_STREAM } _out: /* Save the final values of each of the state variables back to args. */ ZSTD_memcpy(&args->bits, &bits, sizeof(bits)); - ZSTD_memcpy(&args->ip, &ip, sizeof(ip)); + ZSTD_memcpy((void*)(&args->ip), &ip, sizeof(ip)); ZSTD_memcpy(&args->op, &op, sizeof(op)); } @@ -797,8 +844,8 @@ HUF_decompress4X1_usingDTable_internal_fast( HUF_DecompressFastLoopFn loopFn) { void const* dt = DTable + 1; - const BYTE* const iend = (const BYTE*)cSrc + 6; - BYTE* const oend = (BYTE*)dst + dstSize; + BYTE const* const ilowest = (BYTE const*)cSrc; + BYTE* const oend = ZSTD_maybeNullPtrAdd((BYTE*)dst, dstSize); HUF_DecompressFastArgs args; { size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable); FORWARD_IF_ERROR(ret, "Failed to init fast loop args"); @@ -806,18 +853,22 @@ HUF_decompress4X1_usingDTable_internal_fast( return 0; } - assert(args.ip[0] >= args.ilimit); + assert(args.ip[0] >= args.ilowest); loopFn(&args); - /* Our loop guarantees that ip[] >= ilimit and that we haven't + /* Our loop guarantees that ip[] >= ilowest and that we haven't * overwritten any op[]. */ - assert(args.ip[0] >= iend); - assert(args.ip[1] >= iend); - assert(args.ip[2] >= iend); - assert(args.ip[3] >= iend); + assert(args.ip[0] >= ilowest); + assert(args.ip[0] >= ilowest); + assert(args.ip[1] >= ilowest); + assert(args.ip[2] >= ilowest); + assert(args.ip[3] >= ilowest); assert(args.op[3] <= oend); - (void)iend; + + assert(ilowest == args.ilowest); + assert(ilowest + 6 == args.iend[0]); + (void)ilowest; /* finish bit streams one by one. */ { size_t const segmentSize = (dstSize+3) / 4; @@ -868,7 +919,7 @@ static size_t HUF_decompress4X1_usingDTable_internal(void* dst, size_t dstSize, } #endif - if (!(flags & HUF_flags_disableFast)) { + if (HUF_ENABLE_FAST_DECODE && !(flags & HUF_flags_disableFast)) { size_t const ret = HUF_decompress4X1_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn); if (ret != 0) return ret; @@ -1239,15 +1290,19 @@ HUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, c } #define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \ - ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog) + do { ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); } while (0) -#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \ - if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \ - ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog) +#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \ + do { \ + if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \ + ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); \ + } while (0) -#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \ - if (MEM_64bits()) \ - ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog) +#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \ + do { \ + if (MEM_64bits()) \ + ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); \ + } while (0) HINT_INLINE size_t HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, @@ -1307,7 +1362,7 @@ HUF_decompress1X2_usingDTable_internal_body( /* decode */ { BYTE* const ostart = (BYTE*) dst; - BYTE* const oend = ostart + dstSize; + BYTE* const oend = ZSTD_maybeNullPtrAdd(ostart, dstSize); const void* const dtPtr = DTable+1; /* force compiler to not use strict-aliasing */ const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr; DTableDesc const dtd = HUF_getDTableDesc(DTable); @@ -1332,6 +1387,7 @@ HUF_decompress4X2_usingDTable_internal_body( const HUF_DTable* DTable) { if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ + if (dstSize < 6) return ERROR(corruption_detected); /* stream 4-split doesn't work */ { const BYTE* const istart = (const BYTE*) cSrc; BYTE* const ostart = (BYTE*) dst; @@ -1367,7 +1423,7 @@ HUF_decompress4X2_usingDTable_internal_body( if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */ - if (dstSize < 6) return ERROR(corruption_detected); /* stream 4-split doesn't work */ + assert(dstSize >= 6 /* validated above */); CHECK_F( BIT_initDStream(&bitD1, istart1, length1) ); CHECK_F( BIT_initDStream(&bitD2, istart2, length2) ); CHECK_F( BIT_initDStream(&bitD3, istart3, length3) ); @@ -1472,11 +1528,11 @@ void HUF_decompress4X2_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* BYTE* op[4]; BYTE* oend[4]; HUF_DEltX2 const* const dtable = (HUF_DEltX2 const*)args->dt; - BYTE const* const ilimit = args->ilimit; + BYTE const* const ilowest = args->ilowest; /* Copy the arguments to local registers. */ ZSTD_memcpy(&bits, &args->bits, sizeof(bits)); - ZSTD_memcpy(&ip, &args->ip, sizeof(ip)); + ZSTD_memcpy((void*)(&ip), &args->ip, sizeof(ip)); ZSTD_memcpy(&op, &args->op, sizeof(op)); oend[0] = op[1]; @@ -1490,13 +1546,12 @@ void HUF_decompress4X2_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* for (;;) { BYTE* olimit; int stream; - int symbol; /* Assert loop preconditions */ #ifndef NDEBUG for (stream = 0; stream < 4; ++stream) { assert(op[stream] <= oend[stream]); - assert(ip[stream] >= ilimit); + assert(ip[stream] >= ilowest); } #endif /* Compute olimit */ @@ -1509,7 +1564,7 @@ void HUF_decompress4X2_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* * We also know that each input pointer is >= ip[0]. So we can run * iters loops before running out of input. */ - size_t iters = (size_t)(ip[0] - ilimit) / 7; + size_t iters = (size_t)(ip[0] - ilowest) / 7; /* Each iteration can produce up to 10 bytes of output per stream. * Each output stream my advance at different rates. So take the * minimum number of safe iterations among all the output streams. @@ -1527,8 +1582,8 @@ void HUF_decompress4X2_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* */ olimit = op[3] + (iters * 5); - /* Exit the fast decoding loop if we are too close to the end. */ - if (op[3] + 10 > olimit) + /* Exit the fast decoding loop once we reach the end. */ + if (op[3] == olimit) break; /* Exit the decoding loop if any input pointer has crossed the @@ -1547,59 +1602,63 @@ void HUF_decompress4X2_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* } #endif +#define HUF_4X2_DECODE_SYMBOL(_stream, _decode3) \ + do { \ + if ((_decode3) || (_stream) != 3) { \ + int const index = (int)(bits[(_stream)] >> 53); \ + HUF_DEltX2 const entry = dtable[index]; \ + MEM_write16(op[(_stream)], entry.sequence); \ + bits[(_stream)] <<= (entry.nbBits) & 0x3F; \ + op[(_stream)] += (entry.length); \ + } \ + } while (0) + +#define HUF_4X2_RELOAD_STREAM(_stream) \ + do { \ + HUF_4X2_DECODE_SYMBOL(3, 1); \ + { \ + int const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \ + int const nbBits = ctz & 7; \ + int const nbBytes = ctz >> 3; \ + ip[(_stream)] -= nbBytes; \ + bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1; \ + bits[(_stream)] <<= nbBits; \ + } \ + } while (0) + + /* Manually unroll the loop because compilers don't consistently + * unroll the inner loops, which destroys performance. + */ do { - /* Do 5 table lookups for each of the first 3 streams */ - for (symbol = 0; symbol < 5; ++symbol) { - for (stream = 0; stream < 3; ++stream) { - int const index = (int)(bits[stream] >> 53); - HUF_DEltX2 const entry = dtable[index]; - MEM_write16(op[stream], entry.sequence); - bits[stream] <<= (entry.nbBits); - op[stream] += (entry.length); - } - } - /* Do 1 table lookup from the final stream */ - { - int const index = (int)(bits[3] >> 53); - HUF_DEltX2 const entry = dtable[index]; - MEM_write16(op[3], entry.sequence); - bits[3] <<= (entry.nbBits); - op[3] += (entry.length); - } - /* Do 4 table lookups from the final stream & reload bitstreams */ - for (stream = 0; stream < 4; ++stream) { - /* Do a table lookup from the final stream. - * This is interleaved with the reloading to reduce register - * pressure. This shouldn't be necessary, but compilers can - * struggle with codegen with high register pressure. - */ - { - int const index = (int)(bits[3] >> 53); - HUF_DEltX2 const entry = dtable[index]; - MEM_write16(op[3], entry.sequence); - bits[3] <<= (entry.nbBits); - op[3] += (entry.length); - } - /* Reload the bistreams. The final bitstream must be reloaded - * after the 5th symbol was decoded. - */ - { - int const ctz = ZSTD_countTrailingZeros64(bits[stream]); - int const nbBits = ctz & 7; - int const nbBytes = ctz >> 3; - ip[stream] -= nbBytes; - bits[stream] = MEM_read64(ip[stream]) | 1; - bits[stream] <<= nbBits; - } - } + /* Decode 5 symbols from each of the first 3 streams. + * The final stream will be decoded during the reload phase + * to reduce register pressure. + */ + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + + /* Decode one symbol from the final stream */ + HUF_4X2_DECODE_SYMBOL(3, 1); + + /* Decode 4 symbols from the final stream & reload bitstreams. + * The final stream is reloaded last, meaning that all 5 symbols + * are decoded from the final stream before it is reloaded. + */ + HUF_4X_FOR_EACH_STREAM(HUF_4X2_RELOAD_STREAM); } while (op[3] < olimit); } +#undef HUF_4X2_DECODE_SYMBOL +#undef HUF_4X2_RELOAD_STREAM + _out: /* Save the final values of each of the state variables back to args. */ ZSTD_memcpy(&args->bits, &bits, sizeof(bits)); - ZSTD_memcpy(&args->ip, &ip, sizeof(ip)); + ZSTD_memcpy((void*)(&args->ip), &ip, sizeof(ip)); ZSTD_memcpy(&args->op, &op, sizeof(op)); } @@ -1611,8 +1670,8 @@ HUF_decompress4X2_usingDTable_internal_fast( const HUF_DTable* DTable, HUF_DecompressFastLoopFn loopFn) { void const* dt = DTable + 1; - const BYTE* const iend = (const BYTE*)cSrc + 6; - BYTE* const oend = (BYTE*)dst + dstSize; + const BYTE* const ilowest = (const BYTE*)cSrc; + BYTE* const oend = ZSTD_maybeNullPtrAdd((BYTE*)dst, dstSize); HUF_DecompressFastArgs args; { size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable); @@ -1621,16 +1680,19 @@ HUF_decompress4X2_usingDTable_internal_fast( return 0; } - assert(args.ip[0] >= args.ilimit); + assert(args.ip[0] >= args.ilowest); loopFn(&args); /* note : op4 already verified within main loop */ - assert(args.ip[0] >= iend); - assert(args.ip[1] >= iend); - assert(args.ip[2] >= iend); - assert(args.ip[3] >= iend); + assert(args.ip[0] >= ilowest); + assert(args.ip[1] >= ilowest); + assert(args.ip[2] >= ilowest); + assert(args.ip[3] >= ilowest); assert(args.op[3] <= oend); - (void)iend; + + assert(ilowest == args.ilowest); + assert(ilowest + 6 == args.iend[0]); + (void)ilowest; /* finish bitStreams one by one */ { @@ -1679,7 +1741,7 @@ static size_t HUF_decompress4X2_usingDTable_internal(void* dst, size_t dstSize, } #endif - if (!(flags & HUF_flags_disableFast)) { + if (HUF_ENABLE_FAST_DECODE && !(flags & HUF_flags_disableFast)) { size_t const ret = HUF_decompress4X2_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn); if (ret != 0) return ret; diff --git a/src/dependencies/zstd-1.5.4/lib/decompress/huf_decompress_amd64.S b/src/dependencies/zstd-1.5.6/lib/decompress/huf_decompress_amd64.S similarity index 89% rename from src/dependencies/zstd-1.5.4/lib/decompress/huf_decompress_amd64.S rename to src/dependencies/zstd-1.5.6/lib/decompress/huf_decompress_amd64.S index 671624f..78da291 100644 --- a/src/dependencies/zstd-1.5.4/lib/decompress/huf_decompress_amd64.S +++ b/src/dependencies/zstd-1.5.6/lib/decompress/huf_decompress_amd64.S @@ -10,11 +10,32 @@ #include "../common/portability_macros.h" +#if defined(__ELF__) && defined(__GNUC__) /* Stack marking * ref: https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart */ -#if defined(__ELF__) && defined(__GNUC__) .section .note.GNU-stack,"",%progbits + +#if defined(__aarch64__) +/* Mark that this assembly supports BTI & PAC, because it is empty for aarch64. + * See: https://github.com/facebook/zstd/issues/3841 + * See: https://gcc.godbolt.org/z/sqr5T4ffK + * See: https://lore.kernel.org/linux-arm-kernel/20200429211641.9279-8-broonie@kernel.org/ + * See: https://reviews.llvm.org/D62609 + */ +.pushsection .note.gnu.property, "a" +.p2align 3 +.long 4 /* size of the name - "GNU\0" */ +.long 0x10 /* size of descriptor */ +.long 0x5 /* NT_GNU_PROPERTY_TYPE_0 */ +.asciz "GNU" +.long 0xc0000000 /* pr_type - GNU_PROPERTY_AARCH64_FEATURE_1_AND */ +.long 4 /* pr_datasz - 4 bytes */ +.long 3 /* pr_data - GNU_PROPERTY_AARCH64_FEATURE_1_BTI | GNU_PROPERTY_AARCH64_FEATURE_1_PAC */ +.p2align 3 /* pr_padding - bring everything to 8 byte alignment */ +.popsection +#endif + #endif #if ZSTD_ENABLE_ASM_X86_64_BMI2 @@ -131,7 +152,7 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop: movq 88(%rax), %bits3 movq 96(%rax), %dtable push %rax /* argument */ - push 104(%rax) /* ilimit */ + push 104(%rax) /* ilowest */ push 112(%rax) /* oend */ push %olimit /* olimit space */ @@ -156,11 +177,11 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop: shrq $2, %r15 movq %ip0, %rax /* rax = ip0 */ - movq 40(%rsp), %rdx /* rdx = ilimit */ - subq %rdx, %rax /* rax = ip0 - ilimit */ - movq %rax, %rbx /* rbx = ip0 - ilimit */ + movq 40(%rsp), %rdx /* rdx = ilowest */ + subq %rdx, %rax /* rax = ip0 - ilowest */ + movq %rax, %rbx /* rbx = ip0 - ilowest */ - /* rdx = (ip0 - ilimit) / 7 */ + /* rdx = (ip0 - ilowest) / 7 */ movabsq $2635249153387078803, %rdx mulq %rdx subq %rdx, %rbx @@ -183,9 +204,8 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop: /* If (op3 + 20 > olimit) */ movq %op3, %rax /* rax = op3 */ - addq $20, %rax /* rax = op3 + 20 */ - cmpq %rax, %olimit /* op3 + 20 > olimit */ - jb .L_4X1_exit + cmpq %rax, %olimit /* op3 == olimit */ + je .L_4X1_exit /* If (ip1 < ip0) go to exit */ cmpq %ip0, %ip1 @@ -316,7 +336,7 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop: /* Restore stack (oend & olimit) */ pop %rax /* olimit */ pop %rax /* oend */ - pop %rax /* ilimit */ + pop %rax /* ilowest */ pop %rax /* arg */ /* Save ip / op / bits */ @@ -387,7 +407,7 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop: movq 96(%rax), %dtable push %rax /* argument */ push %rax /* olimit */ - push 104(%rax) /* ilimit */ + push 104(%rax) /* ilowest */ movq 112(%rax), %rax push %rax /* oend3 */ @@ -414,9 +434,9 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop: /* We can consume up to 7 input bytes each iteration. */ movq %ip0, %rax /* rax = ip0 */ - movq 40(%rsp), %rdx /* rdx = ilimit */ - subq %rdx, %rax /* rax = ip0 - ilimit */ - movq %rax, %r15 /* r15 = ip0 - ilimit */ + movq 40(%rsp), %rdx /* rdx = ilowest */ + subq %rdx, %rax /* rax = ip0 - ilowest */ + movq %rax, %r15 /* r15 = ip0 - ilowest */ /* rdx = rax / 7 */ movabsq $2635249153387078803, %rdx @@ -426,7 +446,7 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop: addq %r15, %rdx shrq $2, %rdx - /* r15 = (ip0 - ilimit) / 7 */ + /* r15 = (ip0 - ilowest) / 7 */ movq %rdx, %r15 /* r15 = min(r15, min(oend0 - op0, oend1 - op1, oend2 - op2, oend3 - op3) / 10) */ @@ -467,9 +487,8 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop: /* If (op3 + 10 > olimit) */ movq %op3, %rax /* rax = op3 */ - addq $10, %rax /* rax = op3 + 10 */ - cmpq %rax, %olimit /* op3 + 10 > olimit */ - jb .L_4X2_exit + cmpq %rax, %olimit /* op3 == olimit */ + je .L_4X2_exit /* If (ip1 < ip0) go to exit */ cmpq %ip0, %ip1 @@ -537,7 +556,7 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop: pop %rax /* oend1 */ pop %rax /* oend2 */ pop %rax /* oend3 */ - pop %rax /* ilimit */ + pop %rax /* ilowest */ pop %rax /* olimit */ pop %rax /* arg */ diff --git a/src/dependencies/zstd-1.5.4/lib/decompress/zstd_ddict.c b/src/dependencies/zstd-1.5.6/lib/decompress/zstd_ddict.c similarity index 99% rename from src/dependencies/zstd-1.5.4/lib/decompress/zstd_ddict.c rename to src/dependencies/zstd-1.5.6/lib/decompress/zstd_ddict.c index ad5c34a..309ec0d 100644 --- a/src/dependencies/zstd-1.5.4/lib/decompress/zstd_ddict.c +++ b/src/dependencies/zstd-1.5.6/lib/decompress/zstd_ddict.c @@ -14,6 +14,7 @@ /*-******************************************************* * Dependencies *********************************************************/ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customFree */ #include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */ #include "../common/cpu.h" /* bmi2 */ #include "../common/mem.h" /* low level memory routines */ diff --git a/src/dependencies/zstd-1.5.4/lib/decompress/zstd_ddict.h b/src/dependencies/zstd-1.5.6/lib/decompress/zstd_ddict.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/decompress/zstd_ddict.h rename to src/dependencies/zstd-1.5.6/lib/decompress/zstd_ddict.h diff --git a/src/dependencies/zstd-1.5.4/lib/decompress/zstd_decompress.c b/src/dependencies/zstd-1.5.6/lib/decompress/zstd_decompress.c similarity index 93% rename from src/dependencies/zstd-1.5.4/lib/decompress/zstd_decompress.c rename to src/dependencies/zstd-1.5.6/lib/decompress/zstd_decompress.c index d487966..2f03cf7 100644 --- a/src/dependencies/zstd-1.5.4/lib/decompress/zstd_decompress.c +++ b/src/dependencies/zstd-1.5.6/lib/decompress/zstd_decompress.c @@ -56,16 +56,18 @@ * Dependencies *********************************************************/ #include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */ +#include "../common/error_private.h" +#include "../common/zstd_internal.h" /* blockProperties_t */ #include "../common/mem.h" /* low level memory routines */ +#include "../common/bits.h" /* ZSTD_highbit32 */ #define FSE_STATIC_LINKING_ONLY #include "../common/fse.h" #include "../common/huf.h" #include "../common/xxhash.h" /* XXH64_reset, XXH64_update, XXH64_digest, XXH64 */ -#include "../common/zstd_internal.h" /* blockProperties_t */ #include "zstd_decompress_internal.h" /* ZSTD_DCtx */ #include "zstd_ddict.h" /* ZSTD_DDictDictContent */ #include "zstd_decompress_block.h" /* ZSTD_decompressBlock_internal */ -#include "../common/bits.h" /* ZSTD_highbit32 */ #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) # include "../legacy/zstd_legacy.h" @@ -244,6 +246,7 @@ static void ZSTD_DCtx_resetParameters(ZSTD_DCtx* dctx) dctx->forceIgnoreChecksum = ZSTD_d_validateChecksum; dctx->refMultipleDDicts = ZSTD_rmd_refSingleDDict; dctx->disableHufAsm = 0; + dctx->maxBlockSizeParam = 0; } static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx) @@ -264,6 +267,7 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx) #endif dctx->noForwardProgress = 0; dctx->oversizedDuration = 0; + dctx->isFrameDecompression = 1; #if DYNAMIC_BMI2 dctx->bmi2 = ZSTD_cpuSupportsBmi2(); #endif @@ -588,49 +592,52 @@ static size_t readSkippableFrameSize(void const* src, size_t srcSize) sizeU32 = MEM_readLE32((BYTE const*)src + ZSTD_FRAMEIDSIZE); RETURN_ERROR_IF((U32)(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE) < sizeU32, frameParameter_unsupported, ""); - { - size_t const skippableSize = skippableHeaderSize + sizeU32; + { size_t const skippableSize = skippableHeaderSize + sizeU32; RETURN_ERROR_IF(skippableSize > srcSize, srcSize_wrong, ""); return skippableSize; } } /*! ZSTD_readSkippableFrame() : - * Retrieves a zstd skippable frame containing data given by src, and writes it to dst buffer. + * Retrieves content of a skippable frame, and writes it to dst buffer. * * The parameter magicVariant will receive the magicVariant that was supplied when the frame was written, * i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested * in the magicVariant. * - * Returns an error if destination buffer is not large enough, or if the frame is not skippable. + * Returns an error if destination buffer is not large enough, or if this is not a valid skippable frame. * * @return : number of bytes written or a ZSTD error. */ -ZSTDLIB_API size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, unsigned* magicVariant, - const void* src, size_t srcSize) +size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, + unsigned* magicVariant, /* optional, can be NULL */ + const void* src, size_t srcSize) { - U32 const magicNumber = MEM_readLE32(src); - size_t skippableFrameSize = readSkippableFrameSize(src, srcSize); - size_t skippableContentSize = skippableFrameSize - ZSTD_SKIPPABLEHEADERSIZE; + RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong, ""); - /* check input validity */ - RETURN_ERROR_IF(!ZSTD_isSkippableFrame(src, srcSize), frameParameter_unsupported, ""); - RETURN_ERROR_IF(skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize, srcSize_wrong, ""); - RETURN_ERROR_IF(skippableContentSize > dstCapacity, dstSize_tooSmall, ""); + { U32 const magicNumber = MEM_readLE32(src); + size_t skippableFrameSize = readSkippableFrameSize(src, srcSize); + size_t skippableContentSize = skippableFrameSize - ZSTD_SKIPPABLEHEADERSIZE; - /* deliver payload */ - if (skippableContentSize > 0 && dst != NULL) - ZSTD_memcpy(dst, (const BYTE *)src + ZSTD_SKIPPABLEHEADERSIZE, skippableContentSize); - if (magicVariant != NULL) - *magicVariant = magicNumber - ZSTD_MAGIC_SKIPPABLE_START; - return skippableContentSize; + /* check input validity */ + RETURN_ERROR_IF(!ZSTD_isSkippableFrame(src, srcSize), frameParameter_unsupported, ""); + RETURN_ERROR_IF(skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize, srcSize_wrong, ""); + RETURN_ERROR_IF(skippableContentSize > dstCapacity, dstSize_tooSmall, ""); + + /* deliver payload */ + if (skippableContentSize > 0 && dst != NULL) + ZSTD_memcpy(dst, (const BYTE *)src + ZSTD_SKIPPABLEHEADERSIZE, skippableContentSize); + if (magicVariant != NULL) + *magicVariant = magicNumber - ZSTD_MAGIC_SKIPPABLE_START; + return skippableContentSize; + } } /** ZSTD_findDecompressedSize() : - * compatible with legacy mode * `srcSize` must be the exact length of some number of ZSTD compressed and/or * skippable frames - * @return : decompressed size of the frames contained */ + * note: compatible with legacy mode + * @return : decompressed size of the frames contained */ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize) { unsigned long long totalDstSize = 0; @@ -640,9 +647,7 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize) if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { size_t const skippableSize = readSkippableFrameSize(src, srcSize); - if (ZSTD_isError(skippableSize)) { - return ZSTD_CONTENTSIZE_ERROR; - } + if (ZSTD_isError(skippableSize)) return ZSTD_CONTENTSIZE_ERROR; assert(skippableSize <= srcSize); src = (const BYTE *)src + skippableSize; @@ -650,17 +655,17 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize) continue; } - { unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize); - if (ret >= ZSTD_CONTENTSIZE_ERROR) return ret; + { unsigned long long const fcs = ZSTD_getFrameContentSize(src, srcSize); + if (fcs >= ZSTD_CONTENTSIZE_ERROR) return fcs; - /* check for overflow */ - if (totalDstSize + ret < totalDstSize) return ZSTD_CONTENTSIZE_ERROR; - totalDstSize += ret; + if (totalDstSize + fcs < totalDstSize) + return ZSTD_CONTENTSIZE_ERROR; /* check for overflow */ + totalDstSize += fcs; } + /* skip to next frame */ { size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize); - if (ZSTD_isError(frameSrcSize)) { - return ZSTD_CONTENTSIZE_ERROR; - } + if (ZSTD_isError(frameSrcSize)) return ZSTD_CONTENTSIZE_ERROR; + assert(frameSrcSize <= srcSize); src = (const BYTE *)src + frameSrcSize; srcSize -= frameSrcSize; @@ -724,17 +729,17 @@ static ZSTD_frameSizeInfo ZSTD_errorFrameSizeInfo(size_t ret) return frameSizeInfo; } -static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize) +static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize, ZSTD_format_e format) { ZSTD_frameSizeInfo frameSizeInfo; ZSTD_memset(&frameSizeInfo, 0, sizeof(ZSTD_frameSizeInfo)); #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) - if (ZSTD_isLegacy(src, srcSize)) + if (format == ZSTD_f_zstd1 && ZSTD_isLegacy(src, srcSize)) return ZSTD_findFrameSizeInfoLegacy(src, srcSize); #endif - if ((srcSize >= ZSTD_SKIPPABLEHEADERSIZE) + if (format == ZSTD_f_zstd1 && (srcSize >= ZSTD_SKIPPABLEHEADERSIZE) && (MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { frameSizeInfo.compressedSize = readSkippableFrameSize(src, srcSize); assert(ZSTD_isError(frameSizeInfo.compressedSize) || @@ -748,7 +753,7 @@ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize ZSTD_frameHeader zfh; /* Extract Frame Header */ - { size_t const ret = ZSTD_getFrameHeader(&zfh, src, srcSize); + { size_t const ret = ZSTD_getFrameHeader_advanced(&zfh, src, srcSize, format); if (ZSTD_isError(ret)) return ZSTD_errorFrameSizeInfo(ret); if (ret > 0) @@ -791,15 +796,17 @@ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize } } +static size_t ZSTD_findFrameCompressedSize_advanced(const void *src, size_t srcSize, ZSTD_format_e format) { + ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, format); + return frameSizeInfo.compressedSize; +} + /** ZSTD_findFrameCompressedSize() : - * compatible with legacy mode - * `src` must point to the start of a ZSTD frame, ZSTD legacy frame, or skippable frame - * `srcSize` must be at least as large as the frame contained - * @return : the compressed size of the frame starting at `src` */ + * See docs in zstd.h + * Note: compatible with legacy mode */ size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize) { - ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize); - return frameSizeInfo.compressedSize; + return ZSTD_findFrameCompressedSize_advanced(src, srcSize, ZSTD_f_zstd1); } /** ZSTD_decompressBound() : @@ -813,7 +820,7 @@ unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize) unsigned long long bound = 0; /* Iterate over each frame */ while (srcSize > 0) { - ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize); + ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, ZSTD_f_zstd1); size_t const compressedSize = frameSizeInfo.compressedSize; unsigned long long const decompressedBound = frameSizeInfo.decompressedBound; if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR) @@ -833,7 +840,7 @@ size_t ZSTD_decompressionMargin(void const* src, size_t srcSize) /* Iterate over each frame */ while (srcSize > 0) { - ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize); + ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, ZSTD_f_zstd1); size_t const compressedSize = frameSizeInfo.compressedSize; unsigned long long const decompressedBound = frameSizeInfo.decompressedBound; ZSTD_frameHeader zfh; @@ -969,6 +976,10 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx, ip += frameHeaderSize; remainingSrcSize -= frameHeaderSize; } + /* Shrink the blockSizeMax if enabled */ + if (dctx->maxBlockSizeParam != 0) + dctx->fParams.blockSizeMax = MIN(dctx->fParams.blockSizeMax, (unsigned)dctx->maxBlockSizeParam); + /* Loop on each block */ while (1) { BYTE* oBlockEnd = oend; @@ -1001,7 +1012,8 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx, switch(blockProperties.blockType) { case bt_compressed: - decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oBlockEnd-op), ip, cBlockSize, /* frame */ 1, not_streaming); + assert(dctx->isFrameDecompression == 1); + decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oBlockEnd-op), ip, cBlockSize, not_streaming); break; case bt_raw : /* Use oend instead of oBlockEnd because this function is safe to overlap. It uses memmove. */ @@ -1014,12 +1026,14 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx, default: RETURN_ERROR(corruption_detected, "invalid block type"); } - - if (ZSTD_isError(decodedSize)) return decodedSize; - if (dctx->validateChecksum) + FORWARD_IF_ERROR(decodedSize, "Block decompression failure"); + DEBUGLOG(5, "Decompressed block of dSize = %u", (unsigned)decodedSize); + if (dctx->validateChecksum) { XXH64_update(&dctx->xxhState, op, decodedSize); - if (decodedSize != 0) + } + if (decodedSize) /* support dst = NULL,0 */ { op += decodedSize; + } assert(ip != NULL); ip += cBlockSize; remainingSrcSize -= cBlockSize; @@ -1049,7 +1063,9 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx, return (size_t)(op-ostart); } -static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, const void* dict, size_t dictSize, @@ -1069,7 +1085,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, while (srcSize >= ZSTD_startingInputLength(dctx->format)) { #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) - if (ZSTD_isLegacy(src, srcSize)) { + if (dctx->format == ZSTD_f_zstd1 && ZSTD_isLegacy(src, srcSize)) { size_t decodedSize; size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize); if (ZSTD_isError(frameSize)) return frameSize; @@ -1079,6 +1095,15 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize); if (ZSTD_isError(decodedSize)) return decodedSize; + { + unsigned long long const expectedSize = ZSTD_getFrameContentSize(src, srcSize); + RETURN_ERROR_IF(expectedSize == ZSTD_CONTENTSIZE_ERROR, corruption_detected, "Corrupted frame header!"); + if (expectedSize != ZSTD_CONTENTSIZE_UNKNOWN) { + RETURN_ERROR_IF(expectedSize != decodedSize, corruption_detected, + "Frame header size does not match decoded size!"); + } + } + assert(decodedSize <= dstCapacity); dst = (BYTE*)dst + decodedSize; dstCapacity -= decodedSize; @@ -1090,17 +1115,18 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, } #endif - { U32 const magicNumber = MEM_readLE32(src); - DEBUGLOG(4, "reading magic number %08X (expecting %08X)", - (unsigned)magicNumber, ZSTD_MAGICNUMBER); + if (dctx->format == ZSTD_f_zstd1 && srcSize >= 4) { + U32 const magicNumber = MEM_readLE32(src); + DEBUGLOG(5, "reading magic number %08X", (unsigned)magicNumber); if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { + /* skippable frame detected : skip it */ size_t const skippableSize = readSkippableFrameSize(src, srcSize); - FORWARD_IF_ERROR(skippableSize, "readSkippableFrameSize failed"); + FORWARD_IF_ERROR(skippableSize, "invalid skippable frame"); assert(skippableSize <= srcSize); src = (const BYTE *)src + skippableSize; srcSize -= skippableSize; - continue; + continue; /* check next frame */ } } if (ddict) { @@ -1316,7 +1342,8 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c { case bt_compressed: DEBUGLOG(5, "ZSTD_decompressContinue: case bt_compressed"); - rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 1, is_streaming); + assert(dctx->isFrameDecompression == 1); + rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, is_streaming); dctx->expected = 0; /* Streaming not supported */ break; case bt_raw : @@ -1385,6 +1412,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c case ZSTDds_decodeSkippableHeader: assert(src != NULL); assert(srcSize <= ZSTD_SKIPPABLEHEADERSIZE); + assert(dctx->format != ZSTD_f_zstd1_magicless); ZSTD_memcpy(dctx->headerBuffer + (ZSTD_SKIPPABLEHEADERSIZE - srcSize), src, srcSize); /* complete skippable header */ dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_FRAMEIDSIZE); /* note : dctx->expected can grow seriously large, beyond local buffer size */ dctx->stage = ZSTDds_skipFrame; @@ -1545,6 +1573,7 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx) dctx->litEntropy = dctx->fseEntropy = 0; dctx->dictID = 0; dctx->bType = bt_reserved; + dctx->isFrameDecompression = 1; ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue)); ZSTD_memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */ dctx->LLTptr = dctx->entropy.LLTable; @@ -1816,6 +1845,10 @@ ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam) bounds.lowerBound = 0; bounds.upperBound = 1; return bounds; + case ZSTD_d_maxBlockSize: + bounds.lowerBound = ZSTD_BLOCKSIZE_MAX_MIN; + bounds.upperBound = ZSTD_BLOCKSIZE_MAX; + return bounds; default:; } @@ -1860,6 +1893,9 @@ size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value case ZSTD_d_disableHuffmanAssembly: *value = (int)dctx->disableHufAsm; return 0; + case ZSTD_d_maxBlockSize: + *value = dctx->maxBlockSizeParam; + return 0; default:; } RETURN_ERROR(parameter_unsupported, ""); @@ -1897,6 +1933,10 @@ size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value CHECK_DBOUNDS(ZSTD_d_disableHuffmanAssembly, value); dctx->disableHufAsm = value != 0; return 0; + case ZSTD_d_maxBlockSize: + if (value != 0) CHECK_DBOUNDS(ZSTD_d_maxBlockSize, value); + dctx->maxBlockSizeParam = value; + return 0; default:; } RETURN_ERROR(parameter_unsupported, ""); @@ -1908,6 +1948,7 @@ size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset) || (reset == ZSTD_reset_session_and_parameters) ) { dctx->streamStage = zdss_init; dctx->noForwardProgress = 0; + dctx->isFrameDecompression = 1; } if ( (reset == ZSTD_reset_parameters) || (reset == ZSTD_reset_session_and_parameters) ) { @@ -1924,11 +1965,17 @@ size_t ZSTD_sizeof_DStream(const ZSTD_DStream* dctx) return ZSTD_sizeof_DCtx(dctx); } -size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize) +static size_t ZSTD_decodingBufferSize_internal(unsigned long long windowSize, unsigned long long frameContentSize, size_t blockSizeMax) { - size_t const blockSize = (size_t) MIN(windowSize, ZSTD_BLOCKSIZE_MAX); - /* space is needed to store the litbuffer after the output of a given block without stomping the extDict of a previous run, as well as to cover both windows against wildcopy*/ - unsigned long long const neededRBSize = windowSize + blockSize + ZSTD_BLOCKSIZE_MAX + (WILDCOPY_OVERLENGTH * 2); + size_t const blockSize = MIN((size_t)MIN(windowSize, ZSTD_BLOCKSIZE_MAX), blockSizeMax); + /* We need blockSize + WILDCOPY_OVERLENGTH worth of buffer so that if a block + * ends at windowSize + WILDCOPY_OVERLENGTH + 1 bytes, we can start writing + * the block at the beginning of the output buffer, and maintain a full window. + * + * We need another blockSize worth of buffer so that we can store split + * literals at the end of the block without overwriting the extDict window. + */ + unsigned long long const neededRBSize = windowSize + (blockSize * 2) + (WILDCOPY_OVERLENGTH * 2); unsigned long long const neededSize = MIN(frameContentSize, neededRBSize); size_t const minRBSize = (size_t) neededSize; RETURN_ERROR_IF((unsigned long long)minRBSize != neededSize, @@ -1936,6 +1983,11 @@ size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long return minRBSize; } +size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize) +{ + return ZSTD_decodingBufferSize_internal(windowSize, frameContentSize, ZSTD_BLOCKSIZE_MAX); +} + size_t ZSTD_estimateDStreamSize(size_t windowSize) { size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_MAX); @@ -2131,12 +2183,12 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB if (zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN && zds->fParams.frameType != ZSTD_skippableFrame && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) { - size_t const cSize = ZSTD_findFrameCompressedSize(istart, (size_t)(iend-istart)); + size_t const cSize = ZSTD_findFrameCompressedSize_advanced(istart, (size_t)(iend-istart), zds->format); if (cSize <= (size_t)(iend-istart)) { /* shortcut : using single-pass mode */ size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, (size_t)(oend-op), istart, cSize, ZSTD_getDDict(zds)); if (ZSTD_isError(decompressedSize)) return decompressedSize; - DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()") + DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()"); assert(istart != NULL); ip = istart + cSize; op = op ? op + decompressedSize : op; /* can occur if frameContentSize = 0 (empty frame) */ @@ -2158,7 +2210,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB DEBUGLOG(4, "Consume header"); FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(zds, ZSTD_getDDict(zds)), ""); - if ((MEM_readLE32(zds->headerBuffer) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */ + if (zds->format == ZSTD_f_zstd1 + && (MEM_readLE32(zds->headerBuffer) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */ zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_FRAMEIDSIZE); zds->stage = ZSTDds_skipFrame; } else { @@ -2174,11 +2227,13 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN); RETURN_ERROR_IF(zds->fParams.windowSize > zds->maxWindowSize, frameParameter_windowTooLarge, ""); + if (zds->maxBlockSizeParam != 0) + zds->fParams.blockSizeMax = MIN(zds->fParams.blockSizeMax, (unsigned)zds->maxBlockSizeParam); /* Adapt buffer sizes to frame header instructions */ { size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */); size_t const neededOutBuffSize = zds->outBufferMode == ZSTD_bm_buffered - ? ZSTD_decodingBufferSize_min(zds->fParams.windowSize, zds->fParams.frameContentSize) + ? ZSTD_decodingBufferSize_internal(zds->fParams.windowSize, zds->fParams.frameContentSize, zds->fParams.blockSizeMax) : 0; ZSTD_DCtx_updateOversizedDuration(zds, neededInBuffSize, neededOutBuffSize); diff --git a/src/dependencies/zstd-1.5.4/lib/decompress/zstd_decompress_block.c b/src/dependencies/zstd-1.5.6/lib/decompress/zstd_decompress_block.c similarity index 86% rename from src/dependencies/zstd-1.5.4/lib/decompress/zstd_decompress_block.c rename to src/dependencies/zstd-1.5.6/lib/decompress/zstd_decompress_block.c index 0a06a02..76d7332 100644 --- a/src/dependencies/zstd-1.5.4/lib/decompress/zstd_decompress_block.c +++ b/src/dependencies/zstd-1.5.6/lib/decompress/zstd_decompress_block.c @@ -51,6 +51,13 @@ static void ZSTD_copy4(void* dst, const void* src) { ZSTD_memcpy(dst, src, 4); } * Block decoding ***************************************************************/ +static size_t ZSTD_blockSizeMax(ZSTD_DCtx const* dctx) +{ + size_t const blockSizeMax = dctx->isFrameDecompression ? dctx->fParams.blockSizeMax : ZSTD_BLOCKSIZE_MAX; + assert(blockSizeMax <= ZSTD_BLOCKSIZE_MAX); + return blockSizeMax; +} + /*! ZSTD_getcBlockSize() : * Provides the size of compressed block from block header `src` */ size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, @@ -73,41 +80,49 @@ size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, static void ZSTD_allocateLiteralsBuffer(ZSTD_DCtx* dctx, void* const dst, const size_t dstCapacity, const size_t litSize, const streaming_operation streaming, const size_t expectedWriteSize, const unsigned splitImmediately) { - if (streaming == not_streaming && dstCapacity > ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH + litSize + WILDCOPY_OVERLENGTH) - { - /* room for litbuffer to fit without read faulting */ - dctx->litBuffer = (BYTE*)dst + ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH; + size_t const blockSizeMax = ZSTD_blockSizeMax(dctx); + assert(litSize <= blockSizeMax); + assert(dctx->isFrameDecompression || streaming == not_streaming); + assert(expectedWriteSize <= blockSizeMax); + if (streaming == not_streaming && dstCapacity > blockSizeMax + WILDCOPY_OVERLENGTH + litSize + WILDCOPY_OVERLENGTH) { + /* If we aren't streaming, we can just put the literals after the output + * of the current block. We don't need to worry about overwriting the + * extDict of our window, because it doesn't exist. + * So if we have space after the end of the block, just put it there. + */ + dctx->litBuffer = (BYTE*)dst + blockSizeMax + WILDCOPY_OVERLENGTH; dctx->litBufferEnd = dctx->litBuffer + litSize; dctx->litBufferLocation = ZSTD_in_dst; - } - else if (litSize > ZSTD_LITBUFFEREXTRASIZE) - { - /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */ + } else if (litSize <= ZSTD_LITBUFFEREXTRASIZE) { + /* Literals fit entirely within the extra buffer, put them there to avoid + * having to split the literals. + */ + dctx->litBuffer = dctx->litExtraBuffer; + dctx->litBufferEnd = dctx->litBuffer + litSize; + dctx->litBufferLocation = ZSTD_not_in_dst; + } else { + assert(blockSizeMax > ZSTD_LITBUFFEREXTRASIZE); + /* Literals must be split between the output block and the extra lit + * buffer. We fill the extra lit buffer with the tail of the literals, + * and put the rest of the literals at the end of the block, with + * WILDCOPY_OVERLENGTH of buffer room to allow for overreads. + * This MUST not write more than our maxBlockSize beyond dst, because in + * streaming mode, that could overwrite part of our extDict window. + */ if (splitImmediately) { /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */ dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH; dctx->litBufferEnd = dctx->litBuffer + litSize - ZSTD_LITBUFFEREXTRASIZE; - } - else { + } else { /* initially this will be stored entirely in dst during huffman decoding, it will partially be shifted to litExtraBuffer after */ dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize; dctx->litBufferEnd = (BYTE*)dst + expectedWriteSize; } dctx->litBufferLocation = ZSTD_split; - } - else - { - /* fits entirely within litExtraBuffer, so no split is necessary */ - dctx->litBuffer = dctx->litExtraBuffer; - dctx->litBufferEnd = dctx->litBuffer + litSize; - dctx->litBufferLocation = ZSTD_not_in_dst; + assert(dctx->litBufferEnd <= (BYTE*)dst + expectedWriteSize); } } -/* Hidden declaration for fullbench */ -size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, - const void* src, size_t srcSize, - void* dst, size_t dstCapacity, const streaming_operation streaming); /*! ZSTD_decodeLiteralsBlock() : * Where it is possible to do so without being stomped by the output during decompression, the literals block will be stored * in the dstBuffer. If there is room to do so, it will be stored in full in the excess dst space after where the current @@ -116,7 +131,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, * * @return : nb of bytes read from src (< srcSize ) * note : symbol not declared but exposed for fullbench */ -size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, +static size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, const void* src, size_t srcSize, /* note : srcSize < BLOCKSIZE */ void* dst, size_t dstCapacity, const streaming_operation streaming) { @@ -125,6 +140,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, { const BYTE* const istart = (const BYTE*) src; symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3); + size_t const blockSizeMax = ZSTD_blockSizeMax(dctx); switch(litEncType) { @@ -140,7 +156,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, U32 const lhlCode = (istart[0] >> 2) & 3; U32 const lhc = MEM_readLE32(istart); size_t hufSuccess; - size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity); + size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity); int const flags = 0 | (ZSTD_DCtx_get_bmi2(dctx) ? HUF_flags_bmi2 : 0) | (dctx->disableHufAsm ? HUF_flags_disableAsm : 0); @@ -167,7 +183,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, break; } RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled"); - RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, ""); + RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, ""); if (!singleStream) RETURN_ERROR_IF(litSize < MIN_LITERALS_FOR_4_STREAMS, literals_headerWrong, "Not enough literals (%zu) for the 4-streams mode (min %u)", @@ -214,10 +230,12 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, } if (dctx->litBufferLocation == ZSTD_split) { + assert(litSize > ZSTD_LITBUFFEREXTRASIZE); ZSTD_memcpy(dctx->litExtraBuffer, dctx->litBufferEnd - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE); ZSTD_memmove(dctx->litBuffer + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH, dctx->litBuffer, litSize - ZSTD_LITBUFFEREXTRASIZE); dctx->litBuffer += ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH; dctx->litBufferEnd -= WILDCOPY_OVERLENGTH; + assert(dctx->litBufferEnd <= (BYTE*)dst + blockSizeMax); } RETURN_ERROR_IF(HUF_isError(hufSuccess), corruption_detected, ""); @@ -232,7 +250,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, case set_basic: { size_t litSize, lhSize; U32 const lhlCode = ((istart[0]) >> 2) & 3; - size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity); + size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity); switch(lhlCode) { case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */ @@ -251,6 +269,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, } RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled"); + RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, ""); RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, ""); ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1); if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */ @@ -279,7 +298,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, case set_rle: { U32 const lhlCode = ((istart[0]) >> 2) & 3; size_t litSize, lhSize; - size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity); + size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity); switch(lhlCode) { case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */ @@ -298,7 +317,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, break; } RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled"); - RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, ""); + RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, ""); RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, ""); ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1); if (dctx->litBufferLocation == ZSTD_split) @@ -320,6 +339,18 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, } } +/* Hidden declaration for fullbench */ +size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx, + const void* src, size_t srcSize, + void* dst, size_t dstCapacity); +size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx, + const void* src, size_t srcSize, + void* dst, size_t dstCapacity) +{ + dctx->isFrameDecompression = 0; + return ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, not_streaming); +} + /* Default FSE distribution tables. * These are pre-calculated FSE decoding tables using default distributions as defined in specification : * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#default-distributions @@ -675,11 +706,6 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, /* SeqHead */ nbSeq = *ip++; - if (!nbSeq) { - *nbSeqPtr=0; - RETURN_ERROR_IF(srcSize != 1, srcSize_wrong, ""); - return 1; - } if (nbSeq > 0x7F) { if (nbSeq == 0xFF) { RETURN_ERROR_IF(ip+2 > iend, srcSize_wrong, ""); @@ -692,8 +718,16 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, } *nbSeqPtr = nbSeq; + if (nbSeq == 0) { + /* No sequence : section ends immediately */ + RETURN_ERROR_IF(ip != iend, corruption_detected, + "extraneous data present in the Sequences section"); + return (size_t)(ip - istart); + } + /* FSE table descriptors */ RETURN_ERROR_IF(ip+1 > iend, srcSize_wrong, ""); /* minimum possible size: 1 byte for symbol encoding types */ + RETURN_ERROR_IF(*ip & 3, corruption_detected, ""); /* The last field, Reserved, must be all-zeroes. */ { symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6); symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3); symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3); @@ -840,7 +874,7 @@ static void ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, pt /* ZSTD_safecopyDstBeforeSrc(): * This version allows overlap with dst before src, or handles the non-overlap case with dst after src * Kept separate from more common ZSTD_safecopy case to avoid performance impact to the safecopy common case */ -static void ZSTD_safecopyDstBeforeSrc(BYTE* op, BYTE const* ip, ptrdiff_t length) { +static void ZSTD_safecopyDstBeforeSrc(BYTE* op, const BYTE* ip, ptrdiff_t length) { ptrdiff_t const diff = op - ip; BYTE* const oend = op + length; @@ -869,6 +903,7 @@ static void ZSTD_safecopyDstBeforeSrc(BYTE* op, BYTE const* ip, ptrdiff_t length * to be optimized for many small sequences, since those fall into ZSTD_execSequence(). */ FORCE_NOINLINE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR size_t ZSTD_execSequenceEnd(BYTE* op, BYTE* const oend, seq_t sequence, const BYTE** litPtr, const BYTE* const litLimit, @@ -916,6 +951,7 @@ size_t ZSTD_execSequenceEnd(BYTE* op, * This version is intended to be used during instances where the litBuffer is still split. It is kept separate to avoid performance impact for the good case. */ FORCE_NOINLINE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op, BYTE* const oend, const BYTE* const oend_w, seq_t sequence, const BYTE** litPtr, const BYTE* const litLimit, @@ -961,6 +997,7 @@ size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op, } HINT_INLINE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR size_t ZSTD_execSequence(BYTE* op, BYTE* const oend, seq_t sequence, const BYTE** litPtr, const BYTE* const litLimit, @@ -1059,6 +1096,7 @@ size_t ZSTD_execSequence(BYTE* op, } HINT_INLINE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op, BYTE* const oend, const BYTE* const oend_w, seq_t sequence, const BYTE** litPtr, const BYTE* const litLimit, @@ -1181,14 +1219,20 @@ ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, U16 typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e; +/** + * ZSTD_decodeSequence(): + * @p longOffsets : tells the decoder to reload more bit while decoding large offsets + * only used in 32-bit mode + * @return : Sequence (litL + matchL + offset) + */ FORCE_INLINE_TEMPLATE seq_t -ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) +ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, const int isLastSeq) { seq_t seq; /* - * ZSTD_seqSymbol is a structure with a total of 64 bits wide. So it can be - * loaded in one operation and extracted its fields by simply shifting or - * bit-extracting on aarch64. + * ZSTD_seqSymbol is a 64 bits wide structure. + * It can be loaded in one operation + * and its fields extracted by simply shifting or bit-extracting on aarch64. * GCC doesn't recognize this and generates more unnecessary ldr/ldrb/ldrh * operations that cause performance drop. This can be avoided by using this * ZSTD_memcpy hack. @@ -1232,11 +1276,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) /* sequence */ { size_t offset; - #if defined(__clang__) - if (LIKELY(ofBits > 1)) { - #else if (ofBits > 1) { - #endif ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1); ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5); ZSTD_STATIC_ASSERT(STREAM_ACCUMULATOR_MIN_32 > LONG_OFFSETS_MAX_EXTRA_BITS_32); @@ -1265,7 +1305,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) } else { offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1); { size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; - temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ + temp -= !temp; /* 0 is not valid: input corrupted => force offset to -1 => corruption detected at execSequence */ if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; seqState->prevOffset[1] = seqState->prevOffset[0]; seqState->prevOffset[0] = offset = temp; @@ -1273,11 +1313,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) seq.offset = offset; } - #if defined(__clang__) - if (UNLIKELY(mlBits > 0)) - #else if (mlBits > 0) - #endif seq.matchLength += BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/); if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32)) @@ -1287,11 +1323,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) /* Ensure there are enough bits to read the rest of data in 64-bit mode. */ ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64); - #if defined(__clang__) - if (UNLIKELY(llBits > 0)) - #else if (llBits > 0) - #endif seq.litLength += BIT_readBitsFast(&seqState->DStream, llBits/*>0*/); if (MEM_32bits()) @@ -1300,17 +1332,22 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u", (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); - ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */ - ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */ - if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ - ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofNext, ofnbBits); /* <= 8 bits */ + if (!isLastSeq) { + /* don't update FSE state for last Sequence */ + ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */ + ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ + ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofNext, ofnbBits); /* <= 8 bits */ + BIT_reloadDStream(&seqState->DStream); + } } return seq; } -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -MEM_STATIC int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefixStart, BYTE const* oLitEnd) +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) +#if DEBUGLEVEL >= 1 +static int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefixStart, BYTE const* oLitEnd) { size_t const windowSize = dctx->fParams.windowSize; /* No dictionary used. */ @@ -1324,30 +1361,33 @@ MEM_STATIC int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefix /* Dictionary is active. */ return 1; } +#endif -MEM_STATIC void ZSTD_assertValidSequence( +static void ZSTD_assertValidSequence( ZSTD_DCtx const* dctx, BYTE const* op, BYTE const* oend, seq_t const seq, BYTE const* prefixStart, BYTE const* virtualStart) { #if DEBUGLEVEL >= 1 - size_t const windowSize = dctx->fParams.windowSize; - size_t const sequenceSize = seq.litLength + seq.matchLength; - BYTE const* const oLitEnd = op + seq.litLength; - DEBUGLOG(6, "Checking sequence: litL=%u matchL=%u offset=%u", - (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); - assert(op <= oend); - assert((size_t)(oend - op) >= sequenceSize); - assert(sequenceSize <= ZSTD_BLOCKSIZE_MAX); - if (ZSTD_dictionaryIsActive(dctx, prefixStart, oLitEnd)) { - size_t const dictSize = (size_t)((char const*)dctx->dictContentEndForFuzzing - (char const*)dctx->dictContentBeginForFuzzing); - /* Offset must be within the dictionary. */ - assert(seq.offset <= (size_t)(oLitEnd - virtualStart)); - assert(seq.offset <= windowSize + dictSize); - } else { - /* Offset must be within our window. */ - assert(seq.offset <= windowSize); + if (dctx->isFrameDecompression) { + size_t const windowSize = dctx->fParams.windowSize; + size_t const sequenceSize = seq.litLength + seq.matchLength; + BYTE const* const oLitEnd = op + seq.litLength; + DEBUGLOG(6, "Checking sequence: litL=%u matchL=%u offset=%u", + (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); + assert(op <= oend); + assert((size_t)(oend - op) >= sequenceSize); + assert(sequenceSize <= ZSTD_blockSizeMax(dctx)); + if (ZSTD_dictionaryIsActive(dctx, prefixStart, oLitEnd)) { + size_t const dictSize = (size_t)((char const*)dctx->dictContentEndForFuzzing - (char const*)dctx->dictContentBeginForFuzzing); + /* Offset must be within the dictionary. */ + assert(seq.offset <= (size_t)(oLitEnd - virtualStart)); + assert(seq.offset <= windowSize + dictSize); + } else { + /* Offset must be within our window. */ + assert(seq.offset <= windowSize); + } } #else (void)dctx, (void)op, (void)oend, (void)seq, (void)prefixStart, (void)virtualStart; @@ -1363,23 +1403,21 @@ DONT_VECTORIZE ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset, - const int frame) + const ZSTD_longOffset_e isLongOffset) { const BYTE* ip = (const BYTE*)seqStart; const BYTE* const iend = ip + seqSize; BYTE* const ostart = (BYTE*)dst; - BYTE* const oend = ostart + maxDstSize; + BYTE* const oend = ZSTD_maybeNullPtrAdd(ostart, maxDstSize); BYTE* op = ostart; const BYTE* litPtr = dctx->litPtr; const BYTE* litBufferEnd = dctx->litBufferEnd; const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart); const BYTE* const vBase = (const BYTE*) (dctx->virtualStart); const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); - DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer"); - (void)frame; + DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer (%i seqs)", nbSeq); - /* Regen sequences */ + /* Literals are split between internal buffer & output buffer */ if (nbSeq) { seqState_t seqState; dctx->fseEntropy = 1; @@ -1398,8 +1436,7 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx, BIT_DStream_completed < BIT_DStream_overflow); /* decompress without overrunning litPtr begins */ - { - seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset); + { seq_t sequence = {0,0,0}; /* some static analyzer believe that @sequence is not initialized (it necessarily is, since for(;;) loop as at least one iteration) */ /* Align the decompression loop to 32 + 16 bytes. * * zstd compiled with gcc-9 on an Intel i9-9900k shows 10% decompression @@ -1461,27 +1498,26 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx, #endif /* Handle the initial state where litBuffer is currently split between dst and litExtraBuffer */ - for (; litPtr + sequence.litLength <= dctx->litBufferEnd; ) { - size_t const oneSeqSize = ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence.litLength - WILDCOPY_OVERLENGTH, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); + for ( ; nbSeq; nbSeq--) { + sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1); + if (litPtr + sequence.litLength > dctx->litBufferEnd) break; + { size_t const oneSeqSize = ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence.litLength - WILDCOPY_OVERLENGTH, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) - assert(!ZSTD_isError(oneSeqSize)); - if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); #endif - if (UNLIKELY(ZSTD_isError(oneSeqSize))) - return oneSeqSize; - DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); - op += oneSeqSize; - if (UNLIKELY(!--nbSeq)) - break; - BIT_reloadDStream(&(seqState.DStream)); - sequence = ZSTD_decodeSequence(&seqState, isLongOffset); - } + if (UNLIKELY(ZSTD_isError(oneSeqSize))) + return oneSeqSize; + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + op += oneSeqSize; + } } + DEBUGLOG(6, "reached: (litPtr + sequence.litLength > dctx->litBufferEnd)"); /* If there are more sequences, they will need to read literals from litExtraBuffer; copy over the remainder from dst and update litPtr and litEnd */ if (nbSeq > 0) { const size_t leftoverLit = dctx->litBufferEnd - litPtr; - if (leftoverLit) - { + DEBUGLOG(6, "There are %i sequences left, and %zu/%zu literals left in buffer", nbSeq, leftoverLit, sequence.litLength); + if (leftoverLit) { RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer"); ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit); sequence.litLength -= leftoverLit; @@ -1490,24 +1526,22 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx, litPtr = dctx->litExtraBuffer; litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; dctx->litBufferLocation = ZSTD_not_in_dst; - { - size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); + { size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) assert(!ZSTD_isError(oneSeqSize)); - if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); + ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); #endif if (UNLIKELY(ZSTD_isError(oneSeqSize))) return oneSeqSize; DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); op += oneSeqSize; - if (--nbSeq) - BIT_reloadDStream(&(seqState.DStream)); } + nbSeq--; } } - if (nbSeq > 0) /* there is remaining lit from extra buffer */ - { + if (nbSeq > 0) { + /* there is remaining lit from extra buffer */ #if defined(__GNUC__) && defined(__x86_64__) __asm__(".p2align 6"); @@ -1526,35 +1560,34 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx, # endif #endif - for (; ; ) { - seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset); + for ( ; nbSeq ; nbSeq--) { + seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1); size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) assert(!ZSTD_isError(oneSeqSize)); - if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); + ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); #endif if (UNLIKELY(ZSTD_isError(oneSeqSize))) return oneSeqSize; DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); op += oneSeqSize; - if (UNLIKELY(!--nbSeq)) - break; - BIT_reloadDStream(&(seqState.DStream)); } } /* check if reached exact end */ DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer: after decode loop, remaining nbSeq : %i", nbSeq); RETURN_ERROR_IF(nbSeq, corruption_detected, ""); - RETURN_ERROR_IF(BIT_reloadDStream(&seqState.DStream) < BIT_DStream_completed, corruption_detected, ""); + DEBUGLOG(5, "bitStream : start=%p, ptr=%p, bitsConsumed=%u", seqState.DStream.start, seqState.DStream.ptr, seqState.DStream.bitsConsumed); + RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, ""); /* save reps for next block */ { U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); } } /* last literal segment */ - if (dctx->litBufferLocation == ZSTD_split) /* split hasn't been reached yet, first get dst then copy litExtraBuffer */ - { - size_t const lastLLSize = litBufferEnd - litPtr; + if (dctx->litBufferLocation == ZSTD_split) { + /* split hasn't been reached yet, first get dst then copy litExtraBuffer */ + size_t const lastLLSize = (size_t)(litBufferEnd - litPtr); + DEBUGLOG(6, "copy last literals from segment : %u", (U32)lastLLSize); RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, ""); if (op != NULL) { ZSTD_memmove(op, litPtr, lastLLSize); @@ -1564,15 +1597,17 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx, litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; dctx->litBufferLocation = ZSTD_not_in_dst; } - { size_t const lastLLSize = litBufferEnd - litPtr; + /* copy last literals from internal buffer */ + { size_t const lastLLSize = (size_t)(litBufferEnd - litPtr); + DEBUGLOG(6, "copy last literals from internal buffer : %u", (U32)lastLLSize); RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, ""); if (op != NULL) { ZSTD_memcpy(op, litPtr, lastLLSize); op += lastLLSize; - } - } + } } - return op-ostart; + DEBUGLOG(6, "decoded block of size %u bytes", (U32)(op - ostart)); + return (size_t)(op - ostart); } FORCE_INLINE_TEMPLATE size_t @@ -1580,13 +1615,12 @@ DONT_VECTORIZE ZSTD_decompressSequences_body(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset, - const int frame) + const ZSTD_longOffset_e isLongOffset) { const BYTE* ip = (const BYTE*)seqStart; const BYTE* const iend = ip + seqSize; BYTE* const ostart = (BYTE*)dst; - BYTE* const oend = dctx->litBufferLocation == ZSTD_not_in_dst ? ostart + maxDstSize : dctx->litBuffer; + BYTE* const oend = dctx->litBufferLocation == ZSTD_not_in_dst ? ZSTD_maybeNullPtrAdd(ostart, maxDstSize) : dctx->litBuffer; BYTE* op = ostart; const BYTE* litPtr = dctx->litPtr; const BYTE* const litEnd = litPtr + dctx->litSize; @@ -1594,7 +1628,6 @@ ZSTD_decompressSequences_body(ZSTD_DCtx* dctx, const BYTE* const vBase = (const BYTE*)(dctx->virtualStart); const BYTE* const dictEnd = (const BYTE*)(dctx->dictEnd); DEBUGLOG(5, "ZSTD_decompressSequences_body: nbSeq = %d", nbSeq); - (void)frame; /* Regen sequences */ if (nbSeq) { @@ -1609,11 +1642,6 @@ ZSTD_decompressSequences_body(ZSTD_DCtx* dctx, ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); assert(dst != NULL); - ZSTD_STATIC_ASSERT( - BIT_DStream_unfinished < BIT_DStream_completed && - BIT_DStream_endOfBuffer < BIT_DStream_completed && - BIT_DStream_completed < BIT_DStream_overflow); - #if defined(__GNUC__) && defined(__x86_64__) __asm__(".p2align 6"); __asm__("nop"); @@ -1628,73 +1656,70 @@ ZSTD_decompressSequences_body(ZSTD_DCtx* dctx, # endif #endif - for ( ; ; ) { - seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset); + for ( ; nbSeq ; nbSeq--) { + seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1); size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd); #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) assert(!ZSTD_isError(oneSeqSize)); - if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); + ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); #endif if (UNLIKELY(ZSTD_isError(oneSeqSize))) return oneSeqSize; DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); op += oneSeqSize; - if (UNLIKELY(!--nbSeq)) - break; - BIT_reloadDStream(&(seqState.DStream)); } /* check if reached exact end */ - DEBUGLOG(5, "ZSTD_decompressSequences_body: after decode loop, remaining nbSeq : %i", nbSeq); - RETURN_ERROR_IF(nbSeq, corruption_detected, ""); - RETURN_ERROR_IF(BIT_reloadDStream(&seqState.DStream) < BIT_DStream_completed, corruption_detected, ""); + assert(nbSeq == 0); + RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, ""); /* save reps for next block */ { U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); } } /* last literal segment */ - { size_t const lastLLSize = litEnd - litPtr; + { size_t const lastLLSize = (size_t)(litEnd - litPtr); + DEBUGLOG(6, "copy last literals : %u", (U32)lastLLSize); RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, ""); if (op != NULL) { ZSTD_memcpy(op, litPtr, lastLLSize); op += lastLLSize; - } - } + } } - return op-ostart; + DEBUGLOG(6, "decoded block of size %u bytes", (U32)(op - ostart)); + return (size_t)(op - ostart); } static size_t ZSTD_decompressSequences_default(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset, - const int frame) + const ZSTD_longOffset_e isLongOffset) { - return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); + return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); } static size_t ZSTD_decompressSequencesSplitLitBuffer_default(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset, - const int frame) + const ZSTD_longOffset_e isLongOffset) { - return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); + return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); } #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT -FORCE_INLINE_TEMPLATE size_t -ZSTD_prefetchMatch(size_t prefetchPos, seq_t const sequence, +FORCE_INLINE_TEMPLATE + +size_t ZSTD_prefetchMatch(size_t prefetchPos, seq_t const sequence, const BYTE* const prefixStart, const BYTE* const dictEnd) { prefetchPos += sequence.litLength; { const BYTE* const matchBase = (sequence.offset > prefetchPos) ? dictEnd : prefixStart; - const BYTE* const match = matchBase + prefetchPos - sequence.offset; /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted. - * No consequence though : memory address is only used for prefetching, not for dereferencing */ + /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted. + * No consequence though : memory address is only used for prefetching, not for dereferencing */ + const BYTE* const match = ZSTD_wrappedPtrSub(ZSTD_wrappedPtrAdd(matchBase, prefetchPos), sequence.offset); PREFETCH_L1(match); PREFETCH_L1(match+CACHELINE_SIZE); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */ } return prefetchPos + sequence.matchLength; @@ -1709,20 +1734,18 @@ ZSTD_decompressSequencesLong_body( ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset, - const int frame) + const ZSTD_longOffset_e isLongOffset) { const BYTE* ip = (const BYTE*)seqStart; const BYTE* const iend = ip + seqSize; BYTE* const ostart = (BYTE*)dst; - BYTE* const oend = dctx->litBufferLocation == ZSTD_in_dst ? dctx->litBuffer : ostart + maxDstSize; + BYTE* const oend = dctx->litBufferLocation == ZSTD_in_dst ? dctx->litBuffer : ZSTD_maybeNullPtrAdd(ostart, maxDstSize); BYTE* op = ostart; const BYTE* litPtr = dctx->litPtr; const BYTE* litBufferEnd = dctx->litBufferEnd; const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart); const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart); const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); - (void)frame; /* Regen sequences */ if (nbSeq) { @@ -1747,20 +1770,17 @@ ZSTD_decompressSequencesLong_body( ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); /* prepare in advance */ - for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && (seqNblitBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd) - { + if (dctx->litBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd) { /* lit buffer is reaching split point, empty out the first buffer and transition to litExtraBuffer */ const size_t leftoverLit = dctx->litBufferEnd - litPtr; if (leftoverLit) @@ -1773,26 +1793,26 @@ ZSTD_decompressSequencesLong_body( litPtr = dctx->litExtraBuffer; litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; dctx->litBufferLocation = ZSTD_not_in_dst; - oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); + { size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) - assert(!ZSTD_isError(oneSeqSize)); - if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart); + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart); #endif - if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; - prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd); - sequences[seqNb & STORED_SEQS_MASK] = sequence; - op += oneSeqSize; - } + prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd); + sequences[seqNb & STORED_SEQS_MASK] = sequence; + op += oneSeqSize; + } } else { /* lit buffer is either wholly contained in first or second split, or not split at all*/ - oneSeqSize = dctx->litBufferLocation == ZSTD_split ? + size_t const oneSeqSize = dctx->litBufferLocation == ZSTD_split ? ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength - WILDCOPY_OVERLENGTH, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) : ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) assert(!ZSTD_isError(oneSeqSize)); - if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart); + ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart); #endif if (ZSTD_isError(oneSeqSize)) return oneSeqSize; @@ -1801,17 +1821,15 @@ ZSTD_decompressSequencesLong_body( op += oneSeqSize; } } - RETURN_ERROR_IF(seqNblitBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd) - { + if (dctx->litBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd) { const size_t leftoverLit = dctx->litBufferEnd - litPtr; - if (leftoverLit) - { + if (leftoverLit) { RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer"); ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit); sequence->litLength -= leftoverLit; @@ -1820,11 +1838,10 @@ ZSTD_decompressSequencesLong_body( litPtr = dctx->litExtraBuffer; litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; dctx->litBufferLocation = ZSTD_not_in_dst; - { - size_t const oneSeqSize = ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); + { size_t const oneSeqSize = ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) assert(!ZSTD_isError(oneSeqSize)); - if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart); + ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart); #endif if (ZSTD_isError(oneSeqSize)) return oneSeqSize; op += oneSeqSize; @@ -1837,7 +1854,7 @@ ZSTD_decompressSequencesLong_body( ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) assert(!ZSTD_isError(oneSeqSize)); - if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart); + ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart); #endif if (ZSTD_isError(oneSeqSize)) return oneSeqSize; op += oneSeqSize; @@ -1849,8 +1866,7 @@ ZSTD_decompressSequencesLong_body( } /* last literal segment */ - if (dctx->litBufferLocation == ZSTD_split) /* first deplete literal buffer in dst, then copy litExtraBuffer */ - { + if (dctx->litBufferLocation == ZSTD_split) { /* first deplete literal buffer in dst, then copy litExtraBuffer */ size_t const lastLLSize = litBufferEnd - litPtr; RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, ""); if (op != NULL) { @@ -1868,17 +1884,16 @@ ZSTD_decompressSequencesLong_body( } } - return op-ostart; + return (size_t)(op - ostart); } static size_t ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset, - const int frame) + const ZSTD_longOffset_e isLongOffset) { - return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); + return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); } #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */ @@ -1892,20 +1907,18 @@ DONT_VECTORIZE ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset, - const int frame) + const ZSTD_longOffset_e isLongOffset) { - return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); + return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); } static BMI2_TARGET_ATTRIBUTE size_t DONT_VECTORIZE ZSTD_decompressSequencesSplitLitBuffer_bmi2(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset, - const int frame) + const ZSTD_longOffset_e isLongOffset) { - return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); + return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); } #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ @@ -1914,10 +1927,9 @@ static BMI2_TARGET_ATTRIBUTE size_t ZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset, - const int frame) + const ZSTD_longOffset_e isLongOffset) { - return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); + return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); } #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */ @@ -1927,37 +1939,34 @@ typedef size_t (*ZSTD_decompressSequences_t)( ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset, - const int frame); + const ZSTD_longOffset_e isLongOffset); #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG static size_t ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset, - const int frame) + const ZSTD_longOffset_e isLongOffset) { DEBUGLOG(5, "ZSTD_decompressSequences"); #if DYNAMIC_BMI2 if (ZSTD_DCtx_get_bmi2(dctx)) { - return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); + return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); } #endif - return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); + return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); } static size_t ZSTD_decompressSequencesSplitLitBuffer(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset, - const int frame) + const ZSTD_longOffset_e isLongOffset) { DEBUGLOG(5, "ZSTD_decompressSequencesSplitLitBuffer"); #if DYNAMIC_BMI2 if (ZSTD_DCtx_get_bmi2(dctx)) { - return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); + return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); } #endif - return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); + return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); } #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ @@ -1972,22 +1981,21 @@ static size_t ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset, - const int frame) + const ZSTD_longOffset_e isLongOffset) { DEBUGLOG(5, "ZSTD_decompressSequencesLong"); #if DYNAMIC_BMI2 if (ZSTD_DCtx_get_bmi2(dctx)) { - return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); + return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); } #endif - return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); + return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); } #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */ /** - * @returns The total size of the history referencable by zstd, including + * @returns The total size of the history referenceable by zstd, including * both the prefix and the extDict. At @p op any offset larger than this * is invalid. */ @@ -2063,20 +2071,20 @@ static size_t ZSTD_maxShortOffset(void) size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, - const void* src, size_t srcSize, const int frame, const streaming_operation streaming) + const void* src, size_t srcSize, const streaming_operation streaming) { /* blockType == blockCompressed */ const BYTE* ip = (const BYTE*)src; - DEBUGLOG(5, "ZSTD_decompressBlock_internal (size : %u)", (U32)srcSize); + DEBUGLOG(5, "ZSTD_decompressBlock_internal (cSize : %u)", (unsigned)srcSize); /* Note : the wording of the specification - * allows compressed block to be sized exactly ZSTD_BLOCKSIZE_MAX. + * allows compressed block to be sized exactly ZSTD_blockSizeMax(dctx). * This generally does not happen, as it makes little sense, * since an uncompressed block would feature same size and have no decompression cost. * Also, note that decoder from reference libzstd before < v1.5.4 * would consider this edge case as an error. - * As a consequence, avoid generating compressed blocks of size ZSTD_BLOCKSIZE_MAX + * As a consequence, avoid generating compressed blocks of size ZSTD_blockSizeMax(dctx) * for broader compatibility with the deployed ecosystem of zstd decoders */ - RETURN_ERROR_IF(srcSize > ZSTD_BLOCKSIZE_MAX, srcSize_wrong, ""); + RETURN_ERROR_IF(srcSize > ZSTD_blockSizeMax(dctx), srcSize_wrong, ""); /* Decode literals section */ { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, streaming); @@ -2091,8 +2099,8 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, /* Compute the maximum block size, which must also work when !frame and fParams are unset. * Additionally, take the min with dstCapacity to ensure that the totalHistorySize fits in a size_t. */ - size_t const blockSizeMax = MIN(dstCapacity, (frame ? dctx->fParams.blockSizeMax : ZSTD_BLOCKSIZE_MAX)); - size_t const totalHistorySize = ZSTD_totalHistorySize((BYTE*)dst + blockSizeMax, (BYTE const*)dctx->virtualStart); + size_t const blockSizeMax = MIN(dstCapacity, ZSTD_blockSizeMax(dctx)); + size_t const totalHistorySize = ZSTD_totalHistorySize(ZSTD_maybeNullPtrAdd((BYTE*)dst, blockSizeMax), (BYTE const*)dctx->virtualStart); /* isLongOffset must be true if there are long offsets. * Offsets are long if they are larger than ZSTD_maxShortOffset(). * We don't expect that to be the case in 64-bit mode. @@ -2124,7 +2132,9 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, ip += seqHSize; srcSize -= seqHSize; - RETURN_ERROR_IF(dst == NULL && nbSeq > 0, dstSize_tooSmall, "NULL not handled"); + RETURN_ERROR_IF((dst == NULL || dstCapacity == 0) && nbSeq > 0, dstSize_tooSmall, "NULL not handled"); + RETURN_ERROR_IF(MEM_64bits() && sizeof(size_t) == sizeof(void*) && (size_t)(-1) - (size_t)dst < (size_t)(1 << 20), dstSize_tooSmall, + "invalid dst"); /* If we could potentially have long offsets, or we might want to use the prefetch decoder, * compute information about the share of long offsets, and the maximum nbAdditionalBits. @@ -2155,21 +2165,22 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, { #endif #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT - return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame); + return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); #endif } #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG /* else */ if (dctx->litBufferLocation == ZSTD_split) - return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame); + return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); else - return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame); + return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); #endif } } +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize) { if (dst != dctx->previousDstEnd && dstSize > 0) { /* not contiguous */ @@ -2181,13 +2192,24 @@ void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize) } +size_t ZSTD_decompressBlock_deprecated(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + size_t dSize; + dctx->isFrameDecompression = 0; + ZSTD_checkContinuity(dctx, dst, dstCapacity); + dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, not_streaming); + FORWARD_IF_ERROR(dSize, ""); + dctx->previousDstEnd = (char*)dst + dSize; + return dSize; +} + + +/* NOTE: Must just wrap ZSTD_decompressBlock_deprecated() */ size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) { - size_t dSize; - ZSTD_checkContinuity(dctx, dst, dstCapacity); - dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 0, not_streaming); - dctx->previousDstEnd = (char*)dst + dSize; - return dSize; + return ZSTD_decompressBlock_deprecated(dctx, dst, dstCapacity, src, srcSize); } diff --git a/src/dependencies/zstd-1.5.4/lib/decompress/zstd_decompress_block.h b/src/dependencies/zstd-1.5.6/lib/decompress/zstd_decompress_block.h similarity index 89% rename from src/dependencies/zstd-1.5.4/lib/decompress/zstd_decompress_block.h rename to src/dependencies/zstd-1.5.6/lib/decompress/zstd_decompress_block.h index 67791db..ab15240 100644 --- a/src/dependencies/zstd-1.5.4/lib/decompress/zstd_decompress_block.h +++ b/src/dependencies/zstd-1.5.6/lib/decompress/zstd_decompress_block.h @@ -47,7 +47,7 @@ typedef enum { */ size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, - const void* src, size_t srcSize, const int frame, const streaming_operation streaming); + const void* src, size_t srcSize, const streaming_operation streaming); /* ZSTD_buildFSETable() : * generate FSE decoding table for one symbol (ll, ml or off) @@ -64,5 +64,10 @@ void ZSTD_buildFSETable(ZSTD_seqSymbol* dt, unsigned tableLog, void* wksp, size_t wkspSize, int bmi2); +/* Internal definition of ZSTD_decompressBlock() to avoid deprecation warnings. */ +size_t ZSTD_decompressBlock_deprecated(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + #endif /* ZSTD_DEC_BLOCK_H */ diff --git a/src/dependencies/zstd-1.5.4/lib/decompress/zstd_decompress_internal.h b/src/dependencies/zstd-1.5.6/lib/decompress/zstd_decompress_internal.h similarity index 99% rename from src/dependencies/zstd-1.5.4/lib/decompress/zstd_decompress_internal.h rename to src/dependencies/zstd-1.5.6/lib/decompress/zstd_decompress_internal.h index c2ec5d9..83a7a01 100644 --- a/src/dependencies/zstd-1.5.4/lib/decompress/zstd_decompress_internal.h +++ b/src/dependencies/zstd-1.5.6/lib/decompress/zstd_decompress_internal.h @@ -153,6 +153,7 @@ struct ZSTD_DCtx_s size_t litSize; size_t rleSize; size_t staticSize; + int isFrameDecompression; #if DYNAMIC_BMI2 != 0 int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */ #endif @@ -166,6 +167,7 @@ struct ZSTD_DCtx_s ZSTD_DDictHashSet* ddictSet; /* Hash set for multiple ddicts */ ZSTD_refMultipleDDicts_e refMultipleDDicts; /* User specified: if == 1, will allow references to multiple DDicts. Default == 0 (disabled) */ int disableHufAsm; + int maxBlockSizeParam; /* streaming */ ZSTD_dStreamStage streamStage; diff --git a/src/dependencies/zstd-1.5.4/lib/deprecated/zbuff.h b/src/dependencies/zstd-1.5.6/lib/deprecated/zbuff.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/deprecated/zbuff.h rename to src/dependencies/zstd-1.5.6/lib/deprecated/zbuff.h diff --git a/src/dependencies/zstd-1.5.4/lib/deprecated/zbuff_common.c b/src/dependencies/zstd-1.5.6/lib/deprecated/zbuff_common.c similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/deprecated/zbuff_common.c rename to src/dependencies/zstd-1.5.6/lib/deprecated/zbuff_common.c diff --git a/src/dependencies/zstd-1.5.4/lib/deprecated/zbuff_compress.c b/src/dependencies/zstd-1.5.6/lib/deprecated/zbuff_compress.c similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/deprecated/zbuff_compress.c rename to src/dependencies/zstd-1.5.6/lib/deprecated/zbuff_compress.c diff --git a/src/dependencies/zstd-1.5.4/lib/deprecated/zbuff_decompress.c b/src/dependencies/zstd-1.5.6/lib/deprecated/zbuff_decompress.c similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/deprecated/zbuff_decompress.c rename to src/dependencies/zstd-1.5.6/lib/deprecated/zbuff_decompress.c diff --git a/src/dependencies/zstd-1.5.4/lib/dictBuilder/cover.c b/src/dependencies/zstd-1.5.6/lib/dictBuilder/cover.c similarity index 98% rename from src/dependencies/zstd-1.5.4/lib/dictBuilder/cover.c rename to src/dependencies/zstd-1.5.6/lib/dictBuilder/cover.c index 9e5e7d5..44f9029 100644 --- a/src/dependencies/zstd-1.5.4/lib/dictBuilder/cover.c +++ b/src/dependencies/zstd-1.5.6/lib/dictBuilder/cover.c @@ -31,8 +31,8 @@ #endif #include "../common/mem.h" /* read */ -#include "../common/pool.h" -#include "../common/threading.h" +#include "../common/pool.h" /* POOL_ctx */ +#include "../common/threading.h" /* ZSTD_pthread_mutex_t */ #include "../common/zstd_internal.h" /* includes zstd.h */ #include "../common/bits.h" /* ZSTD_highbit32 */ #include "../zdict.h" @@ -78,7 +78,7 @@ static clock_t g_time = 0; #undef LOCALDISPLAYUPDATE #define LOCALDISPLAYUPDATE(displayLevel, l, ...) \ if (displayLevel >= l) { \ - if ((clock() - g_time > g_refreshRate) || (displayLevel >= 4)) { \ + if ((clock() - g_time > g_refreshRate) || (displayLevel >= 4)) { \ g_time = clock(); \ DISPLAY(__VA_ARGS__); \ } \ @@ -301,9 +301,10 @@ static int WIN_CDECL COVER_strict_cmp8(const void *lp, const void *rp) { * Returns the first pointer in [first, last) whose element does not compare * less than value. If no such element exists it returns last. */ -static const size_t *COVER_lower_bound(const size_t *first, const size_t *last, +static const size_t *COVER_lower_bound(const size_t* first, const size_t* last, size_t value) { - size_t count = last - first; + size_t count = (size_t)(last - first); + assert(last >= first); while (count != 0) { size_t step = count / 2; const size_t *ptr = first; @@ -549,7 +550,8 @@ static void COVER_ctx_destroy(COVER_ctx_t *ctx) { */ static size_t COVER_ctx_init(COVER_ctx_t *ctx, const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples, - unsigned d, double splitPoint) { + unsigned d, double splitPoint) +{ const BYTE *const samples = (const BYTE *)samplesBuffer; const size_t totalSamplesSize = COVER_sum(samplesSizes, nbSamples); /* Split samples into testing and training sets */ @@ -733,7 +735,7 @@ static size_t COVER_buildDictionary(const COVER_ctx_t *ctx, U32 *freqs, return tail; } -ZDICTLIB_API size_t ZDICT_trainFromBuffer_cover( +ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_cover( void *dictBuffer, size_t dictBufferCapacity, const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples, ZDICT_cover_params_t parameters) @@ -907,8 +909,10 @@ void COVER_best_start(COVER_best_t *best) { * Decrements liveJobs and signals any waiting threads if liveJobs == 0. * If this dictionary is the best so far save it and its parameters. */ -void COVER_best_finish(COVER_best_t *best, ZDICT_cover_params_t parameters, - COVER_dictSelection_t selection) { +void COVER_best_finish(COVER_best_t* best, + ZDICT_cover_params_t parameters, + COVER_dictSelection_t selection) +{ void* dict = selection.dictContent; size_t compressedSize = selection.totalCompressedSize; size_t dictSize = selection.dictSize; @@ -980,8 +984,8 @@ COVER_dictSelection_t COVER_selectDict(BYTE* customDictContent, size_t dictBuffe size_t largestCompressed = 0; BYTE* customDictContentEnd = customDictContent + dictContentSize; - BYTE * largestDictbuffer = (BYTE *)malloc(dictBufferCapacity); - BYTE * candidateDictBuffer = (BYTE *)malloc(dictBufferCapacity); + BYTE* largestDictbuffer = (BYTE*)malloc(dictBufferCapacity); + BYTE* candidateDictBuffer = (BYTE*)malloc(dictBufferCapacity); double regressionTolerance = ((double)params.shrinkDictMaxRegression / 100.0) + 1.00; if (!largestDictbuffer || !candidateDictBuffer) { @@ -1119,7 +1123,7 @@ _cleanup: free(freqs); } -ZDICTLIB_API size_t ZDICT_optimizeTrainFromBuffer_cover( +ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover( void* dictBuffer, size_t dictBufferCapacity, const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples, ZDICT_cover_params_t* parameters) diff --git a/src/dependencies/zstd-1.5.4/lib/dictBuilder/cover.h b/src/dependencies/zstd-1.5.6/lib/dictBuilder/cover.h similarity index 93% rename from src/dependencies/zstd-1.5.4/lib/dictBuilder/cover.h rename to src/dependencies/zstd-1.5.6/lib/dictBuilder/cover.h index 252624b..a5d7506 100644 --- a/src/dependencies/zstd-1.5.4/lib/dictBuilder/cover.h +++ b/src/dependencies/zstd-1.5.6/lib/dictBuilder/cover.h @@ -12,14 +12,8 @@ # define ZDICT_STATIC_LINKING_ONLY #endif -#include /* fprintf */ -#include /* malloc, free, qsort */ -#include /* memset */ -#include /* clock */ -#include "../common/mem.h" /* read */ -#include "../common/pool.h" -#include "../common/threading.h" -#include "../common/zstd_internal.h" /* includes zstd.h */ +#include "../common/threading.h" /* ZSTD_pthread_mutex_t */ +#include "../common/mem.h" /* U32, BYTE */ #include "../zdict.h" /** diff --git a/src/dependencies/zstd-1.5.4/lib/dictBuilder/divsufsort.c b/src/dependencies/zstd-1.5.6/lib/dictBuilder/divsufsort.c similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/dictBuilder/divsufsort.c rename to src/dependencies/zstd-1.5.6/lib/dictBuilder/divsufsort.c diff --git a/src/dependencies/zstd-1.5.4/lib/dictBuilder/divsufsort.h b/src/dependencies/zstd-1.5.6/lib/dictBuilder/divsufsort.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/dictBuilder/divsufsort.h rename to src/dependencies/zstd-1.5.6/lib/dictBuilder/divsufsort.h diff --git a/src/dependencies/zstd-1.5.4/lib/dictBuilder/fastcover.c b/src/dependencies/zstd-1.5.6/lib/dictBuilder/fastcover.c similarity index 99% rename from src/dependencies/zstd-1.5.4/lib/dictBuilder/fastcover.c rename to src/dependencies/zstd-1.5.6/lib/dictBuilder/fastcover.c index 46bba01..a958eb3 100644 --- a/src/dependencies/zstd-1.5.4/lib/dictBuilder/fastcover.c +++ b/src/dependencies/zstd-1.5.6/lib/dictBuilder/fastcover.c @@ -545,7 +545,7 @@ FASTCOVER_convertToFastCoverParams(ZDICT_cover_params_t coverParams, } -ZDICTLIB_API size_t +ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_fastCover(void* dictBuffer, size_t dictBufferCapacity, const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples, @@ -614,7 +614,7 @@ ZDICT_trainFromBuffer_fastCover(void* dictBuffer, size_t dictBufferCapacity, } -ZDICTLIB_API size_t +ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_fastCover( void* dictBuffer, size_t dictBufferCapacity, const void* samplesBuffer, diff --git a/src/dependencies/zstd-1.5.4/lib/dictBuilder/zdict.c b/src/dependencies/zstd-1.5.6/lib/dictBuilder/zdict.c similarity index 97% rename from src/dependencies/zstd-1.5.4/lib/dictBuilder/zdict.c rename to src/dependencies/zstd-1.5.6/lib/dictBuilder/zdict.c index f22e04d..82e999e 100644 --- a/src/dependencies/zstd-1.5.4/lib/dictBuilder/zdict.c +++ b/src/dependencies/zstd-1.5.6/lib/dictBuilder/zdict.c @@ -74,9 +74,9 @@ static const U32 g_selectivity_default = 9; * Console display ***************************************/ #undef DISPLAY -#define DISPLAY(...) { fprintf(stderr, __VA_ARGS__); fflush( stderr ); } +#define DISPLAY(...) do { fprintf(stderr, __VA_ARGS__); fflush( stderr ); } while (0) #undef DISPLAYLEVEL -#define DISPLAYLEVEL(l, ...) if (notificationLevel>=l) { DISPLAY(__VA_ARGS__); } /* 0 : no display; 1: errors; 2: default; 3: details; 4: debug */ +#define DISPLAYLEVEL(l, ...) do { if (notificationLevel>=l) { DISPLAY(__VA_ARGS__); } } while (0) /* 0 : no display; 1: errors; 2: default; 3: details; 4: debug */ static clock_t ZDICT_clockSpan(clock_t nPrevious) { return clock() - nPrevious; } @@ -477,10 +477,16 @@ static size_t ZDICT_trainBuffer_legacy(dictItem* dictList, U32 dictListSize, clock_t const refreshRate = CLOCKS_PER_SEC * 3 / 10; # undef DISPLAYUPDATE -# define DISPLAYUPDATE(l, ...) if (notificationLevel>=l) { \ - if (ZDICT_clockSpan(displayClock) > refreshRate) \ - { displayClock = clock(); DISPLAY(__VA_ARGS__); \ - if (notificationLevel>=4) fflush(stderr); } } +# define DISPLAYUPDATE(l, ...) \ + do { \ + if (notificationLevel>=l) { \ + if (ZDICT_clockSpan(displayClock) > refreshRate) { \ + displayClock = clock(); \ + DISPLAY(__VA_ARGS__); \ + } \ + if (notificationLevel>=4) fflush(stderr); \ + } \ + } while (0) /* init */ DISPLAYLEVEL(2, "\r%70s\r", ""); /* clean display line */ @@ -566,11 +572,11 @@ static void ZDICT_countEStats(EStats_ress_t esr, const ZSTD_parameters* params, size_t cSize; if (srcSize > blockSizeMax) srcSize = blockSizeMax; /* protection vs large samples */ - { size_t const errorCode = ZSTD_compressBegin_usingCDict(esr.zc, esr.dict); + { size_t const errorCode = ZSTD_compressBegin_usingCDict_deprecated(esr.zc, esr.dict); if (ZSTD_isError(errorCode)) { DISPLAYLEVEL(1, "warning : ZSTD_compressBegin_usingCDict failed \n"); return; } } - cSize = ZSTD_compressBlock(esr.zc, esr.workPlace, ZSTD_BLOCKSIZE_MAX, src, srcSize); + cSize = ZSTD_compressBlock_deprecated(esr.zc, esr.workPlace, ZSTD_BLOCKSIZE_MAX, src, srcSize); if (ZSTD_isError(cSize)) { DISPLAYLEVEL(3, "warning : could not compress sample size %u \n", (unsigned)srcSize); return; } if (cSize) { /* if == 0; block is not compressible */ diff --git a/src/dependencies/zstd-1.5.4/lib/dll/example/Makefile b/src/dependencies/zstd-1.5.6/lib/dll/example/Makefile similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/dll/example/Makefile rename to src/dependencies/zstd-1.5.6/lib/dll/example/Makefile diff --git a/src/dependencies/zstd-1.5.4/lib/dll/example/README.md b/src/dependencies/zstd-1.5.6/lib/dll/example/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/dll/example/README.md rename to src/dependencies/zstd-1.5.6/lib/dll/example/README.md diff --git a/src/dependencies/zstd-1.5.4/lib/dll/example/fullbench-dll.sln b/src/dependencies/zstd-1.5.6/lib/dll/example/fullbench-dll.sln similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/dll/example/fullbench-dll.sln rename to src/dependencies/zstd-1.5.6/lib/dll/example/fullbench-dll.sln diff --git a/src/dependencies/zstd-1.5.4/lib/dll/example/fullbench-dll.vcxproj b/src/dependencies/zstd-1.5.6/lib/dll/example/fullbench-dll.vcxproj similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/dll/example/fullbench-dll.vcxproj rename to src/dependencies/zstd-1.5.6/lib/dll/example/fullbench-dll.vcxproj diff --git a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_legacy.h b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_legacy.h similarity index 95% rename from src/dependencies/zstd-1.5.4/lib/legacy/zstd_legacy.h rename to src/dependencies/zstd-1.5.6/lib/legacy/zstd_legacy.h index dd17325..7a8a04e 100644 --- a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_legacy.h +++ b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_legacy.h @@ -124,6 +124,20 @@ MEM_STATIC size_t ZSTD_decompressLegacy( const void* dict,size_t dictSize) { U32 const version = ZSTD_isLegacy(src, compressedSize); + char x; + /* Avoid passing NULL to legacy decoding. */ + if (dst == NULL) { + assert(dstCapacity == 0); + dst = &x; + } + if (src == NULL) { + assert(compressedSize == 0); + src = &x; + } + if (dict == NULL) { + assert(dictSize == 0); + dict = &x; + } (void)dst; (void)dstCapacity; (void)dict; (void)dictSize; /* unused when ZSTD_LEGACY_SUPPORT >= 8 */ switch(version) { @@ -287,6 +301,12 @@ MEM_STATIC size_t ZSTD_freeLegacyStreamContext(void* legacyContext, U32 version) MEM_STATIC size_t ZSTD_initLegacyStream(void** legacyContext, U32 prevVersion, U32 newVersion, const void* dict, size_t dictSize) { + char x; + /* Avoid passing NULL to legacy decoding. */ + if (dict == NULL) { + assert(dictSize == 0); + dict = &x; + } DEBUGLOG(5, "ZSTD_initLegacyStream for v0.%u", newVersion); if (prevVersion != newVersion) ZSTD_freeLegacyStreamContext(*legacyContext, prevVersion); switch(newVersion) @@ -346,6 +366,16 @@ MEM_STATIC size_t ZSTD_initLegacyStream(void** legacyContext, U32 prevVersion, U MEM_STATIC size_t ZSTD_decompressLegacyStream(void* legacyContext, U32 version, ZSTD_outBuffer* output, ZSTD_inBuffer* input) { + static char x; + /* Avoid passing NULL to legacy decoding. */ + if (output->dst == NULL) { + assert(output->size == 0); + output->dst = &x; + } + if (input->src == NULL) { + assert(input->size == 0); + input->src = &x; + } DEBUGLOG(5, "ZSTD_decompressLegacyStream for v0.%u", version); switch(version) { diff --git a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v01.c b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v01.c similarity index 99% rename from src/dependencies/zstd-1.5.4/lib/legacy/zstd_v01.c rename to src/dependencies/zstd-1.5.6/lib/legacy/zstd_v01.c index 1a3aad0..6cf5123 100644 --- a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v01.c +++ b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v01.c @@ -14,6 +14,7 @@ ******************************************/ #include /* size_t, ptrdiff_t */ #include "zstd_v01.h" +#include "../common/compiler.h" #include "../common/error_private.h" @@ -2118,6 +2119,7 @@ size_t ZSTDv01_decompressContinue(ZSTDv01_Dctx* dctx, void* dst, size_t maxDstSi } ctx->phase = 1; ctx->expected = ZSTD_blockHeaderSize; + if (ZSTDv01_isError(rSize)) return rSize; ctx->previousDstEnd = (void*)( ((char*)dst) + rSize); return rSize; } diff --git a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v01.h b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v01.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/legacy/zstd_v01.h rename to src/dependencies/zstd-1.5.6/lib/legacy/zstd_v01.h diff --git a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v02.c b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v02.c similarity index 99% rename from src/dependencies/zstd-1.5.4/lib/legacy/zstd_v02.c rename to src/dependencies/zstd-1.5.6/lib/legacy/zstd_v02.c index e09bb4a..6d39b6e 100644 --- a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v02.c +++ b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v02.c @@ -11,6 +11,7 @@ #include /* size_t, ptrdiff_t */ #include "zstd_v02.h" +#include "../common/compiler.h" #include "../common/error_private.h" @@ -71,20 +72,6 @@ extern "C" { #include /* memcpy */ -/****************************************** -* Compiler-specific -******************************************/ -#if defined(__GNUC__) -# define MEM_STATIC static __attribute__((unused)) -#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) -# define MEM_STATIC static inline -#elif defined(_MSC_VER) -# define MEM_STATIC static __inline -#else -# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ -#endif - - /**************************************************************** * Basic Types *****************************************************************/ @@ -875,7 +862,7 @@ extern "C" { * Streaming functions ***************************************/ -typedef struct ZSTD_DCtx_s ZSTD_DCtx; +typedef struct ZSTDv02_Dctx_s ZSTD_DCtx; /* Use above functions alternatively. @@ -2750,7 +2737,7 @@ static unsigned ZSTD_isError(size_t code) { return ERR_isError(code); } /* ************************************************************* * Decompression section ***************************************************************/ -struct ZSTD_DCtx_s +struct ZSTDv02_Dctx_s { U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)]; U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)]; @@ -3431,6 +3418,7 @@ static size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSi } ctx->phase = 1; ctx->expected = ZSTD_blockHeaderSize; + if (ZSTD_isError(rSize)) return rSize; ctx->previousDstEnd = (void*)( ((char*)dst) + rSize); return rSize; } diff --git a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v02.h b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v02.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/legacy/zstd_v02.h rename to src/dependencies/zstd-1.5.6/lib/legacy/zstd_v02.h diff --git a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v03.c b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v03.c similarity index 99% rename from src/dependencies/zstd-1.5.4/lib/legacy/zstd_v03.c rename to src/dependencies/zstd-1.5.6/lib/legacy/zstd_v03.c index b0d7f52..47195f3 100644 --- a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v03.c +++ b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v03.c @@ -11,6 +11,7 @@ #include /* size_t, ptrdiff_t */ #include "zstd_v03.h" +#include "../common/compiler.h" #include "../common/error_private.h" @@ -72,20 +73,6 @@ extern "C" { #include /* memcpy */ -/****************************************** -* Compiler-specific -******************************************/ -#if defined(__GNUC__) -# define MEM_STATIC static __attribute__((unused)) -#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) -# define MEM_STATIC static inline -#elif defined(_MSC_VER) -# define MEM_STATIC static __inline -#else -# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ -#endif - - /**************************************************************** * Basic Types *****************************************************************/ @@ -875,7 +862,7 @@ extern "C" { * Streaming functions ***************************************/ -typedef struct ZSTD_DCtx_s ZSTD_DCtx; +typedef struct ZSTDv03_Dctx_s ZSTD_DCtx; /* Use above functions alternatively. @@ -2390,7 +2377,7 @@ static unsigned ZSTD_isError(size_t code) { return ERR_isError(code); } /* ************************************************************* * Decompression section ***************************************************************/ -struct ZSTD_DCtx_s +struct ZSTDv03_Dctx_s { U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)]; U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)]; @@ -3071,6 +3058,7 @@ static size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSi } ctx->phase = 1; ctx->expected = ZSTD_blockHeaderSize; + if (ZSTD_isError(rSize)) return rSize; ctx->previousDstEnd = (void*)( ((char*)dst) + rSize); return rSize; } diff --git a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v03.h b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v03.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/legacy/zstd_v03.h rename to src/dependencies/zstd-1.5.6/lib/legacy/zstd_v03.h diff --git a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v04.c b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v04.c similarity index 99% rename from src/dependencies/zstd-1.5.4/lib/legacy/zstd_v04.c rename to src/dependencies/zstd-1.5.6/lib/legacy/zstd_v04.c index 57be832..0da316c 100644 --- a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v04.c +++ b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v04.c @@ -16,6 +16,7 @@ #include /* memcpy */ #include "zstd_v04.h" +#include "../common/compiler.h" #include "../common/error_private.h" @@ -37,15 +38,6 @@ extern "C" { # include /* _byteswap_ulong */ # include /* _byteswap_* */ #endif -#if defined(__GNUC__) -# define MEM_STATIC static __attribute__((unused)) -#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) -# define MEM_STATIC static inline -#elif defined(_MSC_VER) -# define MEM_STATIC static __inline -#else -# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ -#endif /**************************************************************** @@ -3218,6 +3210,7 @@ static size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSi } ctx->stage = ZSTDds_decodeBlockHeader; ctx->expected = ZSTD_blockHeaderSize; + if (ZSTD_isError(rSize)) return rSize; ctx->previousDstEnd = (char*)dst + rSize; return rSize; } @@ -3545,8 +3538,8 @@ static size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbc, void* dst, size_t* maxDs unsigned ZBUFFv04_isError(size_t errorCode) { return ERR_isError(errorCode); } const char* ZBUFFv04_getErrorName(size_t errorCode) { return ERR_getErrorName(errorCode); } -size_t ZBUFFv04_recommendedDInSize() { return BLOCKSIZE + 3; } -size_t ZBUFFv04_recommendedDOutSize() { return BLOCKSIZE; } +size_t ZBUFFv04_recommendedDInSize(void) { return BLOCKSIZE + 3; } +size_t ZBUFFv04_recommendedDOutSize(void) { return BLOCKSIZE; } diff --git a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v04.h b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v04.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/legacy/zstd_v04.h rename to src/dependencies/zstd-1.5.6/lib/legacy/zstd_v04.h diff --git a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v05.c b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v05.c similarity index 99% rename from src/dependencies/zstd-1.5.4/lib/legacy/zstd_v05.c rename to src/dependencies/zstd-1.5.6/lib/legacy/zstd_v05.c index 93a1169..44a877b 100644 --- a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v05.c +++ b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v05.c @@ -3600,6 +3600,7 @@ size_t ZSTDv05_decompressContinue(ZSTDv05_DCtx* dctx, void* dst, size_t maxDstSi } dctx->stage = ZSTDv05ds_decodeBlockHeader; dctx->expected = ZSTDv05_blockHeaderSize; + if (ZSTDv05_isError(rSize)) return rSize; dctx->previousDstEnd = (char*)dst + rSize; return rSize; } diff --git a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v05.h b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v05.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/legacy/zstd_v05.h rename to src/dependencies/zstd-1.5.6/lib/legacy/zstd_v05.h diff --git a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v06.c b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v06.c similarity index 99% rename from src/dependencies/zstd-1.5.4/lib/legacy/zstd_v06.c rename to src/dependencies/zstd-1.5.6/lib/legacy/zstd_v06.c index 175f7cc..00d6ef7 100644 --- a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v06.c +++ b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v06.c @@ -14,6 +14,7 @@ #include /* size_t, ptrdiff_t */ #include /* memcpy */ #include /* malloc, free, qsort */ +#include "../common/compiler.h" #include "../common/error_private.h" @@ -67,15 +68,6 @@ extern "C" { # include /* _byteswap_ulong */ # include /* _byteswap_* */ #endif -#if defined(__GNUC__) -# define MEM_STATIC static __attribute__((unused)) -#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) -# define MEM_STATIC static inline -#elif defined(_MSC_VER) -# define MEM_STATIC static __inline -#else -# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ -#endif /*-************************************************************** @@ -3745,6 +3737,7 @@ size_t ZSTDv06_decompressContinue(ZSTDv06_DCtx* dctx, void* dst, size_t dstCapac } dctx->stage = ZSTDds_decodeBlockHeader; dctx->expected = ZSTDv06_blockHeaderSize; + if (ZSTDv06_isError(rSize)) return rSize; dctx->previousDstEnd = (char*)dst + rSize; return rSize; } diff --git a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v06.h b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v06.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/legacy/zstd_v06.h rename to src/dependencies/zstd-1.5.6/lib/legacy/zstd_v06.h diff --git a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v07.c b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v07.c similarity index 99% rename from src/dependencies/zstd-1.5.4/lib/legacy/zstd_v07.c rename to src/dependencies/zstd-1.5.6/lib/legacy/zstd_v07.c index 15dc3ef..8778f07 100644 --- a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v07.c +++ b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v07.c @@ -24,6 +24,7 @@ #define HUFv07_STATIC_LINKING_ONLY /* HUFv07_TABLELOG_ABSOLUTEMAX */ #define ZSTDv07_STATIC_LINKING_ONLY +#include "../common/compiler.h" #include "../common/error_private.h" @@ -227,15 +228,6 @@ extern "C" { # include /* _byteswap_ulong */ # include /* _byteswap_* */ #endif -#if defined(__GNUC__) -# define MEM_STATIC static __attribute__((unused)) -#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) -# define MEM_STATIC static inline -#elif defined(_MSC_VER) -# define MEM_STATIC static __inline -#else -# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ -#endif /*-************************************************************** @@ -4015,8 +4007,8 @@ size_t ZSTDv07_decompressContinue(ZSTDv07_DCtx* dctx, void* dst, size_t dstCapac } dctx->stage = ZSTDds_decodeBlockHeader; dctx->expected = ZSTDv07_blockHeaderSize; - dctx->previousDstEnd = (char*)dst + rSize; if (ZSTDv07_isError(rSize)) return rSize; + dctx->previousDstEnd = (char*)dst + rSize; if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize); return rSize; } diff --git a/src/dependencies/zstd-1.5.4/lib/legacy/zstd_v07.h b/src/dependencies/zstd-1.5.6/lib/legacy/zstd_v07.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/legacy/zstd_v07.h rename to src/dependencies/zstd-1.5.6/lib/legacy/zstd_v07.h diff --git a/src/dependencies/zstd-1.5.4/lib/libzstd.mk b/src/dependencies/zstd-1.5.6/lib/libzstd.mk similarity index 78% rename from src/dependencies/zstd-1.5.4/lib/libzstd.mk rename to src/dependencies/zstd-1.5.6/lib/libzstd.mk index 5e11d5d..a308a6e 100644 --- a/src/dependencies/zstd-1.5.4/lib/libzstd.mk +++ b/src/dependencies/zstd-1.5.6/lib/libzstd.mk @@ -8,12 +8,21 @@ # You may select, at your option, one of the above-listed licenses. # ################################################################ +# This included Makefile provides the following variables : +# LIB_SRCDIR, LIB_BINDIR + +# Ensure the file is not included twice +# Note : must be included after setting the default target +ifndef LIBZSTD_MK_INCLUDED +LIBZSTD_MK_INCLUDED := 1 + ################################################################## # Input Variables ################################################################## -# Zstd lib directory -LIBZSTD ?= ./ +# By default, library's directory is same as this included makefile +LIB_SRCDIR ?= $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) +LIB_BINDIR ?= $(LIBSRC_DIR) # ZSTD_LIB_MINIFY is a helper variable that # configures a bunch of other variables to space-optimized defaults. @@ -47,6 +56,9 @@ endif # Assembly support ZSTD_NO_ASM ?= 0 +ZSTD_LIB_EXCLUDE_COMPRESSORS_DFAST_AND_UP ?= 0 +ZSTD_LIB_EXCLUDE_COMPRESSORS_GREEDY_AND_UP ?= 0 + ################################################################## # libzstd helpers ################################################################## @@ -57,6 +69,7 @@ VOID ?= /dev/null NUM_SYMBOL := \# # define silent mode as default (verbose mode with V=1 or VERBOSE=1) +# Note : must be defined _after_ the default target $(V)$(VERBOSE).SILENT: # When cross-compiling from linux to windows, @@ -66,7 +79,7 @@ $(V)$(VERBOSE).SILENT: TARGET_SYSTEM ?= $(OS) # Version numbers -LIBVER_SRC := $(LIBZSTD)/zstd.h +LIBVER_SRC := $(LIB_SRCDIR)/zstd.h LIBVER_MAJOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)` LIBVER_MINOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)` LIBVER_PATCH_SCRIPT:=`sed -n '/define ZSTD_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)` @@ -133,14 +146,14 @@ ifeq ($(HAVE_COLORNEVER), 1) endif GREP = grep $(GREP_OPTIONS) -ZSTD_COMMON_FILES := $(sort $(wildcard $(LIBZSTD)/common/*.c)) -ZSTD_COMPRESS_FILES := $(sort $(wildcard $(LIBZSTD)/compress/*.c)) -ZSTD_DECOMPRESS_FILES := $(sort $(wildcard $(LIBZSTD)/decompress/*.c)) -ZSTD_DICTBUILDER_FILES := $(sort $(wildcard $(LIBZSTD)/dictBuilder/*.c)) -ZSTD_DEPRECATED_FILES := $(sort $(wildcard $(LIBZSTD)/deprecated/*.c)) +ZSTD_COMMON_FILES := $(sort $(wildcard $(LIB_SRCDIR)/common/*.c)) +ZSTD_COMPRESS_FILES := $(sort $(wildcard $(LIB_SRCDIR)/compress/*.c)) +ZSTD_DECOMPRESS_FILES := $(sort $(wildcard $(LIB_SRCDIR)/decompress/*.c)) +ZSTD_DICTBUILDER_FILES := $(sort $(wildcard $(LIB_SRCDIR)/dictBuilder/*.c)) +ZSTD_DEPRECATED_FILES := $(sort $(wildcard $(LIB_SRCDIR)/deprecated/*.c)) ZSTD_LEGACY_FILES := -ZSTD_DECOMPRESS_AMD64_ASM_FILES := $(sort $(wildcard $(LIBZSTD)/decompress/*_amd64.S)) +ZSTD_DECOMPRESS_AMD64_ASM_FILES := $(sort $(wildcard $(LIB_SRCDIR)/decompress/*_amd64.S)) ifneq ($(ZSTD_NO_ASM), 0) CPPFLAGS += -DZSTD_DISABLE_ASM @@ -178,9 +191,17 @@ ifneq ($(ZSTD_LEGACY_MULTITHREADED_API), 0) CFLAGS += -DZSTD_LEGACY_MULTITHREADED_API endif +ifneq ($(ZSTD_LIB_EXCLUDE_COMPRESSORS_DFAST_AND_UP), 0) + CFLAGS += -DZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR -DZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR -DZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR -DZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR -DZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR -DZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR +else +ifneq ($(ZSTD_LIB_EXCLUDE_COMPRESSORS_GREEDY_AND_UP), 0) + CFLAGS += -DZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR -DZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR -DZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR -DZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR -DZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR +endif +endif + ifneq ($(ZSTD_LEGACY_SUPPORT), 0) ifeq ($(shell test $(ZSTD_LEGACY_SUPPORT) -lt 8; echo $$?), 0) - ZSTD_LEGACY_FILES += $(shell ls $(LIBZSTD)/legacy/*.c | $(GREP) 'v0[$(ZSTD_LEGACY_SUPPORT)-7]') + ZSTD_LEGACY_FILES += $(shell ls $(LIB_SRCDIR)/legacy/*.c | $(GREP) 'v0[$(ZSTD_LEGACY_SUPPORT)-7]') endif endif CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) @@ -209,6 +230,8 @@ ifeq ($(HAVE_HASH),0) endif endif # BUILD_DIR -ZSTD_SUBDIR := $(LIBZSTD)/common $(LIBZSTD)/compress $(LIBZSTD)/decompress $(LIBZSTD)/dictBuilder $(LIBZSTD)/legacy $(LIBZSTD)/deprecated +ZSTD_SUBDIR := $(LIB_SRCDIR)/common $(LIB_SRCDIR)/compress $(LIB_SRCDIR)/decompress $(LIB_SRCDIR)/dictBuilder $(LIB_SRCDIR)/legacy $(LIB_SRCDIR)/deprecated vpath %.c $(ZSTD_SUBDIR) vpath %.S $(ZSTD_SUBDIR) + +endif # LIBZSTD_MK_INCLUDED diff --git a/src/dependencies/zstd-1.5.4/lib/libzstd.pc.in b/src/dependencies/zstd-1.5.6/lib/libzstd.pc.in similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/libzstd.pc.in rename to src/dependencies/zstd-1.5.6/lib/libzstd.pc.in diff --git a/src/dependencies/zstd-1.5.4/lib/module.modulemap b/src/dependencies/zstd-1.5.6/lib/module.modulemap similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/module.modulemap rename to src/dependencies/zstd-1.5.6/lib/module.modulemap diff --git a/src/dependencies/zstd-1.5.4/lib/zdict.h b/src/dependencies/zstd-1.5.6/lib/zdict.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/zdict.h rename to src/dependencies/zstd-1.5.6/lib/zdict.h diff --git a/src/dependencies/zstd-1.5.4/lib/zstd.h b/src/dependencies/zstd-1.5.6/lib/zstd.h similarity index 93% rename from src/dependencies/zstd-1.5.4/lib/zstd.h rename to src/dependencies/zstd-1.5.6/lib/zstd.h index 95aac07..5d1fef8 100644 --- a/src/dependencies/zstd-1.5.4/lib/zstd.h +++ b/src/dependencies/zstd-1.5.6/lib/zstd.h @@ -106,7 +106,7 @@ extern "C" { /*------ Version ------*/ #define ZSTD_VERSION_MAJOR 1 #define ZSTD_VERSION_MINOR 5 -#define ZSTD_VERSION_RELEASE 4 +#define ZSTD_VERSION_RELEASE 6 #define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE) /*! ZSTD_versionNumber() : @@ -148,7 +148,8 @@ ZSTDLIB_API const char* ZSTD_versionString(void); ***************************************/ /*! ZSTD_compress() : * Compresses `src` content as a single zstd compressed frame into already allocated `dst`. - * Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`. + * NOTE: Providing `dstCapacity >= ZSTD_compressBound(srcSize)` guarantees that zstd will have + * enough space to successfully compress the data. * @return : compressed size written into `dst` (<= `dstCapacity), * 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, @@ -227,7 +228,7 @@ ZSTDLIB_API size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize) * for example to size a static array on stack. * Will produce constant value 0 if srcSize too large. */ -#define ZSTD_MAX_INPUT_SIZE ((sizeof(size_t)==8) ? 0xFF00FF00FF00FF00LLU : 0xFF00FF00U) +#define ZSTD_MAX_INPUT_SIZE ((sizeof(size_t)==8) ? 0xFF00FF00FF00FF00ULL : 0xFF00FF00U) #define ZSTD_COMPRESSBOUND(srcSize) (((size_t)(srcSize) >= ZSTD_MAX_INPUT_SIZE) ? 0 : (srcSize) + ((srcSize)>>8) + (((srcSize) < (128<<10)) ? (((128<<10) - (srcSize)) >> 11) /* margin, from 64 to 0 */ : 0)) /* this formula ensures that bound(A) + bound(B) <= bound(A+B) as long as A and B >= 128 KB */ ZSTDLIB_API size_t ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case single-pass scenario */ /* ZSTD_isError() : @@ -248,7 +249,7 @@ ZSTDLIB_API int ZSTD_defaultCLevel(void); /*!< default compres /*= Compression context * When compressing many times, * it is recommended to allocate a context just once, - * and re-use it for each successive compression operation. + * and reuse it for each successive compression operation. * This will make workload friendlier for system's memory. * Note : re-using context is just a speed / resource optimization. * It doesn't change the compression ratio, which remains identical. @@ -261,9 +262,9 @@ ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx); /* accept NULL pointer * /*! ZSTD_compressCCtx() : * Same as ZSTD_compress(), using an explicit ZSTD_CCtx. - * Important : in order to behave similarly to `ZSTD_compress()`, - * this function compresses at requested compression level, - * __ignoring any other parameter__ . + * Important : in order to mirror `ZSTD_compress()` behavior, + * this function compresses at the requested compression level, + * __ignoring any other advanced parameter__ . * If any advanced parameter was set using the advanced API, * they will all be reset. Only `compressionLevel` remains. */ @@ -275,7 +276,7 @@ ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx, /*= Decompression context * When decompressing many times, * it is recommended to allocate a context only once, - * and re-use it for each successive compression operation. + * and reuse it for each successive compression operation. * This will make workload friendlier for system's memory. * Use one context per thread for parallel execution. */ typedef struct ZSTD_DCtx_s ZSTD_DCtx; @@ -285,7 +286,7 @@ ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); /* accept NULL pointer * /*! ZSTD_decompressDCtx() : * Same as ZSTD_decompress(), * requires an allocated ZSTD_DCtx. - * Compatible with sticky parameters. + * Compatible with sticky parameters (see below). */ ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, @@ -301,12 +302,12 @@ ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, * using ZSTD_CCtx_set*() functions. * Pushed parameters are sticky : they are valid for next compressed frame, and any subsequent frame. * "sticky" parameters are applicable to `ZSTD_compress2()` and `ZSTD_compressStream*()` ! - * __They do not apply to "simple" one-shot variants such as ZSTD_compressCCtx()__ . + * __They do not apply to one-shot variants such as ZSTD_compressCCtx()__ . * * It's possible to reset all parameters to "default" using ZSTD_CCtx_reset(). * * This API supersedes all other "advanced" API entry points in the experimental section. - * In the future, we expect to remove from experimental API entry points which are redundant with this API. + * In the future, we expect to remove API entry points from experimental which are redundant with this API. */ @@ -389,6 +390,19 @@ typedef enum { * The higher the value of selected strategy, the more complex it is, * resulting in stronger and slower compression. * Special: value 0 means "use default strategy". */ + + ZSTD_c_targetCBlockSize=130, /* v1.5.6+ + * Attempts to fit compressed block size into approximatively targetCBlockSize. + * Bound by ZSTD_TARGETCBLOCKSIZE_MIN and ZSTD_TARGETCBLOCKSIZE_MAX. + * Note that it's not a guarantee, just a convergence target (default:0). + * No target when targetCBlockSize == 0. + * This is helpful in low bandwidth streaming environments to improve end-to-end latency, + * when a client can make use of partial documents (a prominent example being Chrome). + * Note: this parameter is stable since v1.5.6. + * It was present as an experimental parameter in earlier versions, + * but it's not recommended using it with earlier library versions + * due to massive performance regressions. + */ /* LDM mode parameters */ ZSTD_c_enableLongDistanceMatching=160, /* Enable long distance matching. * This parameter is designed to improve compression ratio @@ -468,7 +482,6 @@ typedef enum { * ZSTD_c_forceMaxWindow * ZSTD_c_forceAttachDict * ZSTD_c_literalCompressionMode - * ZSTD_c_targetCBlockSize * ZSTD_c_srcSizeHint * ZSTD_c_enableDedicatedDictSearch * ZSTD_c_stableInBuffer @@ -489,7 +502,7 @@ typedef enum { ZSTD_c_experimentalParam3=1000, ZSTD_c_experimentalParam4=1001, ZSTD_c_experimentalParam5=1002, - ZSTD_c_experimentalParam6=1003, + /* was ZSTD_c_experimentalParam6=1003; is now ZSTD_c_targetCBlockSize */ ZSTD_c_experimentalParam7=1004, ZSTD_c_experimentalParam8=1005, ZSTD_c_experimentalParam9=1006, @@ -574,11 +587,13 @@ ZSTDLIB_API size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset); /*! ZSTD_compress2() : * Behave the same as ZSTD_compressCCtx(), but compression parameters are set using the advanced API. + * (note that this entry point doesn't even expose a compression level parameter). * ZSTD_compress2() always starts a new frame. * Should cctx hold data from a previously unfinished frame, everything about it is forgotten. * - Compression parameters are pushed into CCtx before starting compression, using ZSTD_CCtx_set*() * - The function is always blocking, returns when compression is completed. - * Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`. + * NOTE: Providing `dstCapacity >= ZSTD_compressBound(srcSize)` guarantees that zstd will have + * enough space to successfully compress the data, though it is possible it fails for other reasons. * @return : compressed size written into `dst` (<= `dstCapacity), * or an error code if it fails (which can be tested using ZSTD_isError()). */ @@ -616,6 +631,7 @@ typedef enum { * ZSTD_d_forceIgnoreChecksum * ZSTD_d_refMultipleDDicts * ZSTD_d_disableHuffmanAssembly + * ZSTD_d_maxBlockSize * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them. * note : never ever use experimentalParam? names directly */ @@ -623,7 +639,8 @@ typedef enum { ZSTD_d_experimentalParam2=1001, ZSTD_d_experimentalParam3=1002, ZSTD_d_experimentalParam4=1003, - ZSTD_d_experimentalParam5=1004 + ZSTD_d_experimentalParam5=1004, + ZSTD_d_experimentalParam6=1005 } ZSTD_dParameter; @@ -678,14 +695,14 @@ typedef struct ZSTD_outBuffer_s { * A ZSTD_CStream object is required to track streaming operation. * Use ZSTD_createCStream() and ZSTD_freeCStream() to create/release resources. * ZSTD_CStream objects can be reused multiple times on consecutive compression operations. -* It is recommended to re-use ZSTD_CStream since it will play nicer with system's memory, by re-using already allocated memory. +* It is recommended to reuse ZSTD_CStream since it will play nicer with system's memory, by re-using already allocated memory. * * For parallel execution, use one separate ZSTD_CStream per thread. * * note : since v1.3.0, ZSTD_CStream and ZSTD_CCtx are the same thing. * * Parameters are sticky : when starting a new compression on the same context, -* it will re-use the same sticky parameters as previous compression session. +* it will reuse the same sticky parameters as previous compression session. * When in doubt, it's recommended to fully initialize the context before usage. * Use ZSTD_CCtx_reset() to reset the context and ZSTD_CCtx_setParameter(), * ZSTD_CCtx_setPledgedSrcSize(), or ZSTD_CCtx_loadDictionary() and friends to @@ -774,6 +791,11 @@ typedef enum { * only ZSTD_e_end or ZSTD_e_flush operations are allowed. * Before starting a new compression job, or changing compression parameters, * it is required to fully flush internal buffers. + * - note: if an operation ends with an error, it may leave @cctx in an undefined state. + * Therefore, it's UB to invoke ZSTD_compressStream2() of ZSTD_compressStream() on such a state. + * In order to be re-employed after an error, a state must be reset, + * which can be done explicitly (ZSTD_CCtx_reset()), + * or is sometimes implied by methods starting a new compression job (ZSTD_initCStream(), ZSTD_compressCCtx()) */ ZSTDLIB_API size_t ZSTD_compressStream2( ZSTD_CCtx* cctx, ZSTD_outBuffer* output, @@ -833,7 +855,7 @@ ZSTDLIB_API size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output); * * 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. +* ZSTD_DStream objects can be reused multiple times. * * Use ZSTD_initDStream() to start a new decompression operation. * @return : recommended first input size @@ -887,6 +909,12 @@ ZSTDLIB_API size_t ZSTD_initDStream(ZSTD_DStream* zds); * @return : 0 when a frame is completely decoded and fully flushed, * or an error code, which can be tested using ZSTD_isError(), * or any other value > 0, which means there is some decoding or flushing to do to complete current frame. + * + * Note: when an operation returns with an error code, the @zds state may be left in undefined state. + * It's UB to invoke `ZSTD_decompressStream()` on such a state. + * In order to re-use such a state, it must be first reset, + * which can be done explicitly (`ZSTD_DCtx_reset()`), + * or is implied for operations starting some new decompression job (`ZSTD_initDStream`, `ZSTD_decompressDCtx()`, `ZSTD_decompress_usingDict()`) */ ZSTDLIB_API size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input); @@ -1018,9 +1046,11 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize); * Advanced dictionary and prefix API (Requires v1.4.0+) * * This API allows dictionaries to be used with ZSTD_compress2(), - * ZSTD_compressStream2(), and ZSTD_decompressDCtx(). Dictionaries are sticky, and - * only reset with the context is reset with ZSTD_reset_parameters or - * ZSTD_reset_session_and_parameters. Prefixes are single-use. + * ZSTD_compressStream2(), and ZSTD_decompressDCtx(). + * Dictionaries are sticky, they remain valid when same context is reused, + * they only reset when the context is reset + * with ZSTD_reset_parameters or ZSTD_reset_session_and_parameters. + * In contrast, Prefixes are single-use. ******************************************************************************/ @@ -1041,7 +1071,11 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize); * Use experimental ZSTD_CCtx_loadDictionary_byReference() to reference content instead. * In such a case, dictionary buffer must outlive its users. * Note 4 : Use ZSTD_CCtx_loadDictionary_advanced() - * to precisely select how dictionary content must be interpreted. */ + * to precisely select how dictionary content must be interpreted. + * Note 5 : This method does not benefit from LDM (long distance mode). + * If you want to employ LDM on some large dictionary content, + * prefer employing ZSTD_CCtx_refPrefix() described below. + */ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize); /*! ZSTD_CCtx_refCDict() : Requires v1.4.0+ @@ -1064,6 +1098,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); * Decompression will need same prefix to properly regenerate data. * Compressing with a prefix is similar in outcome as performing a diff and compressing it, * but performs much faster, especially during decompression (compression speed is tunable with compression level). + * This method is compatible with LDM (long distance mode). * @result : 0, or an error code (which can be tested with ZSTD_isError()). * Special: Adding any prefix (including NULL) invalidates any previous prefix or dictionary * Note 1 : Prefix buffer is referenced. It **must** outlive compression. @@ -1230,7 +1265,7 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict); #define ZSTD_LDM_HASHRATELOG_MAX (ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN) /* Advanced parameter bounds */ -#define ZSTD_TARGETCBLOCKSIZE_MIN 64 +#define ZSTD_TARGETCBLOCKSIZE_MIN 1340 /* suitable to fit into an ethernet / wifi / 4G transport frame */ #define ZSTD_TARGETCBLOCKSIZE_MAX ZSTD_BLOCKSIZE_MAX #define ZSTD_SRCSIZEHINT_MIN 0 #define ZSTD_SRCSIZEHINT_MAX INT_MAX @@ -1387,7 +1422,7 @@ typedef enum { } ZSTD_paramSwitch_e; /*************************************** -* Frame size functions +* Frame header and size functions ***************************************/ /*! ZSTD_findDecompressedSize() : @@ -1434,6 +1469,30 @@ ZSTDLIB_STATIC_API unsigned long long ZSTD_decompressBound(const void* src, size * or an error code (if srcSize is too small) */ ZSTDLIB_STATIC_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize); +typedef enum { ZSTD_frame, ZSTD_skippableFrame } ZSTD_frameType_e; +typedef struct { + unsigned long long frameContentSize; /* if == ZSTD_CONTENTSIZE_UNKNOWN, it means this field is not available. 0 means "empty" */ + unsigned long long windowSize; /* can be very large, up to <= frameContentSize */ + unsigned blockSizeMax; + ZSTD_frameType_e frameType; /* if == ZSTD_skippableFrame, frameContentSize is the size of skippable content */ + unsigned headerSize; + unsigned dictID; + unsigned checksumFlag; + unsigned _reserved1; + unsigned _reserved2; +} ZSTD_frameHeader; + +/*! ZSTD_getFrameHeader() : + * decode Frame Header, or requires larger `srcSize`. + * @return : 0, `zfhPtr` is correctly filled, + * >0, `srcSize` is too small, value is wanted `srcSize` amount, + * or an error code, which can be tested using ZSTD_isError() */ +ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize); /**< doesn't consume input */ +/*! ZSTD_getFrameHeader_advanced() : + * same as ZSTD_getFrameHeader(), + * with added capability to select a format (like ZSTD_f_zstd1_magicless) */ +ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format); + /*! ZSTD_decompressionMargin() : * Zstd supports in-place decompression, where the input and output buffers overlap. * In this case, the output buffer must be at least (Margin + Output_Size) bytes large, @@ -1494,25 +1553,38 @@ typedef enum { ZSTDLIB_STATIC_API size_t ZSTD_sequenceBound(size_t srcSize); /*! ZSTD_generateSequences() : + * WARNING: This function is meant for debugging and informational purposes ONLY! + * Its implementation is flawed, and it will be deleted in a future version. + * It is not guaranteed to succeed, as there are several cases where it will give + * up and fail. You should NOT use this function in production code. + * + * This function is deprecated, and will be removed in a future version. + * * Generate sequences using ZSTD_compress2(), given a source buffer. * + * @param zc The compression context to be used for ZSTD_compress2(). Set any + * compression parameters you need on this context. + * @param outSeqs The output sequences buffer of size @p outSeqsSize + * @param outSeqsSize The size of the output sequences buffer. + * ZSTD_sequenceBound(srcSize) is an upper bound on the number + * of sequences that can be generated. + * @param src The source buffer to generate sequences from of size @p srcSize. + * @param srcSize The size of the source buffer. + * * Each block will end with a dummy sequence * with offset == 0, matchLength == 0, and litLength == length of last literals. * litLength may be == 0, and if so, then the sequence of (of: 0 ml: 0 ll: 0) * simply acts as a block delimiter. * - * @zc can be used to insert custom compression params. - * This function invokes ZSTD_compress2(). - * - * The output of this function can be fed into ZSTD_compressSequences() with CCtx - * setting of ZSTD_c_blockDelimiters as ZSTD_sf_explicitBlockDelimiters - * @return : number of sequences generated + * @returns The number of sequences generated, necessarily less than + * ZSTD_sequenceBound(srcSize), or an error code that can be checked + * with ZSTD_isError(). */ - +ZSTD_DEPRECATED("For debugging only, will be replaced by ZSTD_extractSequences()") ZSTDLIB_STATIC_API size_t -ZSTD_generateSequences( ZSTD_CCtx* zc, - ZSTD_Sequence* outSeqs, size_t outSeqsSize, - const void* src, size_t srcSize); +ZSTD_generateSequences(ZSTD_CCtx* zc, + ZSTD_Sequence* outSeqs, size_t outSeqsSize, + const void* src, size_t srcSize); /*! ZSTD_mergeBlockDelimiters() : * Given an array of ZSTD_Sequence, remove all sequences that represent block delimiters/last literals @@ -1607,56 +1679,59 @@ ZSTDLIB_API unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size); /*! ZSTD_estimate*() : * These functions make it possible to estimate memory usage * of a future {D,C}Ctx, before its creation. + * This is useful in combination with ZSTD_initStatic(), + * which makes it possible to employ a static buffer for ZSTD_CCtx* state. * * ZSTD_estimateCCtxSize() will provide a memory budget large enough - * for any compression level up to selected one. - * Note : Unlike ZSTD_estimateCStreamSize*(), this estimate - * does not include space for a window buffer. - * Therefore, the estimation is only guaranteed for single-shot compressions, not streaming. + * to compress data of any size using one-shot compression ZSTD_compressCCtx() or ZSTD_compress2() + * associated with any compression level up to max specified one. * The estimate will assume the input may be arbitrarily large, * which is the worst case. * + * Note that the size estimation is specific for one-shot compression, + * it is not valid for streaming (see ZSTD_estimateCStreamSize*()) + * nor other potential ways of using a ZSTD_CCtx* state. + * * When srcSize can be bound by a known and rather "small" value, - * this fact can be used to provide a tighter estimation - * because the CCtx compression context will need less memory. - * This tighter estimation can be provided by more advanced functions + * this knowledge can be used to provide a tighter budget estimation + * because the ZSTD_CCtx* state will need less memory for small inputs. + * This tighter estimation can be provided by employing more advanced functions * ZSTD_estimateCCtxSize_usingCParams(), which can be used in tandem with ZSTD_getCParams(), * and ZSTD_estimateCCtxSize_usingCCtxParams(), which can be used in tandem with ZSTD_CCtxParams_setParameter(). * Both can be used to estimate memory using custom compression parameters and arbitrary srcSize limits. * * Note : only single-threaded compression is supported. * ZSTD_estimateCCtxSize_usingCCtxParams() will return an error code if ZSTD_c_nbWorkers is >= 1. - * - * Note 2 : ZSTD_estimateCCtxSize* functions are not compatible with the Block-Level Sequence Producer API at this time. - * Size estimates assume that no external sequence producer is registered. */ -ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize(int compressionLevel); +ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize(int maxCompressionLevel); ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams); ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params); ZSTDLIB_STATIC_API size_t ZSTD_estimateDCtxSize(void); /*! ZSTD_estimateCStreamSize() : - * ZSTD_estimateCStreamSize() will provide a budget large enough for any compression level up to selected one. - * It will also consider src size to be arbitrarily "large", which is worst case. + * ZSTD_estimateCStreamSize() will provide a memory budget large enough for streaming compression + * using any compression level up to the max specified one. + * It will also consider src size to be arbitrarily "large", which is a worst case scenario. * If srcSize is known to always be small, ZSTD_estimateCStreamSize_usingCParams() can provide a tighter estimation. * ZSTD_estimateCStreamSize_usingCParams() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. * ZSTD_estimateCStreamSize_usingCCtxParams() can be used in tandem with ZSTD_CCtxParams_setParameter(). Only single-threaded compression is supported. This function will return an error code if ZSTD_c_nbWorkers is >= 1. * Note : CStream size estimation is only correct for single-threaded compression. - * ZSTD_DStream memory budget depends on window Size. + * ZSTD_estimateCStreamSize_usingCCtxParams() will return an error code if ZSTD_c_nbWorkers is >= 1. + * Note 2 : ZSTD_estimateCStreamSize* functions are not compatible with the Block-Level Sequence Producer API at this time. + * Size estimates assume that no external sequence producer is registered. + * + * ZSTD_DStream memory budget depends on frame's window Size. * This information can be passed manually, using ZSTD_estimateDStreamSize, * or deducted from a valid frame Header, using ZSTD_estimateDStreamSize_fromFrame(); + * Any frame requesting a window size larger than max specified one will be rejected. * Note : if streaming is init with function ZSTD_init?Stream_usingDict(), * an internal ?Dict will be created, which additional size is not estimated here. * In this case, get total size by adding ZSTD_estimate?DictSize - * Note 2 : only single-threaded compression is supported. - * ZSTD_estimateCStreamSize_usingCCtxParams() will return an error code if ZSTD_c_nbWorkers is >= 1. - * Note 3 : ZSTD_estimateCStreamSize* functions are not compatible with the Block-Level Sequence Producer API at this time. - * Size estimates assume that no external sequence producer is registered. */ -ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize(int compressionLevel); +ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize(int maxCompressionLevel); ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams); ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params); -ZSTDLIB_STATIC_API size_t ZSTD_estimateDStreamSize(size_t windowSize); +ZSTDLIB_STATIC_API size_t ZSTD_estimateDStreamSize(size_t maxWindowSize); ZSTDLIB_STATIC_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize); /*! ZSTD_estimate?DictSize() : @@ -1803,12 +1878,26 @@ ZSTDLIB_STATIC_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params); ZSTDLIB_STATIC_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize); /*! ZSTD_CCtx_setCParams() : - * Set all parameters provided within @cparams into the working @cctx. + * Set all parameters provided within @p cparams into the working @p cctx. * Note : if modifying parameters during compression (MT mode only), * note that changes to the .windowLog parameter will be ignored. - * @return 0 on success, or an error code (can be checked with ZSTD_isError()) */ + * @return 0 on success, or an error code (can be checked with ZSTD_isError()). + * On failure, no parameters are updated. + */ ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setCParams(ZSTD_CCtx* cctx, ZSTD_compressionParameters cparams); +/*! ZSTD_CCtx_setFParams() : + * Set all parameters provided within @p fparams into the working @p cctx. + * @return 0 on success, or an error code (can be checked with ZSTD_isError()). + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setFParams(ZSTD_CCtx* cctx, ZSTD_frameParameters fparams); + +/*! ZSTD_CCtx_setParams() : + * Set all parameters provided within @p params into the working @p cctx. + * @return 0 on success, or an error code (can be checked with ZSTD_isError()). + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setParams(ZSTD_CCtx* cctx, ZSTD_parameters params); + /*! ZSTD_compress_advanced() : * Note : this function is now DEPRECATED. * It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_setParameter() and other parameter setters. @@ -1899,11 +1988,6 @@ ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const vo */ #define ZSTD_c_literalCompressionMode ZSTD_c_experimentalParam5 -/* Tries to fit compressed block size to be around targetCBlockSize. - * No target when targetCBlockSize == 0. - * There is no guarantee on compressed block size (default:0) */ -#define ZSTD_c_targetCBlockSize ZSTD_c_experimentalParam6 - /* User's best guess of source size. * Hint is not valid when srcSizeHint == 0. * There is no guarantee that hint is close to actual source size, @@ -2134,7 +2218,7 @@ ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const vo * This parameter can be used to set an upper bound on the blocksize * that overrides the default ZSTD_BLOCKSIZE_MAX. It cannot be used to set upper * bounds greater than ZSTD_BLOCKSIZE_MAX or bounds lower than 1KB (will make - * compressBound() innacurate). Only currently meant to be used for testing. + * compressBound() inaccurate). Only currently meant to be used for testing. * */ #define ZSTD_c_maxBlockSize ZSTD_c_experimentalParam18 @@ -2383,6 +2467,22 @@ ZSTDLIB_STATIC_API size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParamete */ #define ZSTD_d_disableHuffmanAssembly ZSTD_d_experimentalParam5 +/* ZSTD_d_maxBlockSize + * Allowed values are between 1KB and ZSTD_BLOCKSIZE_MAX (128KB). + * The default is ZSTD_BLOCKSIZE_MAX, and setting to 0 will set to the default. + * + * Forces the decompressor to reject blocks whose content size is + * larger than the configured maxBlockSize. When maxBlockSize is + * larger than the windowSize, the windowSize is used instead. + * This saves memory on the decoder when you know all blocks are small. + * + * This option is typically used in conjunction with ZSTD_c_maxBlockSize. + * + * WARNING: This causes the decoder to reject otherwise valid frames + * that have block sizes larger than the configured maxBlockSize. + */ +#define ZSTD_d_maxBlockSize ZSTD_d_experimentalParam6 + /*! ZSTD_DCtx_setFormat() : * This function is REDUNDANT. Prefer ZSTD_DCtx_setParameter(). @@ -2452,12 +2552,9 @@ size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, int compressionLevel); /*! ZSTD_initCStream_advanced() : - * This function is DEPRECATED, and is approximately equivalent to: + * This function is DEPRECATED, and is equivalent to: * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); - * // Pseudocode: Set each zstd parameter and leave the rest as-is. - * for ((param, value) : params) { - * ZSTD_CCtx_setParameter(zcs, param, value); - * } + * ZSTD_CCtx_setParams(zcs, params); * ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize); * ZSTD_CCtx_loadDictionary(zcs, dict, dictSize); * @@ -2486,12 +2583,9 @@ ZSTDLIB_STATIC_API size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict); /*! ZSTD_initCStream_usingCDict_advanced() : - * This function is DEPRECATED, and is approximately equivalent to: + * This function is DEPRECATED, and is equivalent to: * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); - * // Pseudocode: Set each zstd frame parameter and leave the rest as-is. - * for ((fParam, value) : fParams) { - * ZSTD_CCtx_setParameter(zcs, fParam, value); - * } + * ZSTD_CCtx_setFParams(zcs, fParams); * ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize); * ZSTD_CCtx_refCDict(zcs, cdict); * @@ -2516,7 +2610,7 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, * explicitly specified. * * start a new frame, using same parameters from previous frame. - * This is typically useful to skip dictionary loading stage, since it will re-use it in-place. + * This is typically useful to skip dictionary loading stage, since it will reuse it in-place. * Note that zcs must be init at least once before using ZSTD_resetCStream(). * If pledgedSrcSize is not known at reset time, use macro ZSTD_CONTENTSIZE_UNKNOWN. * If pledgedSrcSize > 0, its value must be correct, as it will be written in header, and controlled at the end. @@ -2592,220 +2686,12 @@ ZSTDLIB_STATIC_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const Z * * ZSTD_DCtx_reset(zds, ZSTD_reset_session_only); * - * re-use decompression parameters from previous init; saves dictionary loading + * reuse decompression parameters from previous init; saves dictionary loading */ ZSTD_DEPRECATED("use ZSTD_DCtx_reset, see zstd.h for detailed instructions") ZSTDLIB_STATIC_API size_t ZSTD_resetDStream(ZSTD_DStream* zds); -/********************************************************************* -* Buffer-less and synchronous inner streaming functions -* -* This is an advanced API, giving full control over buffer management, for users which need direct control over memory. -* But it's also a complex one, with several restrictions, documented below. -* Prefer normal streaming API for an easier experience. -********************************************************************* */ - -/** - Buffer-less streaming compression (synchronous mode) - - A ZSTD_CCtx object is required to track streaming operations. - Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource. - ZSTD_CCtx object can be re-used multiple times within successive compression operations. - - Start by initializing a context. - Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression. - - Then, consume your input using ZSTD_compressContinue(). - There are some important considerations to keep in mind when using this advanced function : - - ZSTD_compressContinue() has no internal buffer. It uses externally provided buffers only. - - Interface is synchronous : input is consumed entirely and produces 1+ compressed blocks. - - Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario. - Worst case evaluation is provided by ZSTD_compressBound(). - ZSTD_compressContinue() doesn't guarantee recover after a failed compression. - - ZSTD_compressContinue() presumes prior input ***is still accessible and unmodified*** (up to maximum distance size, see WindowLog). - It remembers all previous contiguous blocks, plus one separated memory segment (which can itself consists of multiple contiguous blocks) - - ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps. - In which case, it will "discard" the relevant memory section from its history. - - Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum. - It's possible to use srcSize==0, in which case, it will write a final empty block to end the frame. - Without last block mark, frames are considered unfinished (hence corrupted) by compliant decoders. - - `ZSTD_CCtx` object can be re-used (ZSTD_compressBegin()) to compress again. -*/ - -/*===== Buffer-less streaming compression functions =====*/ -ZSTDLIB_STATIC_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel); -ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel); -ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */ - -ZSTD_DEPRECATED("This function will likely be removed in a future release. It is misleading and has very limited utility.") -ZSTDLIB_STATIC_API -size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */ - -ZSTDLIB_STATIC_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); -ZSTDLIB_STATIC_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); - -/* The ZSTD_compressBegin_advanced() and ZSTD_compressBegin_usingCDict_advanced() are now DEPRECATED and will generate a compiler warning */ -ZSTD_DEPRECATED("use advanced API to access custom parameters") -ZSTDLIB_STATIC_API -size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize : If srcSize is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN */ -ZSTD_DEPRECATED("use advanced API to access custom parameters") -ZSTDLIB_STATIC_API -size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize); /* compression parameters are already set within cdict. pledgedSrcSize must be correct. If srcSize is not known, use macro ZSTD_CONTENTSIZE_UNKNOWN */ -/** - Buffer-less streaming decompression (synchronous mode) - - A ZSTD_DCtx object is required to track streaming operations. - Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it. - A ZSTD_DCtx object can be re-used multiple times. - - First typical operation is to retrieve frame parameters, using ZSTD_getFrameHeader(). - Frame header is extracted from the beginning of compressed frame, so providing only the frame's beginning is enough. - Data fragment must be large enough to ensure successful decoding. - `ZSTD_frameHeaderSize_max` bytes is guaranteed to always be large enough. - result : 0 : successful decoding, the `ZSTD_frameHeader` structure is correctly filled. - >0 : `srcSize` is too small, please provide at least result bytes on next attempt. - errorCode, which can be tested using ZSTD_isError(). - - It fills a ZSTD_frameHeader structure with important information to correctly decode the frame, - such as the dictionary ID, content size, or maximum back-reference distance (`windowSize`). - Note that these values could be wrong, either because of data corruption, or because a 3rd party deliberately spoofs false information. - As a consequence, check that values remain within valid application range. - For example, do not allocate memory blindly, check that `windowSize` is within expectation. - Each application can set its own limits, depending on local restrictions. - For extended interoperability, it is recommended to support `windowSize` of at least 8 MB. - - ZSTD_decompressContinue() needs previous data blocks during decompression, up to `windowSize` bytes. - ZSTD_decompressContinue() is very sensitive to contiguity, - if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place, - or that previous contiguous segment is large enough to properly handle maximum back-reference distance. - There are multiple ways to guarantee this condition. - - The most memory efficient way is to use a round buffer of sufficient size. - Sufficient size is determined by invoking ZSTD_decodingBufferSize_min(), - which can return an error code if required value is too large for current system (in 32-bits mode). - In a round buffer methodology, ZSTD_decompressContinue() decompresses each block next to previous one, - up to the moment there is not enough room left in the buffer to guarantee decoding another full block, - which maximum size is provided in `ZSTD_frameHeader` structure, field `blockSizeMax`. - At which point, decoding can resume from the beginning of the buffer. - Note that already decoded data stored in the buffer should be flushed before being overwritten. - - There are alternatives possible, for example using two or more buffers of size `windowSize` each, though they consume more memory. - - Finally, if you control the compression process, you can also ignore all buffer size rules, - as long as the encoder and decoder progress in "lock-step", - aka use exactly the same buffer sizes, break contiguity at the same place, etc. - - Once buffers are setup, start decompression, with ZSTD_decompressBegin(). - If decompression requires a dictionary, use ZSTD_decompressBegin_usingDict() or ZSTD_decompressBegin_usingDDict(). - - Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively. - ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue(). - ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail. - - result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity). - It can be zero : it just means ZSTD_decompressContinue() has decoded some metadata item. - It can also be an error code, which can be tested with ZSTD_isError(). - - A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero. - Context can then be reset to start a new decompression. - - Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType(). - This information is not required to properly decode a frame. - - == Special case : skippable frames == - - Skippable frames allow integration of user-defined data into a flow of concatenated frames. - Skippable frames will be ignored (skipped) by decompressor. - The format of skippable frames is as follows : - a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F - b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits - c) Frame Content - any content (User Data) of length equal to Frame Size - For skippable frames ZSTD_getFrameHeader() returns zfhPtr->frameType==ZSTD_skippableFrame. - For skippable frames ZSTD_decompressContinue() always returns 0 : it only skips the content. -*/ - -/*===== Buffer-less streaming decompression functions =====*/ -typedef enum { ZSTD_frame, ZSTD_skippableFrame } ZSTD_frameType_e; -typedef struct { - unsigned long long frameContentSize; /* if == ZSTD_CONTENTSIZE_UNKNOWN, it means this field is not available. 0 means "empty" */ - unsigned long long windowSize; /* can be very large, up to <= frameContentSize */ - unsigned blockSizeMax; - ZSTD_frameType_e frameType; /* if == ZSTD_skippableFrame, frameContentSize is the size of skippable content */ - unsigned headerSize; - unsigned dictID; - unsigned checksumFlag; - unsigned _reserved1; - unsigned _reserved2; -} ZSTD_frameHeader; - -/*! ZSTD_getFrameHeader() : - * decode Frame Header, or requires larger `srcSize`. - * @return : 0, `zfhPtr` is correctly filled, - * >0, `srcSize` is too small, value is wanted `srcSize` amount, - * or an error code, which can be tested using ZSTD_isError() */ -ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize); /**< doesn't consume input */ -/*! ZSTD_getFrameHeader_advanced() : - * same as ZSTD_getFrameHeader(), - * with added capability to select a format (like ZSTD_f_zstd1_magicless) */ -ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format); -ZSTDLIB_STATIC_API size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize); /**< when frame content size is not known, pass in frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN */ - -ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx); -ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); -ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); - -ZSTDLIB_STATIC_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx); -ZSTDLIB_STATIC_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); - -/* misc */ -ZSTD_DEPRECATED("This function will likely be removed in the next minor release. It is misleading and has very limited utility.") -ZSTDLIB_STATIC_API void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx); -typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e; -ZSTDLIB_STATIC_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx); - - - - -/* ============================ */ -/** Block level API */ -/* ============================ */ - -/*! - Block functions produce and decode raw zstd blocks, without frame metadata. - Frame metadata cost is typically ~12 bytes, which can be non-negligible for very small blocks (< 100 bytes). - But users will have to take in charge needed metadata to regenerate data, such as compressed and content sizes. - - A few rules to respect : - - Compressing and decompressing require a context structure - + Use ZSTD_createCCtx() and ZSTD_createDCtx() - - It is necessary to init context before starting - + compression : any ZSTD_compressBegin*() variant, including with dictionary - + decompression : any ZSTD_decompressBegin*() variant, including with dictionary - - Block size is limited, it must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX == 128 KB - + If input is larger than a block size, it's necessary to split input data into multiple blocks - + For inputs larger than a single block, consider using regular ZSTD_compress() instead. - Frame metadata is not that costly, and quickly becomes negligible as source size grows larger than a block. - - When a block is considered not compressible enough, ZSTD_compressBlock() result will be 0 (zero) ! - ===> In which case, nothing is produced into `dst` ! - + User __must__ test for such outcome and deal directly with uncompressed data - + A block cannot be declared incompressible if ZSTD_compressBlock() return value was != 0. - Doing so would mess up with statistics history, leading to potential data corruption. - + ZSTD_decompressBlock() _doesn't accept uncompressed data as input_ !! - + In case of multiple successive blocks, should some of them be uncompressed, - decoder must be informed of their existence in order to follow proper history. - Use ZSTD_insertBlock() for such a case. -*/ - -/*===== Raw zstd block functions =====*/ -ZSTDLIB_STATIC_API size_t ZSTD_getBlockSize (const ZSTD_CCtx* cctx); -ZSTDLIB_STATIC_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); -ZSTDLIB_STATIC_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); -ZSTDLIB_STATIC_API size_t ZSTD_insertBlock (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */ - - /* ********************* BLOCK-LEVEL SEQUENCE PRODUCER API ********************* * * *** OVERVIEW *** @@ -2932,7 +2818,7 @@ ZSTDLIB_STATIC_API size_t ZSTD_insertBlock (ZSTD_DCtx* dctx, const void* bloc #define ZSTD_SEQUENCE_PRODUCER_ERROR ((size_t)(-1)) -typedef size_t ZSTD_sequenceProducer_F ( +typedef size_t (*ZSTD_sequenceProducer_F) ( void* sequenceProducerState, ZSTD_Sequence* outSeqs, size_t outSeqsCapacity, const void* src, size_t srcSize, @@ -2964,9 +2850,238 @@ ZSTDLIB_STATIC_API void ZSTD_registerSequenceProducer( ZSTD_CCtx* cctx, void* sequenceProducerState, - ZSTD_sequenceProducer_F* sequenceProducer + ZSTD_sequenceProducer_F sequenceProducer ); +/*! ZSTD_CCtxParams_registerSequenceProducer() : + * Same as ZSTD_registerSequenceProducer(), but operates on ZSTD_CCtx_params. + * This is used for accurate size estimation with ZSTD_estimateCCtxSize_usingCCtxParams(), + * which is needed when creating a ZSTD_CCtx with ZSTD_initStaticCCtx(). + * + * If you are using the external sequence producer API in a scenario where ZSTD_initStaticCCtx() + * is required, then this function is for you. Otherwise, you probably don't need it. + * + * See tests/zstreamtest.c for example usage. */ +ZSTDLIB_STATIC_API void +ZSTD_CCtxParams_registerSequenceProducer( + ZSTD_CCtx_params* params, + void* sequenceProducerState, + ZSTD_sequenceProducer_F sequenceProducer +); + + +/********************************************************************* +* Buffer-less and synchronous inner streaming functions (DEPRECATED) +* +* This API is deprecated, and will be removed in a future version. +* It allows streaming (de)compression with user allocated buffers. +* However, it is hard to use, and not as well tested as the rest of +* our API. +* +* Please use the normal streaming API instead: ZSTD_compressStream2, +* and ZSTD_decompressStream. +* If there is functionality that you need, but it doesn't provide, +* please open an issue on our GitHub. +********************************************************************* */ + +/** + Buffer-less streaming compression (synchronous mode) + + A ZSTD_CCtx object is required to track streaming operations. + Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource. + ZSTD_CCtx object can be reused multiple times within successive compression operations. + + Start by initializing a context. + Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression. + + Then, consume your input using ZSTD_compressContinue(). + There are some important considerations to keep in mind when using this advanced function : + - ZSTD_compressContinue() has no internal buffer. It uses externally provided buffers only. + - Interface is synchronous : input is consumed entirely and produces 1+ compressed blocks. + - Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario. + Worst case evaluation is provided by ZSTD_compressBound(). + ZSTD_compressContinue() doesn't guarantee recover after a failed compression. + - ZSTD_compressContinue() presumes prior input ***is still accessible and unmodified*** (up to maximum distance size, see WindowLog). + It remembers all previous contiguous blocks, plus one separated memory segment (which can itself consists of multiple contiguous blocks) + - ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps. + In which case, it will "discard" the relevant memory section from its history. + + Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum. + It's possible to use srcSize==0, in which case, it will write a final empty block to end the frame. + Without last block mark, frames are considered unfinished (hence corrupted) by compliant decoders. + + `ZSTD_CCtx` object can be reused (ZSTD_compressBegin()) to compress again. +*/ + +/*===== Buffer-less streaming compression functions =====*/ +ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel); +ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel); +ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */ + +ZSTD_DEPRECATED("This function will likely be removed in a future release. It is misleading and has very limited utility.") +ZSTDLIB_STATIC_API +size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */ + +ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); + +/* The ZSTD_compressBegin_advanced() and ZSTD_compressBegin_usingCDict_advanced() are now DEPRECATED and will generate a compiler warning */ +ZSTD_DEPRECATED("use advanced API to access custom parameters") +ZSTDLIB_STATIC_API +size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize : If srcSize is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN */ +ZSTD_DEPRECATED("use advanced API to access custom parameters") +ZSTDLIB_STATIC_API +size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize); /* compression parameters are already set within cdict. pledgedSrcSize must be correct. If srcSize is not known, use macro ZSTD_CONTENTSIZE_UNKNOWN */ +/** + Buffer-less streaming decompression (synchronous mode) + + A ZSTD_DCtx object is required to track streaming operations. + Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it. + A ZSTD_DCtx object can be reused multiple times. + + First typical operation is to retrieve frame parameters, using ZSTD_getFrameHeader(). + Frame header is extracted from the beginning of compressed frame, so providing only the frame's beginning is enough. + Data fragment must be large enough to ensure successful decoding. + `ZSTD_frameHeaderSize_max` bytes is guaranteed to always be large enough. + result : 0 : successful decoding, the `ZSTD_frameHeader` structure is correctly filled. + >0 : `srcSize` is too small, please provide at least result bytes on next attempt. + errorCode, which can be tested using ZSTD_isError(). + + It fills a ZSTD_frameHeader structure with important information to correctly decode the frame, + such as the dictionary ID, content size, or maximum back-reference distance (`windowSize`). + Note that these values could be wrong, either because of data corruption, or because a 3rd party deliberately spoofs false information. + As a consequence, check that values remain within valid application range. + For example, do not allocate memory blindly, check that `windowSize` is within expectation. + Each application can set its own limits, depending on local restrictions. + For extended interoperability, it is recommended to support `windowSize` of at least 8 MB. + + ZSTD_decompressContinue() needs previous data blocks during decompression, up to `windowSize` bytes. + ZSTD_decompressContinue() is very sensitive to contiguity, + if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place, + or that previous contiguous segment is large enough to properly handle maximum back-reference distance. + There are multiple ways to guarantee this condition. + + The most memory efficient way is to use a round buffer of sufficient size. + Sufficient size is determined by invoking ZSTD_decodingBufferSize_min(), + which can return an error code if required value is too large for current system (in 32-bits mode). + In a round buffer methodology, ZSTD_decompressContinue() decompresses each block next to previous one, + up to the moment there is not enough room left in the buffer to guarantee decoding another full block, + which maximum size is provided in `ZSTD_frameHeader` structure, field `blockSizeMax`. + At which point, decoding can resume from the beginning of the buffer. + Note that already decoded data stored in the buffer should be flushed before being overwritten. + + There are alternatives possible, for example using two or more buffers of size `windowSize` each, though they consume more memory. + + Finally, if you control the compression process, you can also ignore all buffer size rules, + as long as the encoder and decoder progress in "lock-step", + aka use exactly the same buffer sizes, break contiguity at the same place, etc. + + Once buffers are setup, start decompression, with ZSTD_decompressBegin(). + If decompression requires a dictionary, use ZSTD_decompressBegin_usingDict() or ZSTD_decompressBegin_usingDDict(). + + Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively. + ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue(). + ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail. + + result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity). + It can be zero : it just means ZSTD_decompressContinue() has decoded some metadata item. + It can also be an error code, which can be tested with ZSTD_isError(). + + A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero. + Context can then be reset to start a new decompression. + + Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType(). + This information is not required to properly decode a frame. + + == Special case : skippable frames == + + Skippable frames allow integration of user-defined data into a flow of concatenated frames. + Skippable frames will be ignored (skipped) by decompressor. + The format of skippable frames is as follows : + a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F + b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits + c) Frame Content - any content (User Data) of length equal to Frame Size + For skippable frames ZSTD_getFrameHeader() returns zfhPtr->frameType==ZSTD_skippableFrame. + For skippable frames ZSTD_decompressContinue() always returns 0 : it only skips the content. +*/ + +/*===== Buffer-less streaming decompression functions =====*/ + +ZSTDLIB_STATIC_API size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize); /**< when frame content size is not known, pass in frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN */ + +ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx); +ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); +ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); + +ZSTDLIB_STATIC_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx); +ZSTDLIB_STATIC_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); + +/* misc */ +ZSTD_DEPRECATED("This function will likely be removed in the next minor release. It is misleading and has very limited utility.") +ZSTDLIB_STATIC_API void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx); +typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e; +ZSTDLIB_STATIC_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx); + + + + +/* ========================================= */ +/** Block level API (DEPRECATED) */ +/* ========================================= */ + +/*! + + This API is deprecated in favor of the regular compression API. + You can get the frame header down to 2 bytes by setting: + - ZSTD_c_format = ZSTD_f_zstd1_magicless + - ZSTD_c_contentSizeFlag = 0 + - ZSTD_c_checksumFlag = 0 + - ZSTD_c_dictIDFlag = 0 + + This API is not as well tested as our normal API, so we recommend not using it. + We will be removing it in a future version. If the normal API doesn't provide + the functionality you need, please open a GitHub issue. + + Block functions produce and decode raw zstd blocks, without frame metadata. + Frame metadata cost is typically ~12 bytes, which can be non-negligible for very small blocks (< 100 bytes). + But users will have to take in charge needed metadata to regenerate data, such as compressed and content sizes. + + A few rules to respect : + - Compressing and decompressing require a context structure + + Use ZSTD_createCCtx() and ZSTD_createDCtx() + - It is necessary to init context before starting + + compression : any ZSTD_compressBegin*() variant, including with dictionary + + decompression : any ZSTD_decompressBegin*() variant, including with dictionary + - Block size is limited, it must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX == 128 KB + + If input is larger than a block size, it's necessary to split input data into multiple blocks + + For inputs larger than a single block, consider using regular ZSTD_compress() instead. + Frame metadata is not that costly, and quickly becomes negligible as source size grows larger than a block. + - When a block is considered not compressible enough, ZSTD_compressBlock() result will be 0 (zero) ! + ===> In which case, nothing is produced into `dst` ! + + User __must__ test for such outcome and deal directly with uncompressed data + + A block cannot be declared incompressible if ZSTD_compressBlock() return value was != 0. + Doing so would mess up with statistics history, leading to potential data corruption. + + ZSTD_decompressBlock() _doesn't accept uncompressed data as input_ !! + + In case of multiple successive blocks, should some of them be uncompressed, + decoder must be informed of their existence in order to follow proper history. + Use ZSTD_insertBlock() for such a case. +*/ + +/*===== Raw zstd block functions =====*/ +ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_getBlockSize (const ZSTD_CCtx* cctx); +ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_insertBlock (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */ + #endif /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */ #if defined (__cplusplus) diff --git a/src/dependencies/zstd-1.5.4/lib/zstd_errors.h b/src/dependencies/zstd-1.5.6/lib/zstd_errors.h similarity index 100% rename from src/dependencies/zstd-1.5.4/lib/zstd_errors.h rename to src/dependencies/zstd-1.5.6/lib/zstd_errors.h diff --git a/src/dependencies/zstd-1.5.4/programs/.gitignore b/src/dependencies/zstd-1.5.6/programs/.gitignore similarity index 94% rename from src/dependencies/zstd-1.5.4/programs/.gitignore rename to src/dependencies/zstd-1.5.6/programs/.gitignore index 2d4edbe..42a7e30 100644 --- a/src/dependencies/zstd-1.5.4/programs/.gitignore +++ b/src/dependencies/zstd-1.5.6/programs/.gitignore @@ -9,6 +9,8 @@ zstd-small zstd-nolegacy zstd-dictBuilder zstd-dll +zstd_arm64 +zstd_x64 # Object files *.o diff --git a/src/dependencies/zstd-1.5.4/programs/BUCK b/src/dependencies/zstd-1.5.6/programs/BUCK similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/BUCK rename to src/dependencies/zstd-1.5.6/programs/BUCK diff --git a/src/dependencies/zstd-1.5.4/programs/Makefile b/src/dependencies/zstd-1.5.6/programs/Makefile similarity index 98% rename from src/dependencies/zstd-1.5.4/programs/Makefile rename to src/dependencies/zstd-1.5.6/programs/Makefile index fcff41d..4dcd841 100644 --- a/src/dependencies/zstd-1.5.4/programs/Makefile +++ b/src/dependencies/zstd-1.5.6/programs/Makefile @@ -15,12 +15,11 @@ # zstd-decompress : decompressor-only version of zstd # ########################################################################## -.PHONY: default -default: zstd-release +# default target (when running `make` with no argument) +zstd-release: -LIBZSTD := ../lib - -include $(LIBZSTD)/libzstd.mk +LIBZSTD_MK_DIR = ../lib +include $(LIBZSTD_MK_DIR)/libzstd.mk ifeq ($(shell $(CC) -v 2>&1 | $(GREP) -c "gcc version "), 1) ALIGN_LOOP = -falign-loops=32 @@ -223,9 +222,9 @@ zstd-noxz : zstd ## zstd-dll: zstd executable linked to dynamic library libzstd (must have same version) .PHONY: zstd-dll -zstd-dll : LDFLAGS+= -L$(LIBZSTD) +zstd-dll : LDFLAGS+= -L$(LIB_BINDIR) zstd-dll : LDLIBS += -lzstd -zstd-dll : ZSTDLIB_LOCAL_SRC = xxhash.c +zstd-dll : ZSTDLIB_LOCAL_SRC = xxhash.c pool.c threading.c zstd-dll : zstd @@ -346,7 +345,7 @@ include $(wildcard $(DEPFILES)) #----------------------------------------------------------------------------- # make install is validated only for Linux, macOS, BSD, Hurd and Solaris targets #----------------------------------------------------------------------------- -ifneq (,$(filter $(UNAME),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku AIX)) +ifneq (,$(filter $(UNAME),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku AIX MSYS_NT CYGWIN_NT)) HAVE_COLORNEVER = $(shell echo a | egrep --color=never a > /dev/null 2> /dev/null && echo 1 || echo 0) EGREP_OPTIONS ?= diff --git a/src/dependencies/zstd-1.5.4/programs/README.md b/src/dependencies/zstd-1.5.6/programs/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/README.md rename to src/dependencies/zstd-1.5.6/programs/README.md diff --git a/src/dependencies/zstd-1.5.4/programs/benchfn.c b/src/dependencies/zstd-1.5.6/programs/benchfn.c similarity index 99% rename from src/dependencies/zstd-1.5.4/programs/benchfn.c rename to src/dependencies/zstd-1.5.6/programs/benchfn.c index 8e6726f..3e042cf 100644 --- a/src/dependencies/zstd-1.5.4/programs/benchfn.c +++ b/src/dependencies/zstd-1.5.6/programs/benchfn.c @@ -108,7 +108,6 @@ static BMK_runOutcome_t BMK_setValid_runTime(BMK_runTime_t runTime) BMK_runOutcome_t BMK_benchFunction(BMK_benchParams_t p, unsigned nbLoops) { - size_t dstSize = 0; nbLoops += !nbLoops; /* minimum nbLoops is 1 */ /* init */ @@ -118,7 +117,8 @@ BMK_runOutcome_t BMK_benchFunction(BMK_benchParams_t p, } } /* benchmark */ - { UTIL_time_t const clockStart = UTIL_getTime(); + { size_t dstSize = 0; + UTIL_time_t const clockStart = UTIL_getTime(); unsigned loopNb, blockNb; if (p.initFn != NULL) p.initFn(p.initPayload); for (loopNb = 0; loopNb < nbLoops; loopNb++) { diff --git a/src/dependencies/zstd-1.5.4/programs/benchfn.h b/src/dependencies/zstd-1.5.6/programs/benchfn.h similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/benchfn.h rename to src/dependencies/zstd-1.5.6/programs/benchfn.h diff --git a/src/dependencies/zstd-1.5.6/programs/benchzstd.c b/src/dependencies/zstd-1.5.6/programs/benchzstd.c new file mode 100644 index 0000000..29ee595 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/programs/benchzstd.c @@ -0,0 +1,1264 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* ************************************** + * Tuning parameters + ****************************************/ +#ifndef BMK_TIMETEST_DEFAULT_S /* default minimum time per test */ +# define BMK_TIMETEST_DEFAULT_S 3 +#endif + +/* ************************************* + * Includes + ***************************************/ +/* this must be included first */ +#include "platform.h" /* Large Files support, compiler specifics */ + +/* then following system includes */ +#include /* assert */ +#include +#include /* fprintf, fopen */ +#include /* malloc, free */ +#include /* memset, strerror */ +#include "util.h" /* UTIL_getFileSize, UTIL_sleep */ +#include "../lib/common/mem.h" +#include "benchfn.h" +#include "timefn.h" /* UTIL_time_t */ +#ifndef ZSTD_STATIC_LINKING_ONLY +# define ZSTD_STATIC_LINKING_ONLY +#endif +#include "../lib/zstd.h" +#include "datagen.h" /* RDG_genBuffer */ +#include "lorem.h" /* LOREM_genBuffer */ +#ifndef XXH_INLINE_ALL +# define XXH_INLINE_ALL +#endif +#include "../lib/common/xxhash.h" +#include "../lib/zstd_errors.h" +#include "benchzstd.h" + +/* ************************************* + * Constants + ***************************************/ +#ifndef ZSTD_GIT_COMMIT +# define ZSTD_GIT_COMMIT_STRING "" +#else +# define ZSTD_GIT_COMMIT_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_GIT_COMMIT) +#endif + +#define TIMELOOP_MICROSEC (1 * 1000000ULL) /* 1 second */ +#define TIMELOOP_NANOSEC (1 * 1000000000ULL) /* 1 second */ +#define ACTIVEPERIOD_MICROSEC (70 * TIMELOOP_MICROSEC) /* 70 seconds */ +#define COOLPERIOD_SEC 10 + +#define KB *(1 << 10) +#define MB *(1 << 20) +#define GB *(1U << 30) + +#define BMK_RUNTEST_DEFAULT_MS 1000 + +static const size_t maxMemory = (sizeof(size_t) == 4) + ? + /* 32-bit */ (2 GB - 64 MB) + : + /* 64-bit */ (size_t)(1ULL << ((sizeof(size_t) * 8) - 31)); + +/* ************************************* + * console display + ***************************************/ +#define DISPLAY(...) \ + { \ + fprintf(stderr, __VA_ARGS__); \ + fflush(NULL); \ + } +#define DISPLAYLEVEL(l, ...) \ + if (displayLevel >= l) { \ + DISPLAY(__VA_ARGS__); \ + } +/* 0 : no display; 1: errors; 2 : + result + interaction + warnings; 3 : + + * progression; 4 : + information */ +#define OUTPUT(...) \ + { \ + fprintf(stdout, __VA_ARGS__); \ + fflush(NULL); \ + } +#define OUTPUTLEVEL(l, ...) \ + if (displayLevel >= l) { \ + OUTPUT(__VA_ARGS__); \ + } + +/* ************************************* + * Exceptions + ***************************************/ +#ifndef DEBUG +# define DEBUG 0 +#endif +#define DEBUGOUTPUT(...) \ + { \ + if (DEBUG) \ + DISPLAY(__VA_ARGS__); \ + } + +#define RETURN_ERROR_INT(errorNum, ...) \ + { \ + DEBUGOUTPUT("%s: %i: \n", __FILE__, __LINE__); \ + DISPLAYLEVEL(1, "Error %i : ", errorNum); \ + DISPLAYLEVEL(1, __VA_ARGS__); \ + DISPLAYLEVEL(1, " \n"); \ + return errorNum; \ + } + +#define CHECK_Z(zf) \ + { \ + size_t const zerr = zf; \ + if (ZSTD_isError(zerr)) { \ + DEBUGOUTPUT("%s: %i: \n", __FILE__, __LINE__); \ + DISPLAY("Error : "); \ + DISPLAY("%s failed : %s", #zf, ZSTD_getErrorName(zerr)); \ + DISPLAY(" \n"); \ + exit(1); \ + } \ + } + +#define RETURN_ERROR(errorNum, retType, ...) \ + { \ + retType r; \ + memset(&r, 0, sizeof(retType)); \ + DEBUGOUTPUT("%s: %i: \n", __FILE__, __LINE__); \ + DISPLAYLEVEL(1, "Error %i : ", errorNum); \ + DISPLAYLEVEL(1, __VA_ARGS__); \ + DISPLAYLEVEL(1, " \n"); \ + r.tag = errorNum; \ + return r; \ + } + +/* replacement for snprintf(), which is not supported by C89 + * sprintf() would be the supported one, but it's labelled unsafe, + * so some modern static analyzer will flag it as such, making it unusable. + * formatString_u() replaces snprintf() for the specific case where there are only %u arguments */ +static int formatString_u(char* buffer, size_t buffer_size, const char* formatString, unsigned int value) +{ + size_t written = 0; + int i; + assert(value <= 100); + + for (i = 0; formatString[i] != '\0' && written < buffer_size - 1; ++i) { + if (formatString[i] != '%') { + buffer[written++] = formatString[i]; + continue; + } + + if (formatString[++i] == 'u') { + /* Handle single digit */ + if (value < 10) { + buffer[written++] = '0' + (char)value; + } else if (value < 100) { + /* Handle two digits */ + if (written >= buffer_size - 2) { + return -1; /* buffer overflow */ + } + buffer[written++] = '0' + (char)(value / 10); + buffer[written++] = '0' + (char)(value % 10); + } else { /* 100 */ + if (written >= buffer_size - 3) { + return -1; /* buffer overflow */ + } + buffer[written++] = '1'; + buffer[written++] = '0'; + buffer[written++] = '0'; + } + } else if (formatString[i] == '%') { /* Check for escaped percent sign */ + buffer[written++] = '%'; + } else { + return -1; /* unsupported format */ + } + } + + if (written < buffer_size) { + buffer[written] = '\0'; + } else { + buffer[0] = '\0'; /* Handle truncation */ + } + + return (int)written; +} + +/* ************************************* + * Benchmark Parameters + ***************************************/ + +BMK_advancedParams_t BMK_initAdvancedParams(void) +{ + BMK_advancedParams_t const res = { + BMK_both, /* mode */ + BMK_TIMETEST_DEFAULT_S, /* nbSeconds */ + 0, /* blockSize */ + 0, /* targetCBlockSize */ + 0, /* nbWorkers */ + 0, /* realTime */ + 0, /* additionalParam */ + 0, /* ldmFlag */ + 0, /* ldmMinMatch */ + 0, /* ldmHashLog */ + 0, /* ldmBuckSizeLog */ + 0, /* ldmHashRateLog */ + ZSTD_ps_auto, /* literalCompressionMode */ + 0 /* useRowMatchFinder */ + }; + return res; +} + +/* ******************************************************** + * Bench functions + **********************************************************/ +typedef struct { + const void* srcPtr; + size_t srcSize; + void* cPtr; + size_t cRoom; + size_t cSize; + void* resPtr; + size_t resSize; +} blockParam_t; + +#undef MIN +#undef MAX +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +static void BMK_initCCtx( + ZSTD_CCtx* ctx, + const void* dictBuffer, + size_t dictBufferSize, + int cLevel, + const ZSTD_compressionParameters* comprParams, + const BMK_advancedParams_t* adv) +{ + ZSTD_CCtx_reset(ctx, ZSTD_reset_session_and_parameters); + if (adv->nbWorkers == 1) { + CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_nbWorkers, 0)); + } else { + CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_nbWorkers, adv->nbWorkers)); + } + CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, cLevel)); + CHECK_Z(ZSTD_CCtx_setParameter( + ctx, ZSTD_c_useRowMatchFinder, adv->useRowMatchFinder)); + CHECK_Z(ZSTD_CCtx_setParameter( + ctx, ZSTD_c_enableLongDistanceMatching, adv->ldmFlag)); + CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_ldmMinMatch, adv->ldmMinMatch)); + CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_ldmHashLog, adv->ldmHashLog)); + CHECK_Z(ZSTD_CCtx_setParameter( + ctx, ZSTD_c_ldmBucketSizeLog, adv->ldmBucketSizeLog)); + CHECK_Z(ZSTD_CCtx_setParameter( + ctx, ZSTD_c_ldmHashRateLog, adv->ldmHashRateLog)); + CHECK_Z(ZSTD_CCtx_setParameter( + ctx, ZSTD_c_windowLog, (int)comprParams->windowLog)); + CHECK_Z(ZSTD_CCtx_setParameter( + ctx, ZSTD_c_hashLog, (int)comprParams->hashLog)); + CHECK_Z(ZSTD_CCtx_setParameter( + ctx, ZSTD_c_chainLog, (int)comprParams->chainLog)); + CHECK_Z(ZSTD_CCtx_setParameter( + ctx, ZSTD_c_searchLog, (int)comprParams->searchLog)); + CHECK_Z(ZSTD_CCtx_setParameter( + ctx, ZSTD_c_minMatch, (int)comprParams->minMatch)); + CHECK_Z(ZSTD_CCtx_setParameter( + ctx, ZSTD_c_targetLength, (int)comprParams->targetLength)); + CHECK_Z(ZSTD_CCtx_setParameter( + ctx, + ZSTD_c_literalCompressionMode, + (int)adv->literalCompressionMode)); + CHECK_Z(ZSTD_CCtx_setParameter( + ctx, ZSTD_c_strategy, (int)comprParams->strategy)); + CHECK_Z(ZSTD_CCtx_setParameter( + ctx, ZSTD_c_targetCBlockSize, (int)adv->targetCBlockSize)); + CHECK_Z(ZSTD_CCtx_loadDictionary(ctx, dictBuffer, dictBufferSize)); +} + +static void +BMK_initDCtx(ZSTD_DCtx* dctx, const void* dictBuffer, size_t dictBufferSize) +{ + CHECK_Z(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_and_parameters)); + CHECK_Z(ZSTD_DCtx_loadDictionary(dctx, dictBuffer, dictBufferSize)); +} + +typedef struct { + ZSTD_CCtx* cctx; + const void* dictBuffer; + size_t dictBufferSize; + int cLevel; + const ZSTD_compressionParameters* comprParams; + const BMK_advancedParams_t* adv; +} BMK_initCCtxArgs; + +static size_t local_initCCtx(void* payload) +{ + BMK_initCCtxArgs* ag = (BMK_initCCtxArgs*)payload; + BMK_initCCtx( + ag->cctx, + ag->dictBuffer, + ag->dictBufferSize, + ag->cLevel, + ag->comprParams, + ag->adv); + return 0; +} + +typedef struct { + ZSTD_DCtx* dctx; + const void* dictBuffer; + size_t dictBufferSize; +} BMK_initDCtxArgs; + +static size_t local_initDCtx(void* payload) +{ + BMK_initDCtxArgs* ag = (BMK_initDCtxArgs*)payload; + BMK_initDCtx(ag->dctx, ag->dictBuffer, ag->dictBufferSize); + return 0; +} + +/* `addArgs` is the context */ +static size_t local_defaultCompress( + const void* srcBuffer, + size_t srcSize, + void* dstBuffer, + size_t dstSize, + void* addArgs) +{ + ZSTD_CCtx* const cctx = (ZSTD_CCtx*)addArgs; + return ZSTD_compress2(cctx, dstBuffer, dstSize, srcBuffer, srcSize); +} + +/* `addArgs` is the context */ +static size_t local_defaultDecompress( + const void* srcBuffer, + size_t srcSize, + void* dstBuffer, + size_t dstCapacity, + void* addArgs) +{ + size_t moreToFlush = 1; + ZSTD_DCtx* const dctx = (ZSTD_DCtx*)addArgs; + ZSTD_inBuffer in; + ZSTD_outBuffer out; + in.src = srcBuffer; + in.size = srcSize; + in.pos = 0; + out.dst = dstBuffer; + out.size = dstCapacity; + out.pos = 0; + while (moreToFlush) { + if (out.pos == out.size) { + return (size_t)-ZSTD_error_dstSize_tooSmall; + } + moreToFlush = ZSTD_decompressStream(dctx, &out, &in); + if (ZSTD_isError(moreToFlush)) { + return moreToFlush; + } + } + return out.pos; +} + +/* ================================================================= */ +/* Benchmark Zstandard, mem-to-mem scenarios */ +/* ================================================================= */ + +int BMK_isSuccessful_benchOutcome(BMK_benchOutcome_t outcome) +{ + return outcome.tag == 0; +} + +BMK_benchResult_t BMK_extract_benchResult(BMK_benchOutcome_t outcome) +{ + assert(outcome.tag == 0); + return outcome.internal_never_use_directly; +} + +static BMK_benchOutcome_t BMK_benchOutcome_error(void) +{ + BMK_benchOutcome_t b; + memset(&b, 0, sizeof(b)); + b.tag = 1; + return b; +} + +static BMK_benchOutcome_t BMK_benchOutcome_setValidResult( + BMK_benchResult_t result) +{ + BMK_benchOutcome_t b; + b.tag = 0; + b.internal_never_use_directly = result; + return b; +} + +/* benchMem with no allocation */ +static BMK_benchOutcome_t BMK_benchMemAdvancedNoAlloc( + const void** srcPtrs, + size_t* srcSizes, + void** cPtrs, + size_t* cCapacities, + size_t* cSizes, + void** resPtrs, + size_t* resSizes, + void** resultBufferPtr, + void* compressedBuffer, + size_t maxCompressedSize, + BMK_timedFnState_t* timeStateCompress, + BMK_timedFnState_t* timeStateDecompress, + + const void* srcBuffer, + size_t srcSize, + const size_t* fileSizes, + unsigned nbFiles, + const int cLevel, + const ZSTD_compressionParameters* comprParams, + const void* dictBuffer, + size_t dictBufferSize, + ZSTD_CCtx* cctx, + ZSTD_DCtx* dctx, + int displayLevel, + const char* displayName, + const BMK_advancedParams_t* adv) +{ + size_t const blockSize = + ((adv->blockSize >= 32 && (adv->mode != BMK_decodeOnly)) + ? adv->blockSize + : srcSize) + + (!srcSize); /* avoid div by 0 */ + BMK_benchResult_t benchResult; + size_t const loadedCompressedSize = srcSize; + size_t cSize = 0; + double ratio = 0.; + U32 nbBlocks; + + assert(cctx != NULL); + assert(dctx != NULL); + + /* init */ + memset(&benchResult, 0, sizeof(benchResult)); + if (strlen(displayName) > 17) + displayName += + strlen(displayName) - 17; /* display last 17 characters */ + if (adv->mode == BMK_decodeOnly) { + /* benchmark only decompression : source must be already compressed */ + const char* srcPtr = (const char*)srcBuffer; + U64 totalDSize64 = 0; + U32 fileNb; + for (fileNb = 0; fileNb < nbFiles; fileNb++) { + U64 const fSize64 = + ZSTD_findDecompressedSize(srcPtr, fileSizes[fileNb]); + if (fSize64 == ZSTD_CONTENTSIZE_UNKNOWN) { + RETURN_ERROR( + 32, + BMK_benchOutcome_t, + "Decompressed size cannot be determined: cannot benchmark"); + } + if (fSize64 == ZSTD_CONTENTSIZE_ERROR) { + RETURN_ERROR( + 32, + BMK_benchOutcome_t, + "Error while trying to assess decompressed size: data may be invalid"); + } + totalDSize64 += fSize64; + srcPtr += fileSizes[fileNb]; + } + { + size_t const decodedSize = (size_t)totalDSize64; + assert((U64)decodedSize == totalDSize64); /* check overflow */ + free(*resultBufferPtr); + if (totalDSize64 > decodedSize) { /* size_t overflow */ + RETURN_ERROR( + 32, + BMK_benchOutcome_t, + "decompressed size is too large for local system"); + } + *resultBufferPtr = malloc(decodedSize); + if (!(*resultBufferPtr)) { + RETURN_ERROR( + 33, + BMK_benchOutcome_t, + "allocation error: not enough memory"); + } + cSize = srcSize; + srcSize = decodedSize; + ratio = (double)srcSize / (double)cSize; + } + } + + /* Init data blocks */ + { + const char* srcPtr = (const char*)srcBuffer; + char* cPtr = (char*)compressedBuffer; + char* resPtr = (char*)(*resultBufferPtr); + U32 fileNb; + for (nbBlocks = 0, fileNb = 0; fileNb < nbFiles; fileNb++) { + size_t remaining = fileSizes[fileNb]; + U32 const nbBlocksforThisFile = (adv->mode == BMK_decodeOnly) + ? 1 + : (U32)((remaining + (blockSize - 1)) / blockSize); + U32 const blockEnd = nbBlocks + nbBlocksforThisFile; + for (; nbBlocks < blockEnd; nbBlocks++) { + size_t const thisBlockSize = MIN(remaining, blockSize); + srcPtrs[nbBlocks] = srcPtr; + srcSizes[nbBlocks] = thisBlockSize; + cPtrs[nbBlocks] = cPtr; + cCapacities[nbBlocks] = (adv->mode == BMK_decodeOnly) + ? thisBlockSize + : ZSTD_compressBound(thisBlockSize); + resPtrs[nbBlocks] = resPtr; + resSizes[nbBlocks] = (adv->mode == BMK_decodeOnly) + ? (size_t)ZSTD_findDecompressedSize( + srcPtr, thisBlockSize) + : thisBlockSize; + srcPtr += thisBlockSize; + cPtr += cCapacities[nbBlocks]; + resPtr += thisBlockSize; + remaining -= thisBlockSize; + if (adv->mode == BMK_decodeOnly) { + cSizes[nbBlocks] = thisBlockSize; + benchResult.cSize = thisBlockSize; + } + } + } + } + + /* warming up `compressedBuffer` */ + if (adv->mode == BMK_decodeOnly) { + memcpy(compressedBuffer, srcBuffer, loadedCompressedSize); + } else { + RDG_genBuffer(compressedBuffer, maxCompressedSize, 0.10, 0.50, 1); + } + + if (!UTIL_support_MT_measurements() && adv->nbWorkers > 1) { + OUTPUTLEVEL( + 2, + "Warning : time measurements may be incorrect in multithreading mode... \n") + } + + /* Bench */ + { + U64 const crcOrig = (adv->mode == BMK_decodeOnly) + ? 0 + : XXH64(srcBuffer, srcSize, 0); +#define NB_MARKS 4 + const char* marks[NB_MARKS] = { " |", " /", " =", " \\" }; + U32 markNb = 0; + int compressionCompleted = (adv->mode == BMK_decodeOnly); + int decompressionCompleted = (adv->mode == BMK_compressOnly); + BMK_benchParams_t cbp, dbp; + BMK_initCCtxArgs cctxprep; + BMK_initDCtxArgs dctxprep; + + cbp.benchFn = local_defaultCompress; /* ZSTD_compress2 */ + cbp.benchPayload = cctx; + cbp.initFn = local_initCCtx; /* BMK_initCCtx */ + cbp.initPayload = &cctxprep; + cbp.errorFn = ZSTD_isError; + cbp.blockCount = nbBlocks; + cbp.srcBuffers = srcPtrs; + cbp.srcSizes = srcSizes; + cbp.dstBuffers = cPtrs; + cbp.dstCapacities = cCapacities; + cbp.blockResults = cSizes; + + cctxprep.cctx = cctx; + cctxprep.dictBuffer = dictBuffer; + cctxprep.dictBufferSize = dictBufferSize; + cctxprep.cLevel = cLevel; + cctxprep.comprParams = comprParams; + cctxprep.adv = adv; + + dbp.benchFn = local_defaultDecompress; + dbp.benchPayload = dctx; + dbp.initFn = local_initDCtx; + dbp.initPayload = &dctxprep; + dbp.errorFn = ZSTD_isError; + dbp.blockCount = nbBlocks; + dbp.srcBuffers = (const void* const*)cPtrs; + dbp.srcSizes = cSizes; + dbp.dstBuffers = resPtrs; + dbp.dstCapacities = resSizes; + dbp.blockResults = NULL; + + dctxprep.dctx = dctx; + dctxprep.dictBuffer = dictBuffer; + dctxprep.dictBufferSize = dictBufferSize; + + OUTPUTLEVEL(2, "\r%70s\r", ""); /* blank line */ + assert(srcSize < UINT_MAX); + OUTPUTLEVEL( + 2, + "%2s-%-17.17s :%10u -> \r", + marks[markNb], + displayName, + (unsigned)srcSize); + + while (!(compressionCompleted && decompressionCompleted)) { + if (!compressionCompleted) { + BMK_runOutcome_t const cOutcome = + BMK_benchTimedFn(timeStateCompress, cbp); + + if (!BMK_isSuccessful_runOutcome(cOutcome)) { + RETURN_ERROR(30, BMK_benchOutcome_t, "compression error"); + } + + { + BMK_runTime_t const cResult = BMK_extract_runTime(cOutcome); + cSize = cResult.sumOfReturn; + ratio = (double)srcSize / (double)cSize; + { + BMK_benchResult_t newResult; + newResult.cSpeed = + (U64)((double)srcSize * TIMELOOP_NANOSEC + / cResult.nanoSecPerRun); + benchResult.cSize = cSize; + if (newResult.cSpeed > benchResult.cSpeed) + benchResult.cSpeed = newResult.cSpeed; + } + } + + { + int const ratioAccuracy = (ratio < 10.) ? 3 : 2; + assert(cSize < UINT_MAX); + OUTPUTLEVEL( + 2, + "%2s-%-17.17s :%10u ->%10u (x%5.*f), %6.*f MB/s \r", + marks[markNb], + displayName, + (unsigned)srcSize, + (unsigned)cSize, + ratioAccuracy, + ratio, + benchResult.cSpeed < (10 * MB_UNIT) ? 2 : 1, + (double)benchResult.cSpeed / MB_UNIT); + } + compressionCompleted = + BMK_isCompleted_TimedFn(timeStateCompress); + } + + if (!decompressionCompleted) { + BMK_runOutcome_t const dOutcome = + BMK_benchTimedFn(timeStateDecompress, dbp); + + if (!BMK_isSuccessful_runOutcome(dOutcome)) { + RETURN_ERROR(30, BMK_benchOutcome_t, "decompression error"); + } + + { + BMK_runTime_t const dResult = BMK_extract_runTime(dOutcome); + U64 const newDSpeed = + (U64)((double)srcSize * TIMELOOP_NANOSEC + / dResult.nanoSecPerRun); + if (newDSpeed > benchResult.dSpeed) + benchResult.dSpeed = newDSpeed; + } + + { + int const ratioAccuracy = (ratio < 10.) ? 3 : 2; + OUTPUTLEVEL( + 2, + "%2s-%-17.17s :%10u ->%10u (x%5.*f), %6.*f MB/s, %6.1f MB/s\r", + marks[markNb], + displayName, + (unsigned)srcSize, + (unsigned)cSize, + ratioAccuracy, + ratio, + benchResult.cSpeed < (10 * MB_UNIT) ? 2 : 1, + (double)benchResult.cSpeed / MB_UNIT, + (double)benchResult.dSpeed / MB_UNIT); + } + decompressionCompleted = + BMK_isCompleted_TimedFn(timeStateDecompress); + } + markNb = (markNb + 1) % NB_MARKS; + } /* while (!(compressionCompleted && decompressionCompleted)) */ + + /* CRC Checking */ + { + const BYTE* resultBuffer = (const BYTE*)(*resultBufferPtr); + U64 const crcCheck = XXH64(resultBuffer, srcSize, 0); + if ((adv->mode == BMK_both) && (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] != resultBuffer[u]) { + unsigned segNb, bNb, pos; + size_t bacc = 0; + DISPLAY("Decoding error at pos %u ", (unsigned)u); + for (segNb = 0; segNb < nbBlocks; segNb++) { + if (bacc + srcSizes[segNb] > u) + break; + bacc += srcSizes[segNb]; + } + pos = (U32)(u - bacc); + bNb = pos / (128 KB); + DISPLAY("(sample %u, block %u, pos %u) \n", + segNb, + bNb, + pos); + { + size_t const lowest = (u > 5) ? 5 : u; + size_t n; + DISPLAY("origin: "); + for (n = lowest; n > 0; n--) + DISPLAY("%02X ", + ((const BYTE*)srcBuffer)[u - n]); + DISPLAY(" :%02X: ", ((const BYTE*)srcBuffer)[u]); + for (n = 1; n < 3; n++) + DISPLAY("%02X ", + ((const BYTE*)srcBuffer)[u + n]); + DISPLAY(" \n"); + DISPLAY("decode: "); + for (n = lowest; n > 0; n--) + DISPLAY("%02X ", resultBuffer[u - n]); + DISPLAY(" :%02X: ", resultBuffer[u]); + for (n = 1; n < 3; n++) + DISPLAY("%02X ", resultBuffer[u + n]); + DISPLAY(" \n"); + } + break; + } + if (u == srcSize - 1) { /* should never happen */ + DISPLAY("no difference detected\n"); + } + } /* for (u=0; umode == BMK_both) && (crcOrig!=crcCheck)) */ + } /* CRC Checking */ + + if (displayLevel + == 1) { /* hidden display mode -q, used by python speed benchmark */ + double const cSpeed = (double)benchResult.cSpeed / MB_UNIT; + double const dSpeed = (double)benchResult.dSpeed / MB_UNIT; + if (adv->additionalParam) { + OUTPUT("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s (param=%d)\n", + cLevel, + (int)cSize, + ratio, + cSpeed, + dSpeed, + displayName, + adv->additionalParam); + } else { + OUTPUT("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s\n", + cLevel, + (int)cSize, + ratio, + cSpeed, + dSpeed, + displayName); + } + } + + OUTPUTLEVEL(2, "%2i#\n", cLevel); + } /* Bench */ + + benchResult.cMem = + (1ULL << (comprParams->windowLog)) + ZSTD_sizeof_CCtx(cctx); + return BMK_benchOutcome_setValidResult(benchResult); +} + +BMK_benchOutcome_t BMK_benchMemAdvanced( + const void* srcBuffer, + size_t srcSize, + void* dstBuffer, + size_t dstCapacity, + const size_t* fileSizes, + unsigned nbFiles, + int cLevel, + const ZSTD_compressionParameters* comprParams, + const void* dictBuffer, + size_t dictBufferSize, + int displayLevel, + const char* displayName, + const BMK_advancedParams_t* adv) + +{ + int const dstParamsError = + !dstBuffer ^ !dstCapacity; /* must be both NULL or none */ + + size_t const blockSize = + ((adv->blockSize >= 32 && (adv->mode != BMK_decodeOnly)) + ? adv->blockSize + : srcSize) + + (!srcSize) /* avoid div by 0 */; + U32 const maxNbBlocks = + (U32)((srcSize + (blockSize - 1)) / blockSize) + nbFiles; + + /* these are the blockTable parameters, just split up */ + const void** const srcPtrs = + (const void**)malloc(maxNbBlocks * sizeof(void*)); + size_t* const srcSizes = (size_t*)malloc(maxNbBlocks * sizeof(size_t)); + + void** const cPtrs = (void**)malloc(maxNbBlocks * sizeof(void*)); + size_t* const cSizes = (size_t*)malloc(maxNbBlocks * sizeof(size_t)); + size_t* const cCapacities = (size_t*)malloc(maxNbBlocks * sizeof(size_t)); + + void** const resPtrs = (void**)malloc(maxNbBlocks * sizeof(void*)); + size_t* const resSizes = (size_t*)malloc(maxNbBlocks * sizeof(size_t)); + + BMK_timedFnState_t* timeStateCompress = BMK_createTimedFnState( + adv->nbSeconds * 1000, BMK_RUNTEST_DEFAULT_MS); + BMK_timedFnState_t* timeStateDecompress = BMK_createTimedFnState( + adv->nbSeconds * 1000, BMK_RUNTEST_DEFAULT_MS); + + ZSTD_CCtx* const cctx = ZSTD_createCCtx(); + ZSTD_DCtx* const dctx = ZSTD_createDCtx(); + + const size_t maxCompressedSize = dstCapacity + ? dstCapacity + : ZSTD_compressBound(srcSize) + (maxNbBlocks * 1024); + + void* const internalDstBuffer = + dstBuffer ? NULL : malloc(maxCompressedSize); + void* const compressedBuffer = dstBuffer ? dstBuffer : internalDstBuffer; + + BMK_benchOutcome_t outcome = + BMK_benchOutcome_error(); /* error by default */ + + void* resultBuffer = srcSize ? malloc(srcSize) : NULL; + + int const allocationincomplete = !srcPtrs || !srcSizes || !cPtrs || !cSizes + || !cCapacities || !resPtrs || !resSizes || !timeStateCompress + || !timeStateDecompress || !cctx || !dctx || !compressedBuffer + || !resultBuffer; + + if (!allocationincomplete && !dstParamsError) { + outcome = BMK_benchMemAdvancedNoAlloc( + srcPtrs, + srcSizes, + cPtrs, + cCapacities, + cSizes, + resPtrs, + resSizes, + &resultBuffer, + compressedBuffer, + maxCompressedSize, + timeStateCompress, + timeStateDecompress, + srcBuffer, + srcSize, + fileSizes, + nbFiles, + cLevel, + comprParams, + dictBuffer, + dictBufferSize, + cctx, + dctx, + displayLevel, + displayName, + adv); + } + + /* clean up */ + BMK_freeTimedFnState(timeStateCompress); + BMK_freeTimedFnState(timeStateDecompress); + + ZSTD_freeCCtx(cctx); + ZSTD_freeDCtx(dctx); + + free(internalDstBuffer); + free(resultBuffer); + + free((void*)srcPtrs); + free(srcSizes); + free(cPtrs); + free(cSizes); + free(cCapacities); + free(resPtrs); + free(resSizes); + + if (allocationincomplete) { + RETURN_ERROR( + 31, BMK_benchOutcome_t, "allocation error : not enough memory"); + } + + if (dstParamsError) { + RETURN_ERROR(32, BMK_benchOutcome_t, "Dst parameters not coherent"); + } + return outcome; +} + +BMK_benchOutcome_t BMK_benchMem( + const void* srcBuffer, + size_t srcSize, + const size_t* fileSizes, + unsigned nbFiles, + int cLevel, + const ZSTD_compressionParameters* comprParams, + const void* dictBuffer, + size_t dictBufferSize, + int displayLevel, + const char* displayName) +{ + BMK_advancedParams_t const adv = BMK_initAdvancedParams(); + return BMK_benchMemAdvanced( + srcBuffer, + srcSize, + NULL, + 0, + fileSizes, + nbFiles, + cLevel, + comprParams, + dictBuffer, + dictBufferSize, + displayLevel, + displayName, + &adv); +} + +static BMK_benchOutcome_t BMK_benchCLevel( + const void* srcBuffer, + size_t benchedSize, + const size_t* fileSizes, + unsigned nbFiles, + int cLevel, + const ZSTD_compressionParameters* comprParams, + const void* dictBuffer, + size_t dictBufferSize, + int displayLevel, + const char* displayName, + BMK_advancedParams_t const* const adv) +{ + const char* pch = strrchr(displayName, '\\'); /* Windows */ + if (!pch) + pch = strrchr(displayName, '/'); /* Linux */ + if (pch) + displayName = pch + 1; + + if (adv->realTime) { + DISPLAYLEVEL(2, "Note : switching to real-time priority \n"); + SET_REALTIME_PRIORITY; + } + + if (displayLevel == 1 && !adv->additionalParam) /* --quiet mode */ + OUTPUT("bench %s %s: input %u bytes, %u seconds, %u KB blocks\n", + ZSTD_VERSION_STRING, + ZSTD_GIT_COMMIT_STRING, + (unsigned)benchedSize, + adv->nbSeconds, + (unsigned)(adv->blockSize >> 10)); + + return BMK_benchMemAdvanced( + srcBuffer, + benchedSize, + NULL, + 0, + fileSizes, + nbFiles, + cLevel, + comprParams, + dictBuffer, + dictBufferSize, + displayLevel, + displayName, + adv); +} + +int BMK_syntheticTest( + int cLevel, + double compressibility, + const ZSTD_compressionParameters* compressionParams, + int displayLevel, + const BMK_advancedParams_t* adv) +{ + char nameBuff[20] = { 0 }; + const char* name = nameBuff; + size_t const benchedSize = adv->blockSize ? adv->blockSize : 10000000; + void* srcBuffer; + BMK_benchOutcome_t res; + + if (cLevel > ZSTD_maxCLevel()) { + DISPLAYLEVEL(1, "Invalid Compression Level"); + return 15; + } + + /* Memory allocation */ + srcBuffer = malloc(benchedSize); + if (!srcBuffer) { + DISPLAYLEVEL(1, "allocation error : not enough memory"); + return 16; + } + + /* Fill input buffer */ + if (compressibility < 0.0) { + LOREM_genBuffer(srcBuffer, benchedSize, 0); + name = "Lorem ipsum"; + } else { + RDG_genBuffer(srcBuffer, benchedSize, compressibility, 0.0, 0); + formatString_u( + nameBuff, + sizeof(nameBuff), + "Synthetic %u%%", + (unsigned)(compressibility * 100)); + } + + /* Bench */ + res = BMK_benchCLevel( + srcBuffer, + benchedSize, + &benchedSize /* ? */, + 1 /* ? */, + cLevel, + compressionParams, + NULL, + 0, /* dictionary */ + displayLevel, + name, + adv); + + /* clean up */ + free(srcBuffer); + + return !BMK_isSuccessful_benchOutcome(res); +} + +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 && requiredMem > 0); + + free(testmem); + return (size_t)(requiredMem); +} + +/*! BMK_loadFiles() : + * Loads `buffer` with content of files listed within `fileNamesTable`. + * At most, fills `buffer` entirely. */ +static int BMK_loadFiles( + void* buffer, + size_t bufferSize, + size_t* fileSizes, + const char* const* fileNamesTable, + unsigned nbFiles, + int displayLevel) +{ + size_t pos = 0, totalSize = 0; + unsigned n; + for (n = 0; n < nbFiles; n++) { + U64 fileSize = UTIL_getFileSize( + fileNamesTable[n]); /* last file may be shortened */ + if (UTIL_isDirectory(fileNamesTable[n])) { + DISPLAYLEVEL( + 2, "Ignoring %s directory... \n", fileNamesTable[n]); + fileSizes[n] = 0; + continue; + } + if (fileSize == UTIL_FILESIZE_UNKNOWN) { + DISPLAYLEVEL( + 2, + "Cannot evaluate size of %s, ignoring ... \n", + fileNamesTable[n]); + fileSizes[n] = 0; + continue; + } + { + FILE* const f = fopen(fileNamesTable[n], "rb"); + if (f == NULL) + RETURN_ERROR_INT( + 10, "impossible to open file %s", fileNamesTable[n]); + OUTPUTLEVEL(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) + RETURN_ERROR_INT( + 11, "could not read %s", fileNamesTable[n]); + pos += readSize; + } + fileSizes[n] = (size_t)fileSize; + totalSize += (size_t)fileSize; + fclose(f); + } + } + + if (totalSize == 0) + RETURN_ERROR_INT(12, "no data to bench"); + return 0; +} + +int BMK_benchFilesAdvanced( + const char* const* fileNamesTable, + unsigned nbFiles, + const char* dictFileName, + int cLevel, + const ZSTD_compressionParameters* compressionParams, + int displayLevel, + const BMK_advancedParams_t* adv) +{ + void* srcBuffer = NULL; + size_t benchedSize; + void* dictBuffer = NULL; + size_t dictBufferSize = 0; + size_t* fileSizes = NULL; + BMK_benchOutcome_t res; + U64 const totalSizeToLoad = UTIL_getTotalFileSize(fileNamesTable, nbFiles); + + if (!nbFiles) { + DISPLAYLEVEL(1, "No Files to Benchmark"); + return 13; + } + + if (cLevel > ZSTD_maxCLevel()) { + DISPLAYLEVEL(1, "Invalid Compression Level"); + return 14; + } + + if (totalSizeToLoad == UTIL_FILESIZE_UNKNOWN) { + DISPLAYLEVEL(1, "Error loading files"); + return 15; + } + + fileSizes = (size_t*)calloc(nbFiles, sizeof(size_t)); + if (!fileSizes) { + DISPLAYLEVEL(1, "not enough memory for fileSizes"); + return 16; + } + + /* Load dictionary */ + if (dictFileName != NULL) { + U64 const dictFileSize = UTIL_getFileSize(dictFileName); + if (dictFileSize == UTIL_FILESIZE_UNKNOWN) { + DISPLAYLEVEL( + 1, + "error loading %s : %s \n", + dictFileName, + strerror(errno)); + free(fileSizes); + DISPLAYLEVEL(1, "benchmark aborted"); + return 17; + } + if (dictFileSize > 64 MB) { + free(fileSizes); + DISPLAYLEVEL(1, "dictionary file %s too large", dictFileName); + return 18; + } + dictBufferSize = (size_t)dictFileSize; + dictBuffer = malloc(dictBufferSize); + if (dictBuffer == NULL) { + free(fileSizes); + DISPLAYLEVEL( + 1, + "not enough memory for dictionary (%u bytes)", + (unsigned)dictBufferSize); + return 19; + } + + { + int const errorCode = BMK_loadFiles( + dictBuffer, + dictBufferSize, + fileSizes, + &dictFileName /*?*/, + 1 /*?*/, + displayLevel); + if (errorCode) { + res = BMK_benchOutcome_error(); + goto _cleanUp; + } + } + } + + /* 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", + (unsigned)(benchedSize >> 20)); + + srcBuffer = benchedSize ? malloc(benchedSize) : NULL; + if (!srcBuffer) { + free(dictBuffer); + free(fileSizes); + DISPLAYLEVEL(1, "not enough memory for srcBuffer"); + return 20; + } + + /* Load input buffer */ + { + int const errorCode = BMK_loadFiles( + srcBuffer, + benchedSize, + fileSizes, + fileNamesTable, + nbFiles, + displayLevel); + if (errorCode) { + res = BMK_benchOutcome_error(); + goto _cleanUp; + } + } + + /* Bench */ + { + char mfName[20] = { 0 }; + formatString_u(mfName, sizeof(mfName), " %u files", nbFiles); + { + const char* const displayName = + (nbFiles > 1) ? mfName : fileNamesTable[0]; + res = BMK_benchCLevel( + srcBuffer, + benchedSize, + fileSizes, + nbFiles, + cLevel, + compressionParams, + dictBuffer, + dictBufferSize, + displayLevel, + displayName, + adv); + } + } + +_cleanUp: + free(srcBuffer); + free(dictBuffer); + free(fileSizes); + return !BMK_isSuccessful_benchOutcome(res); +} + +int BMK_benchFiles( + const char* const* fileNamesTable, + unsigned nbFiles, + const char* dictFileName, + int cLevel, + const ZSTD_compressionParameters* compressionParams, + int displayLevel) +{ + BMK_advancedParams_t const adv = BMK_initAdvancedParams(); + return BMK_benchFilesAdvanced( + fileNamesTable, + nbFiles, + dictFileName, + cLevel, + compressionParams, + displayLevel, + &adv); +} diff --git a/src/dependencies/zstd-1.5.4/programs/benchzstd.h b/src/dependencies/zstd-1.5.6/programs/benchzstd.h similarity index 75% rename from src/dependencies/zstd-1.5.4/programs/benchzstd.h rename to src/dependencies/zstd-1.5.6/programs/benchzstd.h index aa683df..ad3088c 100644 --- a/src/dependencies/zstd-1.5.4/programs/benchzstd.h +++ b/src/dependencies/zstd-1.5.6/programs/benchzstd.h @@ -81,21 +81,13 @@ BMK_benchResult_t BMK_extract_benchResult(BMK_benchOutcome_t outcome); * 2 : + result + interaction + warnings; * 3 : + information; * 4 : + debug - * @return: - * a variant, which expresses either an error, or a valid result. - * Use BMK_isSuccessful_benchOutcome() to check if function was successful. - * If yes, extract the valid result with BMK_extract_benchResult(), - * it will contain : - * .cSpeed: compression speed in bytes per second, - * .dSpeed: decompression speed in bytes per second, - * .cSize : compressed size, in bytes - * .cMem : memory budget required for the compression context + * @return: 0 on success, !0 on error */ -BMK_benchOutcome_t BMK_benchFiles( - const char* const * fileNamesTable, unsigned nbFiles, - const char* dictFileName, - int cLevel, const ZSTD_compressionParameters* compressionParams, - int displayLevel); +int BMK_benchFiles( + const char* const * fileNamesTable, unsigned nbFiles, + const char* dictFileName, + int cLevel, const ZSTD_compressionParameters* compressionParams, + int displayLevel); typedef enum { @@ -108,6 +100,7 @@ typedef struct { BMK_mode_t mode; /* 0: all, 1: compress only 2: decode only */ unsigned nbSeconds; /* default timing is in nbSeconds */ size_t blockSize; /* Maximum size of each block*/ + size_t targetCBlockSize;/* Approximative size of compressed blocks */ int nbWorkers; /* multithreading */ unsigned realTime; /* real time priority */ int additionalParam; /* used by python speed benchmark */ @@ -126,33 +119,25 @@ BMK_advancedParams_t BMK_initAdvancedParams(void); /*! BMK_benchFilesAdvanced(): * Same as BMK_benchFiles(), * with more controls, provided through advancedParams_t structure */ -BMK_benchOutcome_t BMK_benchFilesAdvanced( - const char* const * fileNamesTable, unsigned nbFiles, - const char* dictFileName, - int cLevel, const ZSTD_compressionParameters* compressionParams, - int displayLevel, const BMK_advancedParams_t* adv); +int BMK_benchFilesAdvanced( + const char* const * fileNamesTable, unsigned nbFiles, + const char* dictFileName, + int cLevel, const ZSTD_compressionParameters* compressionParams, + int displayLevel, const BMK_advancedParams_t* adv); /*! BMK_syntheticTest() -- called from zstdcli */ /* Generates a sample with datagen, using compressibility argument */ -/* cLevel - compression level to benchmark, errors if invalid - * compressibility - determines compressibility of sample - * compressionParams - basic compression Parameters - * displayLevel - see benchFiles - * adv - see advanced_Params_t - * @return: - * a variant, which expresses either an error, or a valid result. - * Use BMK_isSuccessful_benchOutcome() to check if function was successful. - * If yes, extract the valid result with BMK_extract_benchResult(), - * it will contain : - * .cSpeed: compression speed in bytes per second, - * .dSpeed: decompression speed in bytes per second, - * .cSize : compressed size, in bytes - * .cMem : memory budget required for the compression context +/* @cLevel - compression level to benchmark, errors if invalid + * @compressibility - determines compressibility of sample, range [0.0 - 1.0] + * if @compressibility < 0.0, uses the lorem ipsum generator + * @compressionParams - basic compression Parameters + * @displayLevel - see benchFiles + * @adv - see advanced_Params_t + * @return: 0 on success, !0 on error */ -BMK_benchOutcome_t BMK_syntheticTest( - int cLevel, double compressibility, - const ZSTD_compressionParameters* compressionParams, - int displayLevel, const BMK_advancedParams_t* adv); +int BMK_syntheticTest(int cLevel, double compressibility, + const ZSTD_compressionParameters* compressionParams, + int displayLevel, const BMK_advancedParams_t* adv); @@ -190,8 +175,8 @@ BMK_benchOutcome_t BMK_benchMem(const void* srcBuffer, size_t srcSize, int displayLevel, const char* displayName); -/* BMK_benchMemAdvanced() : same as BMK_benchMem() - * with following additional options : +/* BMK_benchMemAdvanced() : used by Paramgrill + * same as BMK_benchMem() with following additional options : * dstBuffer - destination buffer to write compressed output in, NULL if none provided. * dstCapacity - capacity of destination buffer, give 0 if dstBuffer = NULL * adv = see advancedParams_t diff --git a/src/dependencies/zstd-1.5.4/programs/datagen.c b/src/dependencies/zstd-1.5.6/programs/datagen.c similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/datagen.c rename to src/dependencies/zstd-1.5.6/programs/datagen.c diff --git a/src/dependencies/zstd-1.5.4/programs/datagen.h b/src/dependencies/zstd-1.5.6/programs/datagen.h similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/datagen.h rename to src/dependencies/zstd-1.5.6/programs/datagen.h diff --git a/src/dependencies/zstd-1.5.4/programs/dibio.c b/src/dependencies/zstd-1.5.6/programs/dibio.c similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/dibio.c rename to src/dependencies/zstd-1.5.6/programs/dibio.c diff --git a/src/dependencies/zstd-1.5.4/programs/dibio.h b/src/dependencies/zstd-1.5.6/programs/dibio.h similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/dibio.h rename to src/dependencies/zstd-1.5.6/programs/dibio.h diff --git a/src/dependencies/zstd-1.5.4/programs/fileio.c b/src/dependencies/zstd-1.5.6/programs/fileio.c similarity index 91% rename from src/dependencies/zstd-1.5.4/programs/fileio.c rename to src/dependencies/zstd-1.5.6/programs/fileio.c index 9a8300c..e3012a7 100644 --- a/src/dependencies/zstd-1.5.4/programs/fileio.c +++ b/src/dependencies/zstd-1.5.6/programs/fileio.c @@ -485,6 +485,11 @@ void FIO_setPassThroughFlag(FIO_prefs_t* const prefs, int value) { prefs->passThrough = (value != 0); } +void FIO_setMMapDict(FIO_prefs_t* const prefs, ZSTD_paramSwitch_e value) +{ + prefs->mmapDict = value; +} + /* FIO_ctx_t functions */ void FIO_setHasStdoutOutput(FIO_ctx_t* const fCtx, int value) { @@ -522,7 +527,7 @@ static int FIO_removeFile(const char* path) DISPLAYLEVEL(2, "zstd: Refusing to remove non-regular file %s\n", path); return 0; } -#if defined(_WIN32) || defined(WIN32) +#if defined(_WIN32) /* windows doesn't allow remove read-only files, * so try to make it writable first */ if (!(statbuf.st_mode & _S_IWRITE)) { @@ -576,6 +581,8 @@ FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs, const char* srcFileName, const char* dstFileName, const int mode) { + int isDstRegFile; + if (prefs->testMode) return NULL; /* do not open file in test mode */ assert(dstFileName != NULL); @@ -595,11 +602,16 @@ FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs, return NULL; } + isDstRegFile = UTIL_isRegularFile(dstFileName); /* invoke once */ if (prefs->sparseFileSupport == 1) { prefs->sparseFileSupport = ZSTD_SPARSE_DEFAULT; + if (!isDstRegFile) { + prefs->sparseFileSupport = 0; + DISPLAYLEVEL(4, "Sparse File Support is disabled when output is not a file \n"); + } } - if (UTIL_isRegularFile(dstFileName)) { + if (isDstRegFile) { /* Check if destination file already exists */ #if !defined(_WIN32) /* this test does not work on Windows : @@ -644,39 +656,34 @@ FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs, #endif if (f == NULL) { DISPLAYLEVEL(1, "zstd: %s: %s\n", dstFileName, strerror(errno)); + } else { + /* An increased buffer size can provide a significant performance + * boost on some platforms. Note that providing a NULL buf with a + * size that's not 0 is not defined in ANSI C, but is defined in an + * extension. There are three possibilities here: + * 1. Libc supports the extended version and everything is good. + * 2. Libc ignores the size when buf is NULL, in which case + * everything will continue as if we didn't call `setvbuf()`. + * 3. We fail the call and execution continues but a warning + * message might be shown. + * In all cases due execution continues. For now, I believe that + * this is a more cost-effective solution than managing the buffers + * allocations ourselves (will require an API change). + */ + if (setvbuf(f, NULL, _IOFBF, 1 MB)) { + DISPLAYLEVEL(2, "Warning: setvbuf failed for %s\n", dstFileName); + } } - /* An increased buffer size can provide a significant performance boost on some platforms. - * Note that providing a NULL buf with a size that's not 0 is not defined in ANSI C, but is defined - * in an extension. There are three possibilities here - - * 1. Libc supports the extended version and everything is good. - * 2. Libc ignores the size when buf is NULL, in which case everything will continue as if we didn't - * call `setvbuf`. - * 3. We fail the call and execution continues but a warning message might be shown. - * In all cases due execution continues. For now, I believe that this is a more cost-effective - * solution than managing the buffers allocations ourselves (will require an API change). */ - if(setvbuf(f, NULL, _IOFBF, 1 MB)) - DISPLAYLEVEL(2, "Warning: setvbuf failed for %s\n", dstFileName); return f; } } -/*! FIO_createDictBuffer() : - * creates a buffer, pointed by `*bufferPtr`, - * loads `filename` content into it, up to DICTSIZE_MAX bytes. - * @return : loaded size - * if fileName==NULL, returns 0 and a NULL pointer + +/* FIO_getDictFileStat() : */ -static size_t FIO_createDictBuffer(void** bufferPtr, const char* fileName, FIO_prefs_t* const prefs, stat_t* dictFileStat) -{ - FILE* fileHandle; - U64 fileSize; - - assert(bufferPtr != NULL); +static void FIO_getDictFileStat(const char* fileName, stat_t* dictFileStat) { assert(dictFileStat != NULL); - *bufferPtr = NULL; - if (fileName == NULL) return 0; - - DISPLAYLEVEL(4,"Loading %s as dictionary \n", fileName); + if (fileName == NULL) return; if (!UTIL_stat(fileName, dictFileStat)) { EXM_THROW(31, "Stat failed on dictionary file %s: %s", fileName, strerror(errno)); @@ -685,6 +692,26 @@ static size_t FIO_createDictBuffer(void** bufferPtr, const char* fileName, FIO_p if (!UTIL_isRegularFileStat(dictFileStat)) { EXM_THROW(32, "Dictionary %s must be a regular file.", fileName); } +} + +/* FIO_setDictBufferMalloc() : + * allocates a buffer, pointed by `dict->dictBuffer`, + * loads `filename` content into it, up to DICTSIZE_MAX bytes. + * @return : loaded size + * if fileName==NULL, returns 0 and a NULL pointer + */ +static size_t FIO_setDictBufferMalloc(FIO_Dict_t* dict, const char* fileName, FIO_prefs_t* const prefs, stat_t* dictFileStat) +{ + FILE* fileHandle; + U64 fileSize; + void** bufferPtr = &dict->dictBuffer; + + assert(bufferPtr != NULL); + assert(dictFileStat != NULL); + *bufferPtr = NULL; + if (fileName == NULL) return 0; + + DISPLAYLEVEL(4,"Loading %s as dictionary \n", fileName); fileHandle = fopen(fileName, "rb"); @@ -712,6 +739,130 @@ static size_t FIO_createDictBuffer(void** bufferPtr, const char* fileName, FIO_p return (size_t)fileSize; } +#if (PLATFORM_POSIX_VERSION > 0) +#include +static void FIO_munmap(FIO_Dict_t* dict) +{ + munmap(dict->dictBuffer, dict->dictBufferSize); + dict->dictBuffer = NULL; + dict->dictBufferSize = 0; +} +static size_t FIO_setDictBufferMMap(FIO_Dict_t* dict, const char* fileName, FIO_prefs_t* const prefs, stat_t* dictFileStat) +{ + int fileHandle; + U64 fileSize; + void** bufferPtr = &dict->dictBuffer; + + assert(bufferPtr != NULL); + assert(dictFileStat != NULL); + *bufferPtr = NULL; + if (fileName == NULL) return 0; + + DISPLAYLEVEL(4,"Loading %s as dictionary \n", fileName); + + fileHandle = open(fileName, O_RDONLY); + + if (fileHandle == -1) { + EXM_THROW(33, "Couldn't open dictionary %s: %s", fileName, strerror(errno)); + } + + fileSize = UTIL_getFileSizeStat(dictFileStat); + { + size_t const dictSizeMax = prefs->patchFromMode ? prefs->memLimit : DICTSIZE_MAX; + if (fileSize > dictSizeMax) { + EXM_THROW(34, "Dictionary file %s is too large (> %u bytes)", + fileName, (unsigned)dictSizeMax); /* avoid extreme cases */ + } + } + + *bufferPtr = mmap(NULL, (size_t)fileSize, PROT_READ, MAP_PRIVATE, fileHandle, 0); + if (*bufferPtr==NULL) EXM_THROW(34, "%s", strerror(errno)); + + close(fileHandle); + return (size_t)fileSize; +} +#elif defined(_MSC_VER) || defined(_WIN32) +#include +static void FIO_munmap(FIO_Dict_t* dict) +{ + UnmapViewOfFile(dict->dictBuffer); + CloseHandle(dict->dictHandle); + dict->dictBuffer = NULL; + dict->dictBufferSize = 0; +} +static size_t FIO_setDictBufferMMap(FIO_Dict_t* dict, const char* fileName, FIO_prefs_t* const prefs, stat_t* dictFileStat) +{ + HANDLE fileHandle, mapping; + U64 fileSize; + void** bufferPtr = &dict->dictBuffer; + + assert(bufferPtr != NULL); + assert(dictFileStat != NULL); + *bufferPtr = NULL; + if (fileName == NULL) return 0; + + DISPLAYLEVEL(4,"Loading %s as dictionary \n", fileName); + + fileHandle = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); + + if (fileHandle == INVALID_HANDLE_VALUE) { + EXM_THROW(33, "Couldn't open dictionary %s: %s", fileName, strerror(errno)); + } + + fileSize = UTIL_getFileSizeStat(dictFileStat); + { + size_t const dictSizeMax = prefs->patchFromMode ? prefs->memLimit : DICTSIZE_MAX; + if (fileSize > dictSizeMax) { + EXM_THROW(34, "Dictionary file %s is too large (> %u bytes)", + fileName, (unsigned)dictSizeMax); /* avoid extreme cases */ + } + } + + mapping = CreateFileMapping(fileHandle, NULL, PAGE_READONLY, 0, 0, NULL); + if (mapping == NULL) { + EXM_THROW(35, "Couldn't map dictionary %s: %s", fileName, strerror(errno)); + } + + *bufferPtr = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, (DWORD)fileSize); /* we can only cast to DWORD here because dictSize <= 2GB */ + if (*bufferPtr==NULL) EXM_THROW(36, "%s", strerror(errno)); + + dict->dictHandle = fileHandle; + return (size_t)fileSize; +} +#else +static size_t FIO_setDictBufferMMap(FIO_Dict_t* dict, const char* fileName, FIO_prefs_t* const prefs, stat_t* dictFileStat) +{ + return FIO_setDictBufferMalloc(dict, fileName, prefs, dictFileStat); +} +static void FIO_munmap(FIO_Dict_t* dict) { + free(dict->dictBuffer); + dict->dictBuffer = NULL; + dict->dictBufferSize = 0; +} +#endif + +static void FIO_freeDict(FIO_Dict_t* dict) { + if (dict->dictBufferType == FIO_mallocDict) { + free(dict->dictBuffer); + dict->dictBuffer = NULL; + dict->dictBufferSize = 0; + } else if (dict->dictBufferType == FIO_mmapDict) { + FIO_munmap(dict); + } else { + assert(0); /* Should not reach this case */ + } +} + +static void FIO_initDict(FIO_Dict_t* dict, const char* fileName, FIO_prefs_t* const prefs, stat_t* dictFileStat, FIO_dictBufferType_t dictBufferType) { + dict->dictBufferType = dictBufferType; + if (dict->dictBufferType == FIO_mallocDict) { + dict->dictBufferSize = FIO_setDictBufferMalloc(dict, fileName, prefs, dictFileStat); + } else if (dict->dictBufferType == FIO_mmapDict) { + dict->dictBufferSize = FIO_setDictBufferMMap(dict, fileName, prefs, dictFileStat); + } else { + assert(0); /* Should not reach this case */ + } +} /* FIO_checkFilenameCollisions() : @@ -914,8 +1065,7 @@ static ZSTD_outBuffer setOutBuffer(void* buf, size_t s, size_t pos) * Compression ************************************************************************/ typedef struct { - void* dictBuffer; - size_t dictBufferSize; + FIO_Dict_t dict; const char* dictFileName; stat_t dictFileStat; ZSTD_CStream* cctx; @@ -946,21 +1096,24 @@ static void FIO_adjustParamsForPatchFromMode(FIO_prefs_t* const prefs, comprParams->windowLog = MAX(ZSTD_WINDOWLOG_MIN, MIN(ZSTD_WINDOWLOG_MAX, fileWindowLog)); if (fileWindowLog > ZSTD_cycleLog(cParams.chainLog, cParams.strategy)) { if (!prefs->ldmFlag) - DISPLAYLEVEL(1, "long mode automatically triggered\n"); + DISPLAYLEVEL(2, "long mode automatically triggered\n"); FIO_setLdmFlag(prefs, 1); } if (cParams.strategy >= ZSTD_btopt) { - DISPLAYLEVEL(1, "[Optimal parser notes] Consider the following to improve patch size at the cost of speed:\n"); - DISPLAYLEVEL(1, "- Use --single-thread mode in the zstd cli\n"); - DISPLAYLEVEL(1, "- Set a larger targetLength (e.g. --zstd=targetLength=4096)\n"); - DISPLAYLEVEL(1, "- Set a larger chainLog (e.g. --zstd=chainLog=%u)\n", ZSTD_CHAINLOG_MAX); - DISPLAYLEVEL(1, "Also consider playing around with searchLog and hashLog\n"); + DISPLAYLEVEL(3, "[Optimal parser notes] Consider the following to improve patch size at the cost of speed:\n"); + DISPLAYLEVEL(3, "- Use --single-thread mode in the zstd cli\n"); + DISPLAYLEVEL(3, "- Set a larger targetLength (e.g. --zstd=targetLength=4096)\n"); + DISPLAYLEVEL(3, "- Set a larger chainLog (e.g. --zstd=chainLog=%u)\n", ZSTD_CHAINLOG_MAX); + DISPLAYLEVEL(3, "Also consider playing around with searchLog and hashLog\n"); } } static cRess_t FIO_createCResources(FIO_prefs_t* const prefs, const char* dictFileName, unsigned long long const maxSrcFileSize, int cLevel, ZSTD_compressionParameters comprParams) { + int useMMap = prefs->mmapDict == ZSTD_ps_enable; + int forceNoUseMMap = prefs->mmapDict == ZSTD_ps_disable; + FIO_dictBufferType_t dictBufferType; cRess_t ress; memset(&ress, 0, sizeof(ress)); @@ -970,19 +1123,25 @@ static cRess_t FIO_createCResources(FIO_prefs_t* const prefs, EXM_THROW(30, "allocation error (%s): can't create ZSTD_CCtx", strerror(errno)); + FIO_getDictFileStat(dictFileName, &ress.dictFileStat); + /* need to update memLimit before calling createDictBuffer * because of memLimit check inside it */ if (prefs->patchFromMode) { + U64 const dictSize = UTIL_getFileSizeStat(&ress.dictFileStat); unsigned long long const ssSize = (unsigned long long)prefs->streamSrcSize; - FIO_adjustParamsForPatchFromMode(prefs, &comprParams, UTIL_getFileSize(dictFileName), ssSize > 0 ? ssSize : maxSrcFileSize, cLevel); + useMMap |= dictSize > prefs->memLimit; + FIO_adjustParamsForPatchFromMode(prefs, &comprParams, dictSize, ssSize > 0 ? ssSize : maxSrcFileSize, cLevel); } - ress.dictBufferSize = FIO_createDictBuffer(&ress.dictBuffer, dictFileName, prefs, &ress.dictFileStat); /* works with dictFileName==NULL */ + + dictBufferType = (useMMap && !forceNoUseMMap) ? FIO_mmapDict : FIO_mallocDict; + FIO_initDict(&ress.dict, dictFileName, prefs, &ress.dictFileStat, dictBufferType); /* works with dictFileName==NULL */ ress.writeCtx = AIO_WritePool_create(prefs, ZSTD_CStreamOutSize()); ress.readCtx = AIO_ReadPool_create(prefs, ZSTD_CStreamInSize()); /* Advanced parameters, including dictionary */ - if (dictFileName && (ress.dictBuffer==NULL)) + if (dictFileName && (ress.dict.dictBuffer==NULL)) EXM_THROW(32, "allocation error : can't create dictBuffer"); ress.dictFileName = dictFileName; @@ -1032,17 +1191,17 @@ static cRess_t FIO_createCResources(FIO_prefs_t* const prefs, #endif /* dictionary */ if (prefs->patchFromMode) { - CHECK( ZSTD_CCtx_refPrefix(ress.cctx, ress.dictBuffer, ress.dictBufferSize) ); + CHECK( ZSTD_CCtx_refPrefix(ress.cctx, ress.dict.dictBuffer, ress.dict.dictBufferSize) ); } else { - CHECK( ZSTD_CCtx_loadDictionary(ress.cctx, ress.dictBuffer, ress.dictBufferSize) ); + CHECK( ZSTD_CCtx_loadDictionary_byReference(ress.cctx, ress.dict.dictBuffer, ress.dict.dictBufferSize) ); } return ress; } -static void FIO_freeCResources(const cRess_t* const ress) +static void FIO_freeCResources(cRess_t* const ress) { - free(ress->dictBuffer); + FIO_freeDict(&(ress->dict)); AIO_WritePool_free(ress->writeCtx); AIO_ReadPool_free(ress->readCtx); ZSTD_freeCStream(ress->cctx); /* never fails */ @@ -1173,8 +1332,8 @@ FIO_compressLzmaFrame(cRess_t* ress, } writeJob =AIO_WritePool_acquireJob(ress->writeCtx); - strm.next_out = (Bytef*)writeJob->buffer; - strm.avail_out = (uInt)writeJob->bufferSize; + strm.next_out = (BYTE*)writeJob->buffer; + strm.avail_out = writeJob->bufferSize; strm.next_in = 0; strm.avail_in = 0; @@ -1201,7 +1360,7 @@ FIO_compressLzmaFrame(cRess_t* ress, writeJob->usedBufferSize = compBytes; AIO_WritePool_enqueueAndReacquireWriteJob(&writeJob); outFileSize += compBytes; - strm.next_out = (Bytef*)writeJob->buffer; + strm.next_out = (BYTE*)writeJob->buffer; strm.avail_out = writeJob->bufferSize; } } if (srcFileSize == UTIL_FILESIZE_UNKNOWN) @@ -1680,7 +1839,7 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx, int closeDstFile = 0; int result; int transferStat = 0; - FILE *dstFile; + int dstFd = -1; assert(AIO_ReadPool_getFile(ress.readCtx) != NULL); if (AIO_WritePool_getFile(ress.writeCtx) == NULL) { @@ -1694,9 +1853,11 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx, closeDstFile = 1; DISPLAYLEVEL(6, "FIO_compressFilename_dstFile: opening dst: %s \n", dstFileName); - dstFile = FIO_openDstFile(fCtx, prefs, srcFileName, dstFileName, dstFileInitialPermissions); - if (dstFile==NULL) return 1; /* could not open dstFileName */ - AIO_WritePool_setFile(ress.writeCtx, dstFile); + { FILE *dstFile = FIO_openDstFile(fCtx, prefs, srcFileName, dstFileName, dstFileInitialPermissions); + if (dstFile==NULL) return 1; /* could not open dstFileName */ + dstFd = fileno(dstFile); + AIO_WritePool_setFile(ress.writeCtx, dstFile); + } /* Must only be added after FIO_openDstFile() succeeds. * Otherwise we may delete the destination file if it already exists, * and the user presses Ctrl-C when asked if they wish to overwrite. @@ -1709,14 +1870,20 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx, if (closeDstFile) { clearHandler(); + if (transferStat) { + UTIL_setFDStat(dstFd, dstFileName, srcFileStat); + } + DISPLAYLEVEL(6, "FIO_compressFilename_dstFile: closing dst: %s \n", dstFileName); if (AIO_WritePool_closeFile(ress.writeCtx)) { /* error closing file */ DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno)); result=1; } + if (transferStat) { - UTIL_setFileStat(dstFileName, srcFileStat); + UTIL_utime(dstFileName, srcFileStat); } + if ( (result != 0) /* operation failure */ && strcmp(dstFileName, stdoutmark) /* special case : don't remove() stdout */ ) { @@ -1740,6 +1907,110 @@ static const char *compressedFileExtensions[] = { TXZ_EXTENSION, LZ4_EXTENSION, TLZ4_EXTENSION, + ".7z", + ".aa3", + ".aac", + ".aar", + ".ace", + ".alac", + ".ape", + ".apk", + ".apng", + ".arc", + ".archive", + ".arj", + ".ark", + ".asf", + ".avi", + ".avif", + ".ba", + ".br", + ".bz2", + ".cab", + ".cdx", + ".chm", + ".cr2", + ".divx", + ".dmg", + ".dng", + ".docm", + ".docx", + ".dotm", + ".dotx", + ".dsft", + ".ear", + ".eftx", + ".emz", + ".eot", + ".epub", + ".f4v", + ".flac", + ".flv", + ".gho", + ".gif", + ".gifv", + ".gnp", + ".iso", + ".jar", + ".jpeg", + ".jpg", + ".jxl", + ".lz", + ".lzh", + ".m4a", + ".m4v", + ".mkv", + ".mov", + ".mp2", + ".mp3", + ".mp4", + ".mpa", + ".mpc", + ".mpe", + ".mpeg", + ".mpg", + ".mpl", + ".mpv", + ".msi", + ".odp", + ".ods", + ".odt", + ".ogg", + ".ogv", + ".otp", + ".ots", + ".ott", + ".pea", + ".png", + ".pptx", + ".qt", + ".rar", + ".s7z", + ".sfx", + ".sit", + ".sitx", + ".sqx", + ".svgz", + ".swf", + ".tbz2", + ".tib", + ".tlz", + ".vob", + ".war", + ".webm", + ".webp", + ".wma", + ".wmv", + ".woff", + ".woff2", + ".wvl", + ".xlsx", + ".xpi", + ".xps", + ".zip", + ".zipx", + ".zoo", + ".zpaq", NULL }; @@ -1873,7 +2144,7 @@ int FIO_compressFilename(FIO_ctx_t* const fCtx, FIO_prefs_t* const prefs, const const char* srcFileName, const char* dictFileName, int compressionLevel, ZSTD_compressionParameters comprParams) { - cRess_t const ress = FIO_createCResources(prefs, dictFileName, UTIL_getFileSize(srcFileName), compressionLevel, comprParams); + cRess_t ress = FIO_createCResources(prefs, dictFileName, UTIL_getFileSize(srcFileName), compressionLevel, comprParams); int const result = FIO_compressFilename_srcFile(fCtx, prefs, ress, dstFileName, srcFileName, compressionLevel); #define DISPLAY_LEVEL_DEFAULT 2 @@ -2043,6 +2314,7 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx, * Decompression ***************************************************************************/ typedef struct { + FIO_Dict_t dict; ZSTD_DStream* dctx; WritePoolCtx_t *writeCtx; ReadPoolCtx_t *readCtx; @@ -2050,11 +2322,20 @@ typedef struct { static dRess_t FIO_createDResources(FIO_prefs_t* const prefs, const char* dictFileName) { + int useMMap = prefs->mmapDict == ZSTD_ps_enable; + int forceNoUseMMap = prefs->mmapDict == ZSTD_ps_disable; + stat_t statbuf; dRess_t ress; + memset(&statbuf, 0, sizeof(statbuf)); memset(&ress, 0, sizeof(ress)); - if (prefs->patchFromMode) - FIO_adjustMemLimitForPatchFromMode(prefs, UTIL_getFileSize(dictFileName), 0 /* just use the dict size */); + FIO_getDictFileStat(dictFileName, &statbuf); + + if (prefs->patchFromMode){ + U64 const dictSize = UTIL_getFileSizeStat(&statbuf); + useMMap |= dictSize > prefs->memLimit; + FIO_adjustMemLimitForPatchFromMode(prefs, dictSize, 0 /* just use the dict size */); + } /* Allocation */ ress.dctx = ZSTD_createDStream(); @@ -2064,29 +2345,34 @@ static dRess_t FIO_createDResources(FIO_prefs_t* const prefs, const char* dictFi CHECK( ZSTD_DCtx_setParameter(ress.dctx, ZSTD_d_forceIgnoreChecksum, !prefs->checksumFlag)); /* dictionary */ - { void* dictBuffer; - stat_t statbuf; - size_t const dictBufferSize = FIO_createDictBuffer(&dictBuffer, dictFileName, prefs, &statbuf); - CHECK( ZSTD_DCtx_reset(ress.dctx, ZSTD_reset_session_only) ); - CHECK( ZSTD_DCtx_loadDictionary(ress.dctx, dictBuffer, dictBufferSize) ); - free(dictBuffer); + { + FIO_dictBufferType_t dictBufferType = (useMMap && !forceNoUseMMap) ? FIO_mmapDict : FIO_mallocDict; + FIO_initDict(&ress.dict, dictFileName, prefs, &statbuf, dictBufferType); + + CHECK(ZSTD_DCtx_reset(ress.dctx, ZSTD_reset_session_only) ); + + if (prefs->patchFromMode){ + CHECK(ZSTD_DCtx_refPrefix(ress.dctx, ress.dict.dictBuffer, ress.dict.dictBufferSize)); + } else { + CHECK(ZSTD_DCtx_loadDictionary_byReference(ress.dctx, ress.dict.dictBuffer, ress.dict.dictBufferSize)); + } } ress.writeCtx = AIO_WritePool_create(prefs, ZSTD_DStreamOutSize()); ress.readCtx = AIO_ReadPool_create(prefs, ZSTD_DStreamInSize()); - return ress; } static void FIO_freeDResources(dRess_t ress) { + FIO_freeDict(&(ress.dict)); CHECK( ZSTD_freeDStream(ress.dctx) ); AIO_WritePool_free(ress.writeCtx); AIO_ReadPool_free(ress.readCtx); } -/** FIO_passThrough() : just copy input into output, for compatibility with gzip -df mode - @return : 0 (no error) */ +/* FIO_passThrough() : just copy input into output, for compatibility with gzip -df mode + * @return : 0 (no error) */ static int FIO_passThrough(dRess_t *ress) { size_t const blockSize = MIN(MIN(64 KB, ZSTD_DStreamInSize()), ZSTD_DStreamOutSize()); @@ -2114,7 +2400,8 @@ static int FIO_passThrough(dRess_t *ress) static void FIO_zstdErrorHelp(const FIO_prefs_t* const prefs, const dRess_t* ress, - size_t err, const char* srcFileName) + size_t err, + const char* srcFileName) { ZSTD_frameHeader header; @@ -2154,9 +2441,10 @@ FIO_decompressZstdFrame(FIO_ctx_t* const fCtx, dRess_t* ress, U64 frameSize = 0; IOJob_t *writeJob = AIO_WritePool_acquireJob(ress->writeCtx); - /* display last 20 characters only */ + /* display last 20 characters only when not --verbose */ { size_t const srcFileLength = strlen(srcFileName); - if (srcFileLength>20) srcFileName += srcFileLength-20; + if ((srcFileLength>20) && (g_display_prefs.displayLevel<3)) + srcFileName += srcFileLength-20; } ZSTD_DCtx_reset(ress->dctx, ZSTD_reset_session_only); @@ -2316,8 +2604,8 @@ FIO_decompressLzmaFrame(dRess_t* ress, } writeJob = AIO_WritePool_acquireJob(ress->writeCtx); - strm.next_out = (Bytef*)writeJob->buffer; - strm.avail_out = (uInt)writeJob->bufferSize; + strm.next_out = (BYTE*)writeJob->buffer; + strm.avail_out = writeJob->bufferSize; strm.next_in = (BYTE const*)ress->readCtx->srcBuffer; strm.avail_in = ress->readCtx->srcBufferLoaded; @@ -2345,7 +2633,7 @@ FIO_decompressLzmaFrame(dRess_t* ress, writeJob->usedBufferSize = decompBytes; AIO_WritePool_enqueueAndReacquireWriteJob(&writeJob); outFileSize += decompBytes; - strm.next_out = (Bytef*)writeJob->buffer; + strm.next_out = (BYTE*)writeJob->buffer; strm.avail_out = writeJob->bufferSize; } } if (ret == LZMA_STREAM_END) break; @@ -2540,6 +2828,7 @@ static int FIO_decompressDstFile(FIO_ctx_t* const fCtx, int result; int releaseDstFile = 0; int transferStat = 0; + int dstFd = 0; if ((AIO_WritePool_getFile(ress.writeCtx) == NULL) && (prefs->testMode == 0)) { FILE *dstFile; @@ -2555,6 +2844,7 @@ static int FIO_decompressDstFile(FIO_ctx_t* const fCtx, dstFile = FIO_openDstFile(fCtx, prefs, srcFileName, dstFileName, dstFilePermissions); if (dstFile==NULL) return 1; + dstFd = fileno(dstFile); AIO_WritePool_setFile(ress.writeCtx, dstFile); /* Must only be added after FIO_openDstFile() succeeds. @@ -2568,13 +2858,18 @@ static int FIO_decompressDstFile(FIO_ctx_t* const fCtx, if (releaseDstFile) { clearHandler(); + + if (transferStat) { + UTIL_setFDStat(dstFd, dstFileName, srcFileStat); + } + if (AIO_WritePool_closeFile(ress.writeCtx)) { DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno)); result = 1; } if (transferStat) { - UTIL_setFileStat(dstFileName, srcFileStat); + UTIL_utime(dstFileName, srcFileStat); } if ( (result != 0) /* operation failure */ @@ -2655,6 +2950,8 @@ int FIO_decompressFilename(FIO_ctx_t* const fCtx, FIO_prefs_t* const prefs, int const decodingError = FIO_decompressSrcFile(fCtx, prefs, ress, dstFileName, srcFileName); + + FIO_freeDResources(ress); return decodingError; } diff --git a/src/dependencies/zstd-1.5.4/programs/fileio.h b/src/dependencies/zstd-1.5.6/programs/fileio.h similarity index 98% rename from src/dependencies/zstd-1.5.4/programs/fileio.h rename to src/dependencies/zstd-1.5.6/programs/fileio.h index 291d4d4..224d895 100644 --- a/src/dependencies/zstd-1.5.4/programs/fileio.h +++ b/src/dependencies/zstd-1.5.6/programs/fileio.h @@ -106,6 +106,7 @@ void FIO_setContentSize(FIO_prefs_t* const prefs, int value); void FIO_displayCompressionParameters(const FIO_prefs_t* prefs); void FIO_setAsyncIOFlag(FIO_prefs_t* const prefs, int value); void FIO_setPassThroughFlag(FIO_prefs_t* const prefs, int value); +void FIO_setMMapDict(FIO_prefs_t* const prefs, ZSTD_paramSwitch_e value); /* FIO_ctx_t functions */ void FIO_setNbFilesTotal(FIO_ctx_t* const fCtx, int value); diff --git a/src/dependencies/zstd-1.5.4/programs/fileio_asyncio.c b/src/dependencies/zstd-1.5.6/programs/fileio_asyncio.c similarity index 98% rename from src/dependencies/zstd-1.5.4/programs/fileio_asyncio.c rename to src/dependencies/zstd-1.5.6/programs/fileio_asyncio.c index fe9cca9..ae6db69 100644 --- a/src/dependencies/zstd-1.5.4/programs/fileio_asyncio.c +++ b/src/dependencies/zstd-1.5.6/programs/fileio_asyncio.c @@ -453,8 +453,8 @@ static IOJob_t* AIO_ReadPool_findNextWaitingOffsetCompletedJob_locked(ReadPoolCt /* AIO_ReadPool_numReadsInFlight: * Returns the number of IO read jobs currently in flight. */ static size_t AIO_ReadPool_numReadsInFlight(ReadPoolCtx_t* ctx) { - const size_t jobsHeld = (ctx->currentJobHeld==NULL ? 0 : 1); - return ctx->base.totalIoJobs - (ctx->base.availableJobsCount + ctx->completedJobsCount + jobsHeld); + const int jobsHeld = (ctx->currentJobHeld==NULL ? 0 : 1); + return (size_t)(ctx->base.totalIoJobs - (ctx->base.availableJobsCount + ctx->completedJobsCount + jobsHeld)); } /* AIO_ReadPool_getNextCompletedJob: @@ -514,8 +514,7 @@ static void AIO_ReadPool_enqueueRead(ReadPoolCtx_t* ctx) { } static void AIO_ReadPool_startReading(ReadPoolCtx_t* ctx) { - int i; - for (i = 0; i < ctx->base.availableJobsCount; i++) { + while(ctx->base.availableJobsCount) { AIO_ReadPool_enqueueRead(ctx); } } @@ -551,6 +550,7 @@ ReadPoolCtx_t* AIO_ReadPool_create(const FIO_prefs_t* prefs, size_t bufferSize) AIO_IOPool_init(&ctx->base, prefs, AIO_ReadPool_executeReadJob, bufferSize); ctx->coalesceBuffer = (U8*) malloc(bufferSize * 2); + if(!ctx->coalesceBuffer) EXM_THROW(100, "Allocation error : not enough memory"); ctx->srcBuffer = ctx->coalesceBuffer; ctx->srcBufferLoaded = 0; ctx->completedJobsCount = 0; diff --git a/src/dependencies/zstd-1.5.4/programs/fileio_asyncio.h b/src/dependencies/zstd-1.5.6/programs/fileio_asyncio.h similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/fileio_asyncio.h rename to src/dependencies/zstd-1.5.6/programs/fileio_asyncio.h diff --git a/src/dependencies/zstd-1.5.4/programs/fileio_common.h b/src/dependencies/zstd-1.5.6/programs/fileio_common.h similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/fileio_common.h rename to src/dependencies/zstd-1.5.6/programs/fileio_common.h diff --git a/src/dependencies/zstd-1.5.4/programs/fileio_types.h b/src/dependencies/zstd-1.5.6/programs/fileio_types.h similarity index 88% rename from src/dependencies/zstd-1.5.4/programs/fileio_types.h rename to src/dependencies/zstd-1.5.6/programs/fileio_types.h index c1f42f1..2994a60 100644 --- a/src/dependencies/zstd-1.5.4/programs/fileio_types.h +++ b/src/dependencies/zstd-1.5.6/programs/fileio_types.h @@ -69,6 +69,18 @@ typedef struct FIO_prefs_s { int contentSize; int allowBlockDevices; int passThrough; + ZSTD_paramSwitch_e mmapDict; } FIO_prefs_t; +typedef enum {FIO_mallocDict, FIO_mmapDict} FIO_dictBufferType_t; + +typedef struct { + void* dictBuffer; + size_t dictBufferSize; + FIO_dictBufferType_t dictBufferType; +#if defined(_MSC_VER) || defined(_WIN32) + HANDLE dictHandle; +#endif +} FIO_Dict_t; + #endif /* FILEIO_TYPES_HEADER */ diff --git a/src/dependencies/zstd-1.5.6/programs/lorem.c b/src/dependencies/zstd-1.5.6/programs/lorem.c new file mode 100644 index 0000000..79030c9 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/programs/lorem.c @@ -0,0 +1,285 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* Implementation notes: + * + * This is a very simple lorem ipsum generator + * which features a static list of words + * and print them one after another randomly + * with a fake sentence / paragraph structure. + * + * The goal is to generate a printable text + * that can be used to fake a text compression scenario. + * The resulting compression / ratio curve of the lorem ipsum generator + * is more satisfying than the previous statistical generator, + * which was initially designed for entropy compression, + * and lacks a regularity more representative of text. + * + * The compression ratio achievable on the generated lorem ipsum + * is still a bit too good, presumably because the dictionary is a bit too + * small. It would be possible to create some more complex scheme, notably by + * enlarging the dictionary with a word generator, and adding grammatical rules + * (composition) and syntax rules. But that's probably overkill for the intended + * goal. + */ + +#include "lorem.h" +#include +#include /* INT_MAX */ +#include /* memcpy */ + +#define WORD_MAX_SIZE 20 + +/* Define the word pool */ +static const char* kWords[] = { + "lorem", "ipsum", "dolor", "sit", "amet", + "consectetur", "adipiscing", "elit", "sed", "do", + "eiusmod", "tempor", "incididunt", "ut", "labore", + "et", "dolore", "magna", "aliqua", "dis", + "lectus", "vestibulum", "mattis", "ullamcorper", "velit", + "commodo", "a", "lacus", "arcu", "magnis", + "parturient", "montes", "nascetur", "ridiculus", "mus", + "mauris", "nulla", "malesuada", "pellentesque", "eget", + "gravida", "in", "dictum", "non", "erat", + "nam", "voluptat", "maecenas", "blandit", "aliquam", + "etiam", "enim", "lobortis", "scelerisque", "fermentum", + "dui", "faucibus", "ornare", "at", "elementum", + "eu", "facilisis", "odio", "morbi", "quis", + "eros", "donec", "ac", "orci", "purus", + "turpis", "cursus", "leo", "vel", "porta", + "consequat", "interdum", "varius", "vulputate", "aliquet", + "pharetra", "nunc", "auctor", "urna", "id", + "metus", "viverra", "nibh", "cras", "mi", + "unde", "omnis", "iste", "natus", "error", + "perspiciatis", "voluptatem", "accusantium", "doloremque", "laudantium", + "totam", "rem", "aperiam", "eaque", "ipsa", + "quae", "ab", "illo", "inventore", "veritatis", + "quasi", "architecto", "beatae", "vitae", "dicta", + "sunt", "explicabo", "nemo", "ipsam", "quia", + "voluptas", "aspernatur", "aut", "odit", "fugit", + "consequuntur", "magni", "dolores", "eos", "qui", + "ratione", "sequi", "nesciunt", "neque", "porro", + "quisquam", "est", "dolorem", "adipisci", "numquam", + "eius", "modi", "tempora", "incidunt", "magnam", + "quaerat", "ad", "minima", "veniam", "nostrum", + "ullam", "corporis", "suscipit", "laboriosam", "nisi", + "aliquid", "ex", "ea", "commodi", "consequatur", + "autem", "eum", "iure", "voluptate", "esse", + "quam", "nihil", "molestiae", "illum", "fugiat", + "quo", "pariatur", "vero", "accusamus", "iusto", + "dignissimos", "ducimus", "blanditiis", "praesentium", "voluptatum", + "deleniti", "atque", "corrupti", "quos", "quas", + "molestias", "excepturi", "sint", "occaecati", "cupiditate", + "provident", "similique", "culpa", "officia", "deserunt", + "mollitia", "animi", "laborum", "dolorum", "fuga", + "harum", "quidem", "rerum", "facilis", "expedita", + "distinctio", "libero", "tempore", "cum", "soluta", + "nobis", "eligendi", "optio", "cumque", "impedit", + "minus", "quod", "maxime", "placeat", "facere", + "possimus", "assumenda", "repellendus", "temporibus", "quibusdam", + "officiis", "debitis", "saepe", "eveniet", "voluptates", + "repudiandae", "recusandae", "itaque", "earum", "hic", + "tenetur", "sapiente", "delectus", "reiciendis", "cillum", + "maiores", "alias", "perferendis", "doloribus", "asperiores", + "repellat", "minim", "nostrud", "exercitation", "ullamco", + "laboris", "aliquip", "duis", "aute", "irure", +}; +static const unsigned kNbWords = sizeof(kWords) / sizeof(kWords[0]); + +/* simple 1-dimension distribution, based on word's length, favors small words + */ +static const int kWeights[] = { 0, 8, 6, 4, 3, 2 }; +static const size_t kNbWeights = sizeof(kWeights) / sizeof(kWeights[0]); + +#define DISTRIB_SIZE_MAX 650 +static int g_distrib[DISTRIB_SIZE_MAX] = { 0 }; +static unsigned g_distribCount = 0; + +static void countFreqs( + const char* words[], + size_t nbWords, + const int* weights, + size_t nbWeights) +{ + unsigned total = 0; + size_t w; + for (w = 0; w < nbWords; w++) { + size_t len = strlen(words[w]); + int lmax; + if (len >= nbWeights) + len = nbWeights - 1; + lmax = weights[len]; + total += (unsigned)lmax; + } + g_distribCount = total; + assert(g_distribCount <= DISTRIB_SIZE_MAX); +} + +static void init_word_distrib( + const char* words[], + size_t nbWords, + const int* weights, + size_t nbWeights) +{ + size_t w, d = 0; + countFreqs(words, nbWords, weights, nbWeights); + for (w = 0; w < nbWords; w++) { + size_t len = strlen(words[w]); + int l, lmax; + if (len >= nbWeights) + len = nbWeights - 1; + lmax = weights[len]; + for (l = 0; l < lmax; l++) { + g_distrib[d++] = (int)w; + } + } +} + +/* Note: this unit only works when invoked sequentially. + * No concurrent access is allowed */ +static char* g_ptr = NULL; +static size_t g_nbChars = 0; +static size_t g_maxChars = 10000000; +static unsigned g_randRoot = 0; + +#define RDG_rotl32(x, r) ((x << r) | (x >> (32 - r))) +static unsigned LOREM_rand(unsigned range) +{ + static const unsigned prime1 = 2654435761U; + static const unsigned prime2 = 2246822519U; + unsigned rand32 = g_randRoot; + rand32 *= prime1; + rand32 ^= prime2; + rand32 = RDG_rotl32(rand32, 13); + g_randRoot = rand32; + return (unsigned)(((unsigned long long)rand32 * range) >> 32); +} + +static void writeLastCharacters(void) +{ + size_t lastChars = g_maxChars - g_nbChars; + assert(g_maxChars >= g_nbChars); + if (lastChars == 0) + return; + g_ptr[g_nbChars++] = '.'; + if (lastChars > 2) { + memset(g_ptr + g_nbChars, ' ', lastChars - 2); + } + if (lastChars > 1) { + g_ptr[g_maxChars - 1] = '\n'; + } + g_nbChars = g_maxChars; +} + +static void generateWord(const char* word, const char* separator, int upCase) +{ + size_t const len = strlen(word) + strlen(separator); + if (g_nbChars + len > g_maxChars) { + writeLastCharacters(); + return; + } + memcpy(g_ptr + g_nbChars, word, strlen(word)); + if (upCase) { + static const char toUp = 'A' - 'a'; + g_ptr[g_nbChars] = (char)(g_ptr[g_nbChars] + toUp); + } + g_nbChars += strlen(word); + memcpy(g_ptr + g_nbChars, separator, strlen(separator)); + g_nbChars += strlen(separator); +} + +static int about(unsigned target) +{ + return (int)(LOREM_rand(target) + LOREM_rand(target) + 1); +} + +/* Function to generate a random sentence */ +static void generateSentence(int nbWords) +{ + int commaPos = about(9); + int comma2 = commaPos + about(7); + int qmark = (LOREM_rand(11) == 7); + const char* endSep = qmark ? "? " : ". "; + int i; + for (i = 0; i < nbWords; i++) { + int const wordID = g_distrib[LOREM_rand(g_distribCount)]; + const char* const word = kWords[wordID]; + const char* sep = " "; + if (i == commaPos) + sep = ", "; + if (i == comma2) + sep = ", "; + if (i == nbWords - 1) + sep = endSep; + generateWord(word, sep, i == 0); + } +} + +static void generateParagraph(int nbSentences) +{ + int i; + for (i = 0; i < nbSentences; i++) { + int wordsPerSentence = about(11); + generateSentence(wordsPerSentence); + } + if (g_nbChars < g_maxChars) { + g_ptr[g_nbChars++] = '\n'; + } + if (g_nbChars < g_maxChars) { + g_ptr[g_nbChars++] = '\n'; + } +} + +/* It's "common" for lorem ipsum generators to start with the same first + * pre-defined sentence */ +static void generateFirstSentence(void) +{ + int i; + for (i = 0; i < 18; i++) { + const char* word = kWords[i]; + const char* separator = " "; + if (i == 4) + separator = ", "; + if (i == 7) + separator = ", "; + generateWord(word, separator, i == 0); + } + generateWord(kWords[18], ". ", 0); +} + +size_t +LOREM_genBlock(void* buffer, size_t size, unsigned seed, int first, int fill) +{ + g_ptr = (char*)buffer; + assert(size < INT_MAX); + g_maxChars = size; + g_nbChars = 0; + g_randRoot = seed; + if (g_distribCount == 0) { + init_word_distrib(kWords, kNbWords, kWeights, kNbWeights); + } + + if (first) { + generateFirstSentence(); + } + while (g_nbChars < g_maxChars) { + int sentencePerParagraph = about(7); + generateParagraph(sentencePerParagraph); + if (!fill) + break; /* only generate one paragraph in not-fill mode */ + } + g_ptr = NULL; + return g_nbChars; +} + +void LOREM_genBuffer(void* buffer, size_t size, unsigned seed) +{ + LOREM_genBlock(buffer, size, seed, 1, 1); +} diff --git a/src/dependencies/zstd-1.5.6/programs/lorem.h b/src/dependencies/zstd-1.5.6/programs/lorem.h new file mode 100644 index 0000000..4a87f87 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/programs/lorem.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* lorem ipsum generator */ + +#include /* size_t */ + +/* + * LOREM_genBuffer(): + * Generate @size bytes of compressible data using lorem ipsum generator + * into provided @buffer. + */ +void LOREM_genBuffer(void* buffer, size_t size, unsigned seed); + +/* + * LOREM_genBlock(): + * Similar to LOREM_genBuffer, with additional controls : + * - @first : generate the first sentence + * - @fill : fill the entire @buffer, + * if ==0: generate one paragraph at most. + * @return : nb of bytes generated into @buffer. + */ +size_t LOREM_genBlock(void* buffer, size_t size, + unsigned seed, + int first, int fill); diff --git a/src/dependencies/zstd-1.5.4/programs/platform.h b/src/dependencies/zstd-1.5.6/programs/platform.h similarity index 96% rename from src/dependencies/zstd-1.5.4/programs/platform.h rename to src/dependencies/zstd-1.5.6/programs/platform.h index 18a3587..4d2b949 100644 --- a/src/dependencies/zstd-1.5.4/programs/platform.h +++ b/src/dependencies/zstd-1.5.6/programs/platform.h @@ -74,8 +74,7 @@ extern "C" { ***************************************************************/ #ifndef PLATFORM_POSIX_VERSION -# if (defined(__APPLE__) && defined(__MACH__)) || defined(__SVR4) || defined(_AIX) || defined(__hpux) /* POSIX.1-2001 (SUSv3) conformant */ \ - || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) /* BSD distros */ +# if (defined(__APPLE__) && defined(__MACH__)) || defined(__SVR4) || defined(_AIX) || defined(__hpux) /* POSIX.1-2001 (SUSv3) conformant */ /* exception rule : force posix version to 200112L, * note: it's better to use unistd.h's _POSIX_VERSION whenever possible */ # define PLATFORM_POSIX_VERSION 200112L @@ -89,7 +88,7 @@ extern "C" { */ # elif !defined(_WIN32) \ && ( defined(__unix__) || defined(__unix) \ - || defined(__midipix__) || defined(__VMS) || defined(__HAIKU__) ) + || defined(_QNX_SOURCE) || defined(__midipix__) || defined(__VMS) || defined(__HAIKU__) ) # if defined(__linux__) || defined(__linux) || defined(__CYGWIN__) # ifndef _POSIX_C_SOURCE @@ -141,7 +140,7 @@ extern "C" { #elif defined(MSDOS) || defined(OS2) # include /* _isatty */ # define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream)) -#elif defined(WIN32) || defined(_WIN32) +#elif defined(_WIN32) # include /* _isatty */ # include /* DeviceIoControl, HANDLE, FSCTL_SET_SPARSE */ # include /* FILE */ @@ -157,7 +156,7 @@ static __inline int IS_CONSOLE(FILE* stdStream) { /****************************** * OS-specific IO behaviors ******************************/ -#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) +#if defined(MSDOS) || defined(OS2) || defined(_WIN32) # include /* _O_BINARY */ # include /* _setmode, _fileno, _get_osfhandle */ # if !defined(__DJGPP__) diff --git a/src/dependencies/zstd-1.5.4/programs/timefn.c b/src/dependencies/zstd-1.5.6/programs/timefn.c similarity index 98% rename from src/dependencies/zstd-1.5.4/programs/timefn.c rename to src/dependencies/zstd-1.5.6/programs/timefn.c index f941e57..4f04522 100644 --- a/src/dependencies/zstd-1.5.4/programs/timefn.c +++ b/src/dependencies/zstd-1.5.6/programs/timefn.c @@ -88,7 +88,7 @@ UTIL_time_t UTIL_getTime(void) /* C11 requires support of timespec_get(). * However, FreeBSD 11 claims C11 compliance while lacking timespec_get(). * Double confirm timespec_get() support by checking the definition of TIME_UTC. - * However, some versions of Android manage to simultanously define TIME_UTC + * However, some versions of Android manage to simultaneously define TIME_UTC * and lack timespec_get() support... */ #elif (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */) \ && defined(TIME_UTC) && !defined(__ANDROID__) diff --git a/src/dependencies/zstd-1.5.4/programs/timefn.h b/src/dependencies/zstd-1.5.6/programs/timefn.h similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/timefn.h rename to src/dependencies/zstd-1.5.6/programs/timefn.h diff --git a/src/dependencies/zstd-1.5.4/programs/util.c b/src/dependencies/zstd-1.5.6/programs/util.c similarity index 94% rename from src/dependencies/zstd-1.5.4/programs/util.c rename to src/dependencies/zstd-1.5.6/programs/util.c index e017772..7f65f93 100644 --- a/src/dependencies/zstd-1.5.4/programs/util.c +++ b/src/dependencies/zstd-1.5.6/programs/util.c @@ -23,16 +23,27 @@ extern "C" { #include #include +#if defined(__FreeBSD__) +#include /* __FreeBSD_version */ +#endif /* #ifdef __FreeBSD__ */ + #if defined(_WIN32) # include /* utime */ # include /* _chmod */ +# define ZSTD_USE_UTIMENSAT 0 #else # include /* chown, stat */ -# if PLATFORM_POSIX_VERSION < 200809L || !defined(st_mtime) -# include /* utime */ +# include /* utimensat, st_mtime */ +# if (PLATFORM_POSIX_VERSION >= 200809L && defined(st_mtime)) \ + || (defined(__FreeBSD__) && __FreeBSD_version >= 1100056) +# define ZSTD_USE_UTIMENSAT 1 # else +# define ZSTD_USE_UTIMENSAT 0 +# endif +# if ZSTD_USE_UTIMENSAT # include /* AT_FDCWD */ -# include /* utimensat */ +# else +# include /* utime */ # endif #endif @@ -102,6 +113,17 @@ UTIL_STATIC void* UTIL_realloc(void *ptr, size_t size) #define chmod _chmod #endif +#ifndef ZSTD_HAVE_FCHMOD +#if PLATFORM_POSIX_VERSION >= 199309L +#define ZSTD_HAVE_FCHMOD +#endif +#endif + +#ifndef ZSTD_HAVE_FCHOWN +#if PLATFORM_POSIX_VERSION >= 200809L +#define ZSTD_HAVE_FCHOWN +#endif +#endif /*-**************************************** * Console log @@ -147,21 +169,38 @@ void UTIL_traceFileStat(void) g_traceFileStat = 1; } -int UTIL_stat(const char* filename, stat_t* statbuf) +int UTIL_fstat(const int fd, const char* filename, stat_t* statbuf) { int ret; - UTIL_TRACE_CALL("UTIL_stat(%s)", filename); + UTIL_TRACE_CALL("UTIL_stat(%d, %s)", fd, filename); #if defined(_MSC_VER) - ret = !_stat64(filename, statbuf); + if (fd >= 0) { + ret = !_fstat64(fd, statbuf); + } else { + ret = !_stat64(filename, statbuf); + } #elif defined(__MINGW32__) && defined (__MSVCRT__) - ret = !_stati64(filename, statbuf); + if (fd >= 0) { + ret = !_fstati64(fd, statbuf); + } else { + ret = !_stati64(filename, statbuf); + } #else - ret = !stat(filename, statbuf); + if (fd >= 0) { + ret = !fstat(fd, statbuf); + } else { + ret = !stat(filename, statbuf); + } #endif UTIL_TRACE_RET(ret); return ret; } +int UTIL_stat(const char* filename, stat_t* statbuf) +{ + return UTIL_fstat(-1, filename, statbuf); +} + int UTIL_isRegularFile(const char* infilename) { stat_t statbuf; @@ -183,11 +222,16 @@ int UTIL_isRegularFileStat(const stat_t* statbuf) /* like chmod, but avoid changing permission of /dev/null */ int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions) +{ + return UTIL_fchmod(-1, filename, statbuf, permissions); +} + +int UTIL_fchmod(const int fd, char const* filename, const stat_t* statbuf, mode_t permissions) { stat_t localStatBuf; UTIL_TRACE_CALL("UTIL_chmod(%s, %#4o)", filename, (unsigned)permissions); if (statbuf == NULL) { - if (!UTIL_stat(filename, &localStatBuf)) { + if (!UTIL_fstat(fd, filename, &localStatBuf)) { UTIL_TRACE_RET(0); return 0; } @@ -197,9 +241,20 @@ int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions) UTIL_TRACE_RET(0); return 0; /* pretend success, but don't change anything */ } - UTIL_TRACE_CALL("chmod"); +#ifdef ZSTD_HAVE_FCHMOD + if (fd >= 0) { + int ret; + UTIL_TRACE_CALL("fchmod"); + ret = fchmod(fd, permissions); + UTIL_TRACE_RET(ret); + UTIL_TRACE_RET(ret); + return ret; + } else +#endif { - int const ret = chmod(filename, permissions); + int ret; + UTIL_TRACE_CALL("chmod"); + ret = chmod(filename, permissions); UTIL_TRACE_RET(ret); UTIL_TRACE_RET(ret); return ret; @@ -215,7 +270,12 @@ int UTIL_utime(const char* filename, const stat_t *statbuf) * that struct stat has a struct timespec st_mtim member. We need this * check because there are some platforms that claim to be POSIX 2008 * compliant but which do not have st_mtim... */ -#if (PLATFORM_POSIX_VERSION >= 200809L) && defined(st_mtime) + /* FreeBSD has implemented POSIX 2008 for a long time but still only + * advertises support for POSIX 2001. They have a version macro that + * lets us safely gate them in. + * See https://docs.freebsd.org/en/books/porters-handbook/versions/. + */ +#if ZSTD_USE_UTIMENSAT { /* (atime, mtime) */ struct timespec timebuf[2] = { {0, UTIME_NOW} }; @@ -236,19 +296,21 @@ int UTIL_utime(const char* filename, const stat_t *statbuf) } int UTIL_setFileStat(const char *filename, const stat_t *statbuf) +{ + return UTIL_setFDStat(-1, filename, statbuf); +} + +int UTIL_setFDStat(const int fd, const char *filename, const stat_t *statbuf) { int res = 0; stat_t curStatBuf; - UTIL_TRACE_CALL("UTIL_setFileStat(%s)", filename); + UTIL_TRACE_CALL("UTIL_setFileStat(%d, %s)", fd, filename); - if (!UTIL_stat(filename, &curStatBuf) || !UTIL_isRegularFileStat(&curStatBuf)) { + if (!UTIL_fstat(fd, filename, &curStatBuf) || !UTIL_isRegularFileStat(&curStatBuf)) { UTIL_TRACE_RET(-1); return -1; } - /* set access and modification times */ - res += UTIL_utime(filename, statbuf); - /* Mimic gzip's behavior: * * "Change the group first, then the permissions, then the owner. @@ -258,13 +320,27 @@ int UTIL_setFileStat(const char *filename, const stat_t *statbuf) * setgid bits." */ #if !defined(_WIN32) - res += chown(filename, -1, statbuf->st_gid); /* Apply group ownership */ +#ifdef ZSTD_HAVE_FCHOWN + if (fd >= 0) { + res += fchown(fd, -1, statbuf->st_gid); /* Apply group ownership */ + } else +#endif + { + res += chown(filename, -1, statbuf->st_gid); /* Apply group ownership */ + } #endif - res += UTIL_chmod(filename, &curStatBuf, statbuf->st_mode & 0777); /* Copy file permissions */ + res += UTIL_fchmod(fd, filename, &curStatBuf, statbuf->st_mode & 0777); /* Copy file permissions */ #if !defined(_WIN32) - res += chown(filename, statbuf->st_uid, -1); /* Apply user ownership */ +#ifdef ZSTD_HAVE_FCHOWN + if (fd >= 0) { + res += fchown(fd, statbuf->st_uid, -1); /* Apply user ownership */ + } else +#endif + { + res += chown(filename, statbuf->st_uid, -1); /* Apply user ownership */ + } #endif errno = 0; @@ -600,7 +676,6 @@ UTIL_createFileNamesTable_fromFileName(const char* inputFileName) size_t nbFiles = 0; char* buf; size_t bufSize; - size_t pos = 0; stat_t statbuf; if (!UTIL_stat(inputFileName, &statbuf) || !UTIL_isRegularFileStat(&statbuf)) @@ -627,12 +702,13 @@ UTIL_createFileNamesTable_fromFileName(const char* inputFileName) { const char** filenamesTable = (const char**) malloc(nbFiles * sizeof(*filenamesTable)); CONTROL(filenamesTable != NULL); - { size_t fnb; - for (fnb = 0, pos = 0; fnb < nbFiles; fnb++) { + { size_t fnb, pos = 0; + for (fnb = 0; fnb < nbFiles; fnb++) { filenamesTable[fnb] = buf+pos; pos += strlen(buf+pos)+1; /* +1 for the finishing `\0` */ - } } + } assert(pos <= bufSize); + } return UTIL_assembleFileNamesTable(filenamesTable, nbFiles, buf); } @@ -693,7 +769,7 @@ void UTIL_refFilename(FileNamesTable* fnt, const char* filename) static size_t getTotalTableSize(FileNamesTable* table) { - size_t fnb = 0, totalSize = 0; + size_t fnb, totalSize = 0; for(fnb = 0 ; fnb < table->tableSize && table->fileNames[fnb] ; ++fnb) { totalSize += strlen(table->fileNames[fnb]) + 1; /* +1 to add '\0' at the end of each fileName */ } @@ -1059,9 +1135,6 @@ static char* mallocAndJoin2Dir(const char *dir1, const char *dir2) memcpy(outDirBuffer, dir1, dir1Size); outDirBuffer[dir1Size] = '\0'; - if (dir2[0] == '.') - return outDirBuffer; - buffer = outDirBuffer + dir1Size; if (dir1Size > 0 && *(buffer - 1) != PATH_SEP) { *buffer = PATH_SEP; @@ -1486,7 +1559,6 @@ failed: #elif defined(__FreeBSD__) -#include #include /* Use physical core sysctl when available diff --git a/src/dependencies/zstd-1.5.4/programs/util.h b/src/dependencies/zstd-1.5.6/programs/util.h similarity index 94% rename from src/dependencies/zstd-1.5.4/programs/util.h rename to src/dependencies/zstd-1.5.6/programs/util.h index 4ec5413..571d394 100644 --- a/src/dependencies/zstd-1.5.4/programs/util.h +++ b/src/dependencies/zstd-1.5.6/programs/util.h @@ -126,15 +126,25 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, const /** * Calls platform's equivalent of stat() on filename and writes info to statbuf. * Returns success (1) or failure (0). + * + * UTIL_fstat() is like UTIL_stat() but takes an optional fd that refers to the + * file in question. It turns out that this can be meaningfully faster. If fd is + * -1, behaves just like UTIL_stat() (i.e., falls back to using the filename). */ int UTIL_stat(const char* filename, stat_t* statbuf); +int UTIL_fstat(const int fd, const char* filename, stat_t* statbuf); /** * Instead of getting a file's stats, this updates them with the info in the * provided stat_t. Currently sets owner, group, atime, and mtime. Will only * update this info for regular files. + * + * UTIL_setFDStat() also takes an fd, and will preferentially use that to + * indicate which file to modify, If fd is -1, it will fall back to using the + * filename. */ int UTIL_setFileStat(const char* filename, const stat_t* statbuf); +int UTIL_setFDStat(const int fd, const char* filename, const stat_t* statbuf); /** * Set atime to now and mtime to the st_mtim in statbuf. @@ -159,8 +169,11 @@ U64 UTIL_getFileSizeStat(const stat_t* statbuf); * Like chmod(), but only modifies regular files. Provided statbuf may be NULL, * in which case this function will stat() the file internally, in order to * check whether it should be modified. + * + * If fd is -1, fd is ignored and the filename is used. */ int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions); +int UTIL_fchmod(const int fd, char const* filename, const stat_t* statbuf, mode_t permissions); /* * In the absence of a pre-existing stat result on the file in question, these @@ -325,7 +338,7 @@ void UTIL_refFilename(FileNamesTable* fnt, const char* filename); FileNamesTable* UTIL_createExpandedFNT(const char* const* filenames, size_t nbFilenames, int followLinks); -#if defined(_WIN32) || defined(WIN32) +#if defined(_WIN32) DWORD CountSetBits(ULONG_PTR bitMask); #endif diff --git a/src/dependencies/zstd-1.5.4/programs/windres/verrsrc.h b/src/dependencies/zstd-1.5.6/programs/windres/verrsrc.h similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/windres/verrsrc.h rename to src/dependencies/zstd-1.5.6/programs/windres/verrsrc.h diff --git a/src/dependencies/zstd-1.5.4/build/VS2010/zstd/zstd.rc b/src/dependencies/zstd-1.5.6/programs/windres/zstd.rc similarity index 100% rename from src/dependencies/zstd-1.5.4/build/VS2010/zstd/zstd.rc rename to src/dependencies/zstd-1.5.6/programs/windres/zstd.rc diff --git a/src/dependencies/zstd-1.5.4/programs/windres/zstd32.res b/src/dependencies/zstd-1.5.6/programs/windres/zstd32.res similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/windres/zstd32.res rename to src/dependencies/zstd-1.5.6/programs/windres/zstd32.res diff --git a/src/dependencies/zstd-1.5.4/programs/windres/zstd64.res b/src/dependencies/zstd-1.5.6/programs/windres/zstd64.res similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/windres/zstd64.res rename to src/dependencies/zstd-1.5.6/programs/windres/zstd64.res diff --git a/src/dependencies/zstd-1.5.4/programs/zstd.1 b/src/dependencies/zstd-1.5.6/programs/zstd.1 similarity index 84% rename from src/dependencies/zstd-1.5.4/programs/zstd.1 rename to src/dependencies/zstd-1.5.6/programs/zstd.1 index edc128f..2b5a985 100644 --- a/src/dependencies/zstd-1.5.4/programs/zstd.1 +++ b/src/dependencies/zstd-1.5.6/programs/zstd.1 @@ -1,381 +1,566 @@ -.TH "ZSTD" "1" "February 2023" "zstd 1.5.4" "User Commands" +. +.TH "ZSTD" "1" "March 2024" "zstd 1.5.6" "User Commands" +. .SH "NAME" \fBzstd\fR \- zstd, zstdmt, unzstd, zstdcat \- Compress or decompress \.zst files +. .SH "SYNOPSIS" -.TS -allbox; -\fBzstd\fR [\fIOPTIONS\fR] [\- \fIINPUT\-FILE\fR] [\-o \fIOUTPUT\-FILE\fR] -.TE +\fBzstd\fR [\fIOPTIONS\fR] [\-|\fIINPUT\-FILE\fR] [\-o \fIOUTPUT\-FILE\fR] +. .P \fBzstdmt\fR is equivalent to \fBzstd \-T0\fR +. .P \fBunzstd\fR is equivalent to \fBzstd \-d\fR +. .P \fBzstdcat\fR is equivalent to \fBzstd \-dcf\fR +. .SH "DESCRIPTION" -\fBzstd\fR is a fast lossless compression algorithm and data compression tool, with command line syntax similar to \fBgzip\fR(1) and \fBxz\fR(1)\. It is based on the \fBLZ77\fR family, with further FSE & huff0 entropy stages\. \fBzstd\fR offers highly configurable compression speed, from fast modes at > 200 MB/s per core, to strong modes with excellent compression ratios\. It also features a very fast decoder, with speeds > 500 MB/s per core\. +\fBzstd\fR is a fast lossless compression algorithm and data compression tool, with command line syntax similar to \fBgzip\fR(1) and \fBxz\fR(1)\. It is based on the \fBLZ77\fR family, with further FSE & huff0 entropy stages\. \fBzstd\fR offers highly configurable compression speed, from fast modes at > 200 MB/s per core, to strong modes with excellent compression ratios\. It also features a very fast decoder, with speeds > 500 MB/s per core, which remains roughly stable at all compression settings\. +. .P -\fBzstd\fR command line syntax is generally similar to gzip, but features the following differences: -.IP "\[ci]" 4 +\fBzstd\fR command line syntax is generally similar to gzip, but features the following few differences: +. +.IP "\(bu" 4 Source files are preserved by default\. It\'s possible to remove them automatically by using the \fB\-\-rm\fR command\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 When compressing a single file, \fBzstd\fR displays progress notifications and result summary by default\. Use \fB\-q\fR to turn them off\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fBzstd\fR displays a short help page when command line is an error\. Use \fB\-q\fR to turn it off\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fBzstd\fR does not accept input from console, though it does accept \fBstdin\fR when it\'s not the console\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fBzstd\fR does not store the input\'s filename or attributes, only its contents\. +. .IP "" 0 +. .P \fBzstd\fR processes each \fIfile\fR according to the selected operation mode\. If no \fIfiles\fR are given or \fIfile\fR is \fB\-\fR, \fBzstd\fR reads from standard input and writes the processed data to standard output\. \fBzstd\fR will refuse to write compressed data to standard output if it is a terminal: it will display an error message and skip the file\. Similarly, \fBzstd\fR will refuse to read compressed data from standard input if it is a terminal\. +. .P Unless \fB\-\-stdout\fR or \fB\-o\fR is specified, \fIfiles\fR are written to a new file whose name is derived from the source \fIfile\fR name: -.IP "\[ci]" 4 +. +.IP "\(bu" 4 When compressing, the suffix \fB\.zst\fR is appended to the source filename to get the target filename\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 When decompressing, the \fB\.zst\fR suffix is removed from the source filename to get the target filename +. .IP "" 0 +. .SS "Concatenation with \.zst Files" It is possible to concatenate multiple \fB\.zst\fR files\. \fBzstd\fR will decompress such agglomerated file as if it was a single \fB\.zst\fR file\. +. .SH "OPTIONS" +. .SS "Integer Suffixes and Special Values" In most places where an integer argument is expected, an optional suffix is supported to easily indicate large integers\. There must be no space between the integer and the suffix\. +. .TP \fBKiB\fR -Multiply the integer by 1,024 (2\e^10)\. \fBKi\fR, \fBK\fR, and \fBKB\fR are accepted as synonyms for \fBKiB\fR\. +Multiply the integer by 1,024 (2^10)\. \fBKi\fR, \fBK\fR, and \fBKB\fR are accepted as synonyms for \fBKiB\fR\. +. .TP \fBMiB\fR -Multiply the integer by 1,048,576 (2\e^20)\. \fBMi\fR, \fBM\fR, and \fBMB\fR are accepted as synonyms for \fBMiB\fR\. +Multiply the integer by 1,048,576 (2^20)\. \fBMi\fR, \fBM\fR, and \fBMB\fR are accepted as synonyms for \fBMiB\fR\. +. .SS "Operation Mode" If multiple operation mode options are given, the last one takes effect\. +. .TP \fB\-z\fR, \fB\-\-compress\fR Compress\. This is the default operation mode when no operation mode option is specified and no other operation mode is implied from the command name (for example, \fBunzstd\fR implies \fB\-\-decompress\fR)\. +. .TP \fB\-d\fR, \fB\-\-decompress\fR, \fB\-\-uncompress\fR Decompress\. +. .TP \fB\-t\fR, \fB\-\-test\fR Test the integrity of compressed \fIfiles\fR\. This option is equivalent to \fB\-\-decompress \-\-stdout > /dev/null\fR, decompressed data is discarded and checksummed for errors\. No files are created or removed\. +. .TP \fB\-b#\fR Benchmark file(s) using compression level \fI#\fR\. See \fIBENCHMARK\fR below for a description of this operation\. +. .TP \fB\-\-train FILES\fR Use \fIFILES\fR as a training set to create a dictionary\. The training set should contain a lot of small files (> 100)\. See \fIDICTIONARY BUILDER\fR below for a description of this operation\. +. .TP \fB\-l\fR, \fB\-\-list\fR Display information related to a zstd compressed file, such as size, ratio, and checksum\. Some of these fields may not be available\. This command\'s output can be augmented with the \fB\-v\fR modifier\. +. .SS "Operation Modifiers" -.IP "\[ci]" 4 -\fB\-#\fR: selects \fB#\fR compression level [1\-19] (default: 3) -.IP "\[ci]" 4 +. +.IP "\(bu" 4 +\fB\-#\fR: selects \fB#\fR compression level [1\-19] (default: 3)\. Higher compression levels \fIgenerally\fR produce higher compression ratio at the expense of speed and memory\. A rough rule of thumb is that compression speed is expected to be divided by 2 every 2 levels\. Technically, each level is mapped to a set of advanced parameters (that can also be modified individually, see below)\. Because the compressor\'s behavior highly depends on the content to compress, there\'s no guarantee of a smooth progression from one level to another\. +. +.IP "\(bu" 4 \fB\-\-ultra\fR: unlocks high compression levels 20+ (maximum 22), using a lot more memory\. Note that decompression will also require more memory when using these levels\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-fast[=#]\fR: switch to ultra\-fast compression levels\. If \fB=#\fR is not present, it defaults to \fB1\fR\. The higher the value, the faster the compression speed, at the cost of some compression ratio\. This setting overwrites compression level if one was set previously\. Similarly, if a compression level is set after \fB\-\-fast\fR, it overrides it\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-T#\fR, \fB\-\-threads=#\fR: Compress using \fB#\fR working threads (default: 1)\. If \fB#\fR is 0, attempt to detect and use the number of physical CPU cores\. In all cases, the nb of threads is capped to \fBZSTDMT_NBWORKERS_MAX\fR, which is either 64 in 32\-bit mode, or 256 for 64\-bit environments\. This modifier does nothing if \fBzstd\fR is compiled without multithread support\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-single\-thread\fR: Use a single thread for both I/O and compression\. As compression is serialized with I/O, this can be slightly slower\. Single\-thread mode features significantly lower memory usage, which can be useful for systems with limited amount of memory, such as 32\-bit systems\. +. .IP Note 1: this mode is the only available one when multithread support is disabled\. +. .IP Note 2: this mode is different from \fB\-T1\fR, which spawns 1 compression thread in parallel with I/O\. Final compressed result is also slightly different from \fB\-T1\fR\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-auto\-threads={physical,logical} (default: physical)\fR: When using a default amount of threads via \fB\-T0\fR, choose the default based on the number of detected physical or logical cores\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-adapt[=min=#,max=#]\fR: \fBzstd\fR will dynamically adapt compression level to perceived I/O conditions\. Compression level adaptation can be observed live by using command \fB\-v\fR\. Adaptation can be constrained between supplied \fBmin\fR and \fBmax\fR levels\. The feature works when combined with multi\-threading and \fB\-\-long\fR mode\. It does not work with \fB\-\-single\-thread\fR\. It sets window size to 8 MiB by default (can be changed manually, see \fBwlog\fR)\. Due to the chaotic nature of dynamic adaptation, compressed result is not reproducible\. +. .IP \fINote\fR: at the time of this writing, \fB\-\-adapt\fR can remain stuck at low speed when combined with multiple worker threads (>=2)\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-long[=#]\fR: enables long distance matching with \fB#\fR \fBwindowLog\fR, if \fB#\fR is not present it defaults to \fB27\fR\. This increases the window size (\fBwindowLog\fR) and memory usage for both the compressor and decompressor\. This setting is designed to improve the compression ratio for files with long matches at a large distance\. +. .IP Note: If \fBwindowLog\fR is set to larger than 27, \fB\-\-long=windowLog\fR or \fB\-\-memory=windowSize\fR needs to be passed to the decompressor\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-D DICT\fR: use \fBDICT\fR as Dictionary to compress or decompress FILE(s) -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-patch\-from FILE\fR: Specify the file to be used as a reference point for zstd\'s diff engine\. This is effectively dictionary compression with some convenient parameter selection, namely that \fIwindowSize\fR > \fIsrcSize\fR\. +. .IP Note: cannot use both this and \fB\-D\fR together\. +. .IP Note: \fB\-\-long\fR mode will be automatically activated if \fIchainLog\fR < \fIfileLog\fR (\fIfileLog\fR being the \fIwindowLog\fR required to cover the whole file)\. You can also manually force it\. +. .IP Note: for all levels, you can use \fB\-\-patch\-from\fR in \fB\-\-single\-thread\fR mode to improve compression ratio at the cost of speed\. +. .IP Note: for level 19, you can get increased compression ratio at the cost of speed by specifying \fB\-\-zstd=targetLength=\fR to be something large (i\.e\. 4096), and by setting a large \fB\-\-zstd=chainLog=\fR\. -.IP "\[ci]" 4 -\fB\-\-rsyncable\fR: \fBzstd\fR will periodically synchronize the compression state to make the compressed file more rsync\-friendly\. There is a negligible impact to compression ratio, and the faster compression levels will see a small compression speed hit\. This feature does not work with \fB\-\-single\-thread\fR\. You probably don\'t want to use it with long range mode, since it will decrease the effectiveness of the synchronization points, but your mileage may vary\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 +\fB\-\-rsyncable\fR: \fBzstd\fR will periodically synchronize the compression state to make the compressed file more rsync\-friendly\. There is a negligible impact to compression ratio, and a potential impact to compression speed, perceptible at higher speeds, for example when combining \fB\-\-rsyncable\fR with many parallel worker threads\. This feature does not work with \fB\-\-single\-thread\fR\. You probably don\'t want to use it with long range mode, since it will decrease the effectiveness of the synchronization points, but your mileage may vary\. +. +.IP "\(bu" 4 \fB\-C\fR, \fB\-\-[no\-]check\fR: add integrity check computed from uncompressed data (default: enabled) -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-[no\-]content\-size\fR: enable / disable whether or not the original size of the file is placed in the header of the compressed file\. The default option is \fB\-\-content\-size\fR (meaning that the original size will be placed in the header)\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-no\-dictID\fR: do not store dictionary ID within frame header (dictionary compression)\. The decoder will have to rely on implicit knowledge about which dictionary to use, it won\'t be able to check if it\'s correct\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-M#\fR, \fB\-\-memory=#\fR: Set a memory usage limit\. By default, \fBzstd\fR uses 128 MiB for decompression as the maximum amount of memory the decompressor is allowed to use, but you can override this manually if need be in either direction (i\.e\. you can increase or decrease it)\. +. .IP This is also used during compression when using with \fB\-\-patch\-from=\fR\. In this case, this parameter overrides that maximum size allowed for a dictionary\. (128 MiB)\. +. .IP Additionally, this can be used to limit memory for dictionary training\. This parameter overrides the default limit of 2 GiB\. zstd will load training samples up to the memory limit and ignore the rest\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-stream\-size=#\fR: Sets the pledged source size of input coming from a stream\. This value must be exact, as it will be included in the produced frame header\. Incorrect stream sizes will cause an error\. This information will be used to better optimize compression parameters, resulting in better and potentially faster compression, especially for smaller source sizes\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-size\-hint=#\fR: When handling input from a stream, \fBzstd\fR must guess how large the source size will be when optimizing compression parameters\. If the stream size is relatively small, this guess may be a poor one, resulting in a higher compression ratio than expected\. This feature allows for controlling the guess when needed\. Exact guesses result in better compression ratios\. Overestimates result in slightly degraded compression ratios, while underestimates may result in significant degradation\. -.IP "\[ci]" 4 -\fB\-o FILE\fR: save result into \fBFILE\fR\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 +\fB\-\-target\-compressed\-block\-size=#\fR: Attempt to produce compressed blocks of approximately this size\. This will split larger blocks in order to approach this target\. This feature is notably useful for improved latency, when the receiver can leverage receiving early incomplete data\. This parameter defines a loose target: compressed blocks will target this size "on average", but individual blocks can still be larger or smaller\. Enabling this feature can decrease compression speed by up to ~10% at level 1\. Higher levels will see smaller relative speed regression, becoming invisible at higher settings\. +. +.IP "\(bu" 4 \fB\-f\fR, \fB\-\-force\fR: disable input and output checks\. Allows overwriting existing files, input from console, output to stdout, operating on links, block devices, etc\. During decompression and when the output destination is stdout, pass\-through unrecognized formats as\-is\. -.IP "\[ci]" 4 -\fB\-c\fR, \fB\-\-stdout\fR: write to standard output (even if it is the console); keep original files unchanged\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 +\fB\-c\fR, \fB\-\-stdout\fR: write to standard output (even if it is the console); keep original files (disable \fB\-\-rm\fR)\. +. +.IP "\(bu" 4 +\fB\-o FILE\fR: save result into \fBFILE\fR\. Note that this operation is in conflict with \fB\-c\fR\. If both operations are present on the command line, the last expressed one wins\. +. +.IP "\(bu" 4 \fB\-\-[no\-]sparse\fR: enable / disable sparse FS support, to make files with many zeroes smaller on disk\. Creating sparse files may save disk space and speed up decompression by reducing the amount of disk I/O\. default: enabled when output is into a file, and disabled when output is stdout\. This setting overrides default and can force sparse mode over stdout\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-[no\-]pass\-through\fR enable / disable passing through uncompressed files as\-is\. During decompression when pass\-through is enabled, unrecognized formats will be copied as\-is from the input to the output\. By default, pass\-through will occur when the output destination is stdout and the force (\fB\-f\fR) option is set\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-rm\fR: remove source file(s) after successful compression or decompression\. This command is silently ignored if output is \fBstdout\fR\. If used in combination with \fB\-o\fR, triggers a confirmation prompt (which can be silenced with \fB\-f\fR), as this is a destructive operation\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-k\fR, \fB\-\-keep\fR: keep source file(s) after successful compression or decompression\. This is the default behavior\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-r\fR: operate recursively on directories\. It selects all files in the named directory and all its subdirectories\. This can be useful both to reduce command line typing, and to circumvent shell expansion limitations, when there are a lot of files and naming breaks the maximum size of a command line\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-filelist FILE\fR read a list of files to process as content from \fBFILE\fR\. Format is compatible with \fBls\fR output, with one file per line\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-output\-dir\-flat DIR\fR: resulting files are stored into target \fBDIR\fR directory, instead of same directory as origin file\. Be aware that this command can introduce name collision issues, if multiple files, from different directories, end up having the same name\. Collision resolution ensures first file with a given name will be present in \fBDIR\fR, while in combination with \fB\-f\fR, the last file will be present instead\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-output\-dir\-mirror DIR\fR: similar to \fB\-\-output\-dir\-flat\fR, the output files are stored underneath target \fBDIR\fR directory, but this option will replicate input directory hierarchy into output \fBDIR\fR\. +. .IP If input directory contains "\.\.", the files in this directory will be ignored\. If input directory is an absolute directory (i\.e\. "/var/tmp/abc"), it will be stored into the "output\-dir/var/tmp/abc"\. If there are multiple input files or directories, name collision resolution will follow the same rules as \fB\-\-output\-dir\-flat\fR\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-format=FORMAT\fR: compress and decompress in other formats\. If compiled with support, zstd can compress to or decompress from other compression algorithm formats\. Possibly available options are \fBzstd\fR, \fBgzip\fR, \fBxz\fR, \fBlzma\fR, and \fBlz4\fR\. If no such format is provided, \fBzstd\fR is the default\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-h\fR/\fB\-H\fR, \fB\-\-help\fR: display help/long help and exit -.IP "\[ci]" 4 -\fB\-V\fR, \fB\-\-version\fR: display version number and exit\. Advanced: \fB\-vV\fR also displays supported formats\. \fB\-vvV\fR also displays POSIX support\. \fB\-q\fR will only display the version number, suitable for machine reading\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 +\fB\-V\fR, \fB\-\-version\fR: display version number and immediately exit\. note that, since it exits, flags specified after \fB\-V\fR are effectively ignored\. Advanced: \fB\-vV\fR also displays supported formats\. \fB\-vvV\fR also displays POSIX support\. \fB\-qV\fR will only display the version number, suitable for machine reading\. +. +.IP "\(bu" 4 \fB\-v\fR, \fB\-\-verbose\fR: verbose mode, display more information -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-q\fR, \fB\-\-quiet\fR: suppress warnings, interactivity, and notifications\. specify twice to suppress errors too\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-no\-progress\fR: do not display the progress bar, but keep all other messages\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 \fB\-\-show\-default\-cparams\fR: shows the default compression parameters that will be used for a particular input file, based on the provided compression level and the input size\. If the provided file is not a regular file (e\.g\. a pipe), this flag will output the parameters used for inputs of unknown size\. -.IP "\[ci]" 4 +. +.IP "\(bu" 4 +\fB\-\-exclude\-compressed\fR: only compress files that are not already compressed\. +. +.IP "\(bu" 4 \fB\-\-\fR: All arguments after \fB\-\-\fR are treated as files +. .IP "" 0 +. .SS "gzip Operation Modifiers" When invoked via a \fBgzip\fR symlink, \fBzstd\fR will support further options that intend to mimic the \fBgzip\fR behavior: +. .TP \fB\-n\fR, \fB\-\-no\-name\fR do not store the original filename and timestamps when compressing a file\. This is the default behavior and hence a no\-op\. +. .TP \fB\-\-best\fR alias to the option \fB\-9\fR\. +. .SS "Environment Variables" -Employing environment variables to set parameters has security implications\. Therefore, this avenue is intentionally limited\. Only \fBZSTD_CLEVEL\fR and \fBZSTD_NBTHREADS\fR are currently supported\. They set the compression level and number of threads to use during compression, respectively\. +Employing environment variables to set parameters has security implications\. Therefore, this avenue is intentionally limited\. Only \fBZSTD_CLEVEL\fR and \fBZSTD_NBTHREADS\fR are currently supported\. They set the default compression level and number of threads to use during compression, respectively\. +. .P \fBZSTD_CLEVEL\fR can be used to set the level between 1 and 19 (the "normal" range)\. If the value of \fBZSTD_CLEVEL\fR is not a valid integer, it will be ignored with a warning message\. \fBZSTD_CLEVEL\fR just replaces the default compression level (\fB3\fR)\. +. .P -\fBZSTD_NBTHREADS\fR can be used to set the number of threads \fBzstd\fR will attempt to use during compression\. If the value of \fBZSTD_NBTHREADS\fR is not a valid unsigned integer, it will be ignored with a warning message\. \fBZSTD_NBTHREADS\fR has a default value of (\fB1\fR), and is capped at ZSTDMT_NBWORKERS_MAX==200\. \fBzstd\fR must be compiled with multithread support for this to have any effect\. +\fBZSTD_NBTHREADS\fR can be used to set the number of threads \fBzstd\fR will attempt to use during compression\. If the value of \fBZSTD_NBTHREADS\fR is not a valid unsigned integer, it will be ignored with a warning message\. \fBZSTD_NBTHREADS\fR has a default value of (\fB1\fR), and is capped at ZSTDMT_NBWORKERS_MAX==200\. \fBzstd\fR must be compiled with multithread support for this variable to have any effect\. +. .P They can both be overridden by corresponding command line arguments: \fB\-#\fR for compression level and \fB\-T#\fR for number of compression threads\. -.SH "DICTIONARY BUILDER" -\fBzstd\fR offers \fIdictionary\fR compression, which greatly improves efficiency on small files and messages\. It\'s possible to train \fBzstd\fR with a set of samples, the result of which is saved into a file called a \fBdictionary\fR\. Then, during compression and decompression, reference the same dictionary, using command \fB\-D dictionaryFileName\fR\. Compression of small files similar to the sample set will be greatly improved\. -.TP -\fB\-\-train FILEs\fR -Use FILEs as training set to create a dictionary\. The training set should ideally contain a lot of samples (> 100), and weight typically 100x the target dictionary size (for example, ~10 MB for a 100 KB dictionary)\. \fB\-\-train\fR can be combined with \fB\-r\fR to indicate a directory rather than listing all the files, which can be useful to circumvent shell expansion limits\. -.IP -Since dictionary compression is mostly effective for small files, the expectation is that the training set will only contain small files\. In the case where some samples happen to be large, only the first 128 KiB of these samples will be used for training\. -.IP -\fB\-\-train\fR supports multithreading if \fBzstd\fR is compiled with threading support (default)\. Additional advanced parameters can be specified with \fB\-\-train\-fastcover\fR\. The legacy dictionary builder can be accessed with \fB\-\-train\-legacy\fR\. The slower cover dictionary builder can be accessed with \fB\-\-train\-cover\fR\. Default \fB\-\-train\fR is equivalent to \fB\-\-train\-fastcover=d=8,steps=4\fR\. -.TP -\fB\-o FILE\fR -Dictionary saved into \fBFILE\fR (default name: dictionary)\. -.TP -\fB\-\-maxdict=#\fR -Limit dictionary to specified size (default: 112640 bytes)\. As usual, quantities are expressed in bytes by default, and it\'s possible to employ suffixes (like \fBKB\fR or \fBMB\fR) to specify larger values\. -.TP -\fB\-#\fR -Use \fB#\fR compression level during training (optional)\. Will generate statistics more tuned for selected compression level, resulting in a \fIsmall\fR compression ratio improvement for this level\. -.TP -\fB\-B#\fR -Split input files into blocks of size # (default: no split) -.TP -\fB\-M#\fR, \fB\-\-memory=#\fR -Limit the amount of sample data loaded for training (default: 2 GB)\. Note that the default (2 GB) is also the maximum\. This parameter can be useful in situations where the training set size is not well controlled and could be potentially very large\. Since speed of the training process is directly correlated to the size of the training sample set, a smaller sample set leads to faster training\. -.IP -In situations where the training set is larger than maximum memory, the CLI will randomly select samples among the available ones, up to the maximum allowed memory budget\. This is meant to improve dictionary relevance by mitigating the potential impact of clustering, such as selecting only files from the beginning of a list sorted by modification date, or sorted by alphabetical order\. The randomization process is deterministic, so training of the same list of files with the same parameters will lead to the creation of the same dictionary\. -.TP -\fB\-\-dictID=#\fR -A dictionary ID is a locally unique ID\. The decoder will use this value to verify it is using the right dictionary\. By default, zstd will create a 4\-bytes random number ID\. It\'s possible to provide an explicit number ID instead\. It\'s up to the dictionary manager to not assign twice the same ID to 2 different dictionaries\. Note that short numbers have an advantage: an ID < 256 will only need 1 byte in the compressed frame header, and an ID < 65536 will only need 2 bytes\. This compares favorably to 4 bytes default\. -.IP -Note that RFC8878 reserves IDs less than 32768 and greater than or equal to 2\e^31, so they should not be used in public\. -.TP -\fB\-\-train\-cover[=k#,d=#,steps=#,split=#,shrink[=#]]\fR -Select parameters for the default dictionary builder algorithm named cover\. If \fId\fR is not specified, then it tries \fId\fR = 6 and \fId\fR = 8\. If \fIk\fR is not specified, then it tries \fIsteps\fR values in the range [50, 2000]\. If \fIsteps\fR is not specified, then the default value of 40 is used\. If \fIsplit\fR is not specified or split <= 0, then the default value of 100 is used\. Requires that \fId\fR <= \fIk\fR\. If \fIshrink\fR flag is not used, then the default value for \fIshrinkDict\fR of 0 is used\. If \fIshrink\fR is not specified, then the default value for \fIshrinkDictMaxRegression\fR of 1 is used\. -.IP -Selects segments of size \fIk\fR with highest score to put in the dictionary\. The score of a segment is computed by the sum of the frequencies of all the subsegments of size \fId\fR\. Generally \fId\fR should be in the range [6, 8], occasionally up to 16, but the algorithm will run faster with d <= \fI8\fR\. Good values for \fIk\fR vary widely based on the input data, but a safe range is [2 * \fId\fR, 2000]\. If \fIsplit\fR is 100, all input samples are used for both training and testing to find optimal \fId\fR and \fIk\fR to build dictionary\. Supports multithreading if \fBzstd\fR is compiled with threading support\. Having \fIshrink\fR enabled takes a truncated dictionary of minimum size and doubles in size until compression ratio of the truncated dictionary is at most \fIshrinkDictMaxRegression%\fR worse than the compression ratio of the largest dictionary\. -.IP -Examples: -.IP -\fBzstd \-\-train\-cover FILEs\fR -.IP -\fBzstd \-\-train\-cover=k=50,d=8 FILEs\fR -.IP -\fBzstd \-\-train\-cover=d=8,steps=500 FILEs\fR -.IP -\fBzstd \-\-train\-cover=k=50 FILEs\fR -.IP -\fBzstd \-\-train\-cover=k=50,split=60 FILEs\fR -.IP -\fBzstd \-\-train\-cover=shrink FILEs\fR -.IP -\fBzstd \-\-train\-cover=shrink=2 FILEs\fR -.TP -\fB\-\-train\-fastcover[=k#,d=#,f=#,steps=#,split=#,accel=#]\fR -Same as cover but with extra parameters \fIf\fR and \fIaccel\fR and different default value of split If \fIsplit\fR is not specified, then it tries \fIsplit\fR = 75\. If \fIf\fR is not specified, then it tries \fIf\fR = 20\. Requires that 0 < \fIf\fR < 32\. If \fIaccel\fR is not specified, then it tries \fIaccel\fR = 1\. Requires that 0 < \fIaccel\fR <= 10\. Requires that \fId\fR = 6 or \fId\fR = 8\. -.IP -\fIf\fR is log of size of array that keeps track of frequency of subsegments of size \fId\fR\. The subsegment is hashed to an index in the range [0,2^\fIf\fR \- 1]\. It is possible that 2 different subsegments are hashed to the same index, and they are considered as the same subsegment when computing frequency\. Using a higher \fIf\fR reduces collision but takes longer\. -.IP -Examples: -.IP -\fBzstd \-\-train\-fastcover FILEs\fR -.IP -\fBzstd \-\-train\-fastcover=d=8,f=15,accel=2 FILEs\fR -.TP -\fB\-\-train\-legacy[=selectivity=#]\fR -Use legacy dictionary builder algorithm with the given dictionary \fIselectivity\fR (default: 9)\. The smaller the \fIselectivity\fR value, the denser the dictionary, improving its efficiency but reducing its achievable maximum size\. \fB\-\-train\-legacy=s=#\fR is also accepted\. -.IP -Examples: -.IP -\fBzstd \-\-train\-legacy FILEs\fR -.IP -\fBzstd \-\-train\-legacy=selectivity=8 FILEs\fR -.SH "BENCHMARK" -.TP -\fB\-b#\fR -benchmark file(s) using compression level # -.TP -\fB\-e#\fR -benchmark file(s) using multiple compression levels, from \fB\-b#\fR to \fB\-e#\fR (inclusive) -.TP -\fB\-i#\fR -minimum evaluation time, in seconds (default: 3s), benchmark mode only -.TP -\fB\-B#\fR, \fB\-\-block\-size=#\fR -cut file(s) into independent chunks of size # (default: no chunking) -.TP -\fB\-\-priority=rt\fR -set process priority to real\-time -.P -\fBOutput Format:\fR CompressionLevel#Filename: InputSize \-> OutputSize (CompressionRatio), CompressionSpeed, DecompressionSpeed -.P -\fBMethodology:\fR For both compression and decompression speed, the entire input is compressed/decompressed in\-memory to measure speed\. A run lasts at least 1 sec, so when files are small, they are compressed/decompressed several times per run, in order to improve measurement accuracy\. +. .SH "ADVANCED COMPRESSION OPTIONS" -### \-B#: Specify the size of each compression job\. This parameter is only available when multi\-threading is enabled\. Each compression job is run in parallel, so this value indirectly impacts the nb of active threads\. Default job size varies depending on compression level (generally \fB4 * windowSize\fR)\. \fB\-B#\fR makes it possible to manually select a custom size\. Note that job size must respect a minimum value which is enforced transparently\. This minimum is either 512 KB, or \fBoverlapSize\fR, whichever is largest\. Different job sizes will lead to non\-identical compressed frames\. +\fBzstd\fR provides 22 predefined regular compression levels plus the fast levels\. A compression level is translated internally into multiple advanced parameters that control the behavior of the compressor (one can observe the result of this translation with \fB\-\-show\-default\-cparams\fR)\. These advanced parameters can be overridden using advanced compression options\. +. .SS "\-\-zstd[=options]:" -\fBzstd\fR provides 22 predefined regular compression levels plus the fast levels\. This compression level is translated internally into a number of specific parameters that actually control the behavior of the compressor\. (You can see the result of this translation with \fB\-\-show\-default\-cparams\fR\.) These specific parameters can be overridden with advanced compression options\. The \fIoptions\fR are provided as a comma\-separated list\. You may specify only the options you want to change and the rest will be taken from the selected or default compression level\. The list of available \fIoptions\fR: +The \fIoptions\fR are provided as a comma\-separated list\. You may specify only the options you want to change and the rest will be taken from the selected or default compression level\. The list of available \fIoptions\fR: +. .TP \fBstrategy\fR=\fIstrat\fR, \fBstrat\fR=\fIstrat\fR Specify a strategy used by a match finder\. +. .IP There are 9 strategies numbered from 1 to 9, from fastest to strongest: 1=\fBZSTD_fast\fR, 2=\fBZSTD_dfast\fR, 3=\fBZSTD_greedy\fR, 4=\fBZSTD_lazy\fR, 5=\fBZSTD_lazy2\fR, 6=\fBZSTD_btlazy2\fR, 7=\fBZSTD_btopt\fR, 8=\fBZSTD_btultra\fR, 9=\fBZSTD_btultra2\fR\. +. .TP \fBwindowLog\fR=\fIwlog\fR, \fBwlog\fR=\fIwlog\fR Specify the maximum number of bits for a match distance\. +. .IP The higher number of increases the chance to find a match which usually improves compression ratio\. It also increases memory requirements for the compressor and decompressor\. The minimum \fIwlog\fR is 10 (1 KiB) and the maximum is 30 (1 GiB) on 32\-bit platforms and 31 (2 GiB) on 64\-bit platforms\. +. .IP Note: If \fBwindowLog\fR is set to larger than 27, \fB\-\-long=windowLog\fR or \fB\-\-memory=windowSize\fR needs to be passed to the decompressor\. +. .TP \fBhashLog\fR=\fIhlog\fR, \fBhlog\fR=\fIhlog\fR Specify the maximum number of bits for a hash table\. +. .IP Bigger hash tables cause fewer collisions which usually makes compression faster, but requires more memory during compression\. +. .IP The minimum \fIhlog\fR is 6 (64 entries / 256 B) and the maximum is 30 (1B entries / 4 GiB)\. +. .TP \fBchainLog\fR=\fIclog\fR, \fBclog\fR=\fIclog\fR Specify the maximum number of bits for the secondary search structure, whose form depends on the selected \fBstrategy\fR\. +. .IP Higher numbers of bits increases the chance to find a match which usually improves compression ratio\. It also slows down compression speed and increases memory requirements for compression\. This option is ignored for the \fBZSTD_fast\fR \fBstrategy\fR, which only has the primary hash table\. +. .IP The minimum \fIclog\fR is 6 (64 entries / 256 B) and the maximum is 29 (512M entries / 2 GiB) on 32\-bit platforms and 30 (1B entries / 4 GiB) on 64\-bit platforms\. +. .TP \fBsearchLog\fR=\fIslog\fR, \fBslog\fR=\fIslog\fR Specify the maximum number of searches in a hash chain or a binary tree using logarithmic scale\. +. .IP More searches increases the chance to find a match which usually increases compression ratio but decreases compression speed\. +. .IP The minimum \fIslog\fR is 1 and the maximum is \'windowLog\' \- 1\. +. .TP \fBminMatch\fR=\fImml\fR, \fBmml\fR=\fImml\fR Specify the minimum searched length of a match in a hash table\. +. .IP Larger search lengths usually decrease compression ratio but improve decompression speed\. +. .IP The minimum \fImml\fR is 3 and the maximum is 7\. +. .TP \fBtargetLength\fR=\fItlen\fR, \fBtlen\fR=\fItlen\fR The impact of this field vary depending on selected strategy\. +. .IP For \fBZSTD_btopt\fR, \fBZSTD_btultra\fR and \fBZSTD_btultra2\fR, it specifies the minimum match length that causes match finder to stop searching\. A larger \fBtargetLength\fR usually improves compression ratio but decreases compression speed\. +. .IP For \fBZSTD_fast\fR, it triggers ultra\-fast mode when > 0\. The value represents the amount of data skipped between match sampling\. Impact is reversed: a larger \fBtargetLength\fR increases compression speed but decreases compression ratio\. +. .IP For all other strategies, this field has no impact\. +. .IP The minimum \fItlen\fR is 0 and the maximum is 128 KiB\. +. .TP \fBoverlapLog\fR=\fIovlog\fR, \fBovlog\fR=\fIovlog\fR Determine \fBoverlapSize\fR, amount of data reloaded from previous job\. This parameter is only available when multithreading is enabled\. Reloading more data improves compression ratio, but decreases speed\. +. .IP The minimum \fIovlog\fR is 0, and the maximum is 9\. 1 means "no overlap", hence completely independent jobs\. 9 means "full overlap", meaning up to \fBwindowSize\fR is reloaded from previous job\. Reducing \fIovlog\fR by 1 reduces the reloaded amount by a factor 2\. For example, 8 means "windowSize/2", and 6 means "windowSize/8"\. Value 0 is special and means "default": \fIovlog\fR is automatically determined by \fBzstd\fR\. In which case, \fIovlog\fR will range from 6 to 9, depending on selected \fIstrat\fR\. +. .TP \fBldmHashLog\fR=\fIlhlog\fR, \fBlhlog\fR=\fIlhlog\fR Specify the maximum size for a hash table used for long distance matching\. +. .IP This option is ignored unless long distance matching is enabled\. +. .IP Bigger hash tables usually improve compression ratio at the expense of more memory during compression and a decrease in compression speed\. +. .IP The minimum \fIlhlog\fR is 6 and the maximum is 30 (default: 20)\. +. .TP \fBldmMinMatch\fR=\fIlmml\fR, \fBlmml\fR=\fIlmml\fR Specify the minimum searched length of a match for long distance matching\. +. .IP This option is ignored unless long distance matching is enabled\. +. .IP Larger/very small values usually decrease compression ratio\. +. .IP The minimum \fIlmml\fR is 4 and the maximum is 4096 (default: 64)\. +. .TP \fBldmBucketSizeLog\fR=\fIlblog\fR, \fBlblog\fR=\fIlblog\fR Specify the size of each bucket for the hash table used for long distance matching\. +. .IP This option is ignored unless long distance matching is enabled\. +. .IP Larger bucket sizes improve collision resolution but decrease compression speed\. +. .IP The minimum \fIlblog\fR is 1 and the maximum is 8 (default: 3)\. +. .TP \fBldmHashRateLog\fR=\fIlhrlog\fR, \fBlhrlog\fR=\fIlhrlog\fR Specify the frequency of inserting entries into the long distance matching hash table\. +. .IP This option is ignored unless long distance matching is enabled\. +. .IP Larger values will improve compression speed\. Deviating far from the default value will likely result in a decrease in compression ratio\. +. .IP The default value is \fBwlog \- lhlog\fR\. +. .SS "Example" The following parameters sets advanced compression options to something similar to predefined level 19 for files bigger than 256 KB: +. .P \fB\-\-zstd\fR=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6 +. +.SS "\-B#:" +Specify the size of each compression job\. This parameter is only available when multi\-threading is enabled\. Each compression job is run in parallel, so this value indirectly impacts the nb of active threads\. Default job size varies depending on compression level (generally \fB4 * windowSize\fR)\. \fB\-B#\fR makes it possible to manually select a custom size\. Note that job size must respect a minimum value which is enforced transparently\. This minimum is either 512 KB, or \fBoverlapSize\fR, whichever is largest\. Different job sizes will lead to non\-identical compressed frames\. +. +.SH "DICTIONARY BUILDER" +\fBzstd\fR offers \fIdictionary\fR compression, which greatly improves efficiency on small files and messages\. It\'s possible to train \fBzstd\fR with a set of samples, the result of which is saved into a file called a \fBdictionary\fR\. Then, during compression and decompression, reference the same dictionary, using command \fB\-D dictionaryFileName\fR\. Compression of small files similar to the sample set will be greatly improved\. +. +.TP +\fB\-\-train FILEs\fR +Use FILEs as training set to create a dictionary\. The training set should ideally contain a lot of samples (> 100), and weight typically 100x the target dictionary size (for example, ~10 MB for a 100 KB dictionary)\. \fB\-\-train\fR can be combined with \fB\-r\fR to indicate a directory rather than listing all the files, which can be useful to circumvent shell expansion limits\. +. +.IP +Since dictionary compression is mostly effective for small files, the expectation is that the training set will only contain small files\. In the case where some samples happen to be large, only the first 128 KiB of these samples will be used for training\. +. +.IP +\fB\-\-train\fR supports multithreading if \fBzstd\fR is compiled with threading support (default)\. Additional advanced parameters can be specified with \fB\-\-train\-fastcover\fR\. The legacy dictionary builder can be accessed with \fB\-\-train\-legacy\fR\. The slower cover dictionary builder can be accessed with \fB\-\-train\-cover\fR\. Default \fB\-\-train\fR is equivalent to \fB\-\-train\-fastcover=d=8,steps=4\fR\. +. +.TP +\fB\-o FILE\fR +Dictionary saved into \fBFILE\fR (default name: dictionary)\. +. +.TP +\fB\-\-maxdict=#\fR +Limit dictionary to specified size (default: 112640 bytes)\. As usual, quantities are expressed in bytes by default, and it\'s possible to employ suffixes (like \fBKB\fR or \fBMB\fR) to specify larger values\. +. +.TP +\fB\-#\fR +Use \fB#\fR compression level during training (optional)\. Will generate statistics more tuned for selected compression level, resulting in a \fIsmall\fR compression ratio improvement for this level\. +. +.TP +\fB\-B#\fR +Split input files into blocks of size # (default: no split) +. +.TP +\fB\-M#\fR, \fB\-\-memory=#\fR +Limit the amount of sample data loaded for training (default: 2 GB)\. Note that the default (2 GB) is also the maximum\. This parameter can be useful in situations where the training set size is not well controlled and could be potentially very large\. Since speed of the training process is directly correlated to the size of the training sample set, a smaller sample set leads to faster training\. +. +.IP +In situations where the training set is larger than maximum memory, the CLI will randomly select samples among the available ones, up to the maximum allowed memory budget\. This is meant to improve dictionary relevance by mitigating the potential impact of clustering, such as selecting only files from the beginning of a list sorted by modification date, or sorted by alphabetical order\. The randomization process is deterministic, so training of the same list of files with the same parameters will lead to the creation of the same dictionary\. +. +.TP +\fB\-\-dictID=#\fR +A dictionary ID is a locally unique ID\. The decoder will use this value to verify it is using the right dictionary\. By default, zstd will create a 4\-bytes random number ID\. It\'s possible to provide an explicit number ID instead\. It\'s up to the dictionary manager to not assign twice the same ID to 2 different dictionaries\. Note that short numbers have an advantage: an ID < 256 will only need 1 byte in the compressed frame header, and an ID < 65536 will only need 2 bytes\. This compares favorably to 4 bytes default\. +. +.IP +Note that RFC8878 reserves IDs less than 32768 and greater than or equal to 2^31, so they should not be used in public\. +. +.TP +\fB\-\-train\-cover[=k#,d=#,steps=#,split=#,shrink[=#]]\fR +Select parameters for the default dictionary builder algorithm named cover\. If \fId\fR is not specified, then it tries \fId\fR = 6 and \fId\fR = 8\. If \fIk\fR is not specified, then it tries \fIsteps\fR values in the range [50, 2000]\. If \fIsteps\fR is not specified, then the default value of 40 is used\. If \fIsplit\fR is not specified or split <= 0, then the default value of 100 is used\. Requires that \fId\fR <= \fIk\fR\. If \fIshrink\fR flag is not used, then the default value for \fIshrinkDict\fR of 0 is used\. If \fIshrink\fR is not specified, then the default value for \fIshrinkDictMaxRegression\fR of 1 is used\. +. +.IP +Selects segments of size \fIk\fR with highest score to put in the dictionary\. The score of a segment is computed by the sum of the frequencies of all the subsegments of size \fId\fR\. Generally \fId\fR should be in the range [6, 8], occasionally up to 16, but the algorithm will run faster with d <= \fI8\fR\. Good values for \fIk\fR vary widely based on the input data, but a safe range is [2 * \fId\fR, 2000]\. If \fIsplit\fR is 100, all input samples are used for both training and testing to find optimal \fId\fR and \fIk\fR to build dictionary\. Supports multithreading if \fBzstd\fR is compiled with threading support\. Having \fIshrink\fR enabled takes a truncated dictionary of minimum size and doubles in size until compression ratio of the truncated dictionary is at most \fIshrinkDictMaxRegression%\fR worse than the compression ratio of the largest dictionary\. +. +.IP +Examples: +. +.IP +\fBzstd \-\-train\-cover FILEs\fR +. +.IP +\fBzstd \-\-train\-cover=k=50,d=8 FILEs\fR +. +.IP +\fBzstd \-\-train\-cover=d=8,steps=500 FILEs\fR +. +.IP +\fBzstd \-\-train\-cover=k=50 FILEs\fR +. +.IP +\fBzstd \-\-train\-cover=k=50,split=60 FILEs\fR +. +.IP +\fBzstd \-\-train\-cover=shrink FILEs\fR +. +.IP +\fBzstd \-\-train\-cover=shrink=2 FILEs\fR +. +.TP +\fB\-\-train\-fastcover[=k#,d=#,f=#,steps=#,split=#,accel=#]\fR +Same as cover but with extra parameters \fIf\fR and \fIaccel\fR and different default value of split If \fIsplit\fR is not specified, then it tries \fIsplit\fR = 75\. If \fIf\fR is not specified, then it tries \fIf\fR = 20\. Requires that 0 < \fIf\fR < 32\. If \fIaccel\fR is not specified, then it tries \fIaccel\fR = 1\. Requires that 0 < \fIaccel\fR <= 10\. Requires that \fId\fR = 6 or \fId\fR = 8\. +. +.IP +\fIf\fR is log of size of array that keeps track of frequency of subsegments of size \fId\fR\. The subsegment is hashed to an index in the range [0,2^\fIf\fR \- 1]\. It is possible that 2 different subsegments are hashed to the same index, and they are considered as the same subsegment when computing frequency\. Using a higher \fIf\fR reduces collision but takes longer\. +. +.IP +Examples: +. +.IP +\fBzstd \-\-train\-fastcover FILEs\fR +. +.IP +\fBzstd \-\-train\-fastcover=d=8,f=15,accel=2 FILEs\fR +. +.TP +\fB\-\-train\-legacy[=selectivity=#]\fR +Use legacy dictionary builder algorithm with the given dictionary \fIselectivity\fR (default: 9)\. The smaller the \fIselectivity\fR value, the denser the dictionary, improving its efficiency but reducing its achievable maximum size\. \fB\-\-train\-legacy=s=#\fR is also accepted\. +. +.IP +Examples: +. +.IP +\fBzstd \-\-train\-legacy FILEs\fR +. +.IP +\fBzstd \-\-train\-legacy=selectivity=8 FILEs\fR +. +.SH "BENCHMARK" +The \fBzstd\fR CLI provides a benchmarking mode that can be used to easily find suitable compression parameters, or alternatively to benchmark a computer\'s performance\. Note that the results are highly dependent on the content being compressed\. +. +.TP +\fB\-b#\fR +benchmark file(s) using compression level # +. +.TP +\fB\-e#\fR +benchmark file(s) using multiple compression levels, from \fB\-b#\fR to \fB\-e#\fR (inclusive) +. +.TP +\fB\-d\fR +benchmark decompression speed only (requires providing an already zstd\-compressed content) +. +.TP +\fB\-i#\fR +minimum evaluation time, in seconds (default: 3s), benchmark mode only +. +.TP +\fB\-B#\fR, \fB\-\-block\-size=#\fR +cut file(s) into independent chunks of size # (default: no chunking) +. +.TP +\fB\-\-priority=rt\fR +set process priority to real\-time (Windows) +. +.P +\fBOutput Format:\fR CompressionLevel#Filename: InputSize \-> OutputSize (CompressionRatio), CompressionSpeed, DecompressionSpeed +. +.P +\fBMethodology:\fR For both compression and decompression speed, the entire input is compressed/decompressed in\-memory to measure speed\. A run lasts at least 1 sec, so when files are small, they are compressed/decompressed several times per run, in order to improve measurement accuracy\. +. .SH "SEE ALSO" \fBzstdgrep\fR(1), \fBzstdless\fR(1), \fBgzip\fR(1), \fBxz\fR(1) +. .P The \fIzstandard\fR format is specified in Y\. Collet, "Zstandard Compression and the \'application/zstd\' Media Type", https://www\.ietf\.org/rfc/rfc8878\.txt, Internet RFC 8878 (February 2021)\. +. .SH "BUGS" Report bugs at: https://github\.com/facebook/zstd/issues +. .SH "AUTHOR" Yann Collet diff --git a/src/dependencies/zstd-1.5.4/programs/zstd.1.md b/src/dependencies/zstd-1.5.6/programs/zstd.1.md similarity index 91% rename from src/dependencies/zstd-1.5.4/programs/zstd.1.md rename to src/dependencies/zstd-1.5.6/programs/zstd.1.md index 3b7f24f..fcbfb45 100644 --- a/src/dependencies/zstd-1.5.4/programs/zstd.1.md +++ b/src/dependencies/zstd-1.5.6/programs/zstd.1.md @@ -21,10 +21,11 @@ It is based on the **LZ77** family, with further FSE & huff0 entropy stages. `zstd` offers highly configurable compression speed, from fast modes at > 200 MB/s per core, to strong modes with excellent compression ratios. -It also features a very fast decoder, with speeds > 500 MB/s per core. +It also features a very fast decoder, with speeds > 500 MB/s per core, +which remains roughly stable at all compression settings. `zstd` command line syntax is generally similar to gzip, -but features the following differences: +but features the following few differences: - Source files are preserved by default. It's possible to remove them automatically by using the `--rm` command. @@ -105,7 +106,11 @@ the last one takes effect. ### Operation Modifiers * `-#`: - selects `#` compression level \[1-19\] (default: 3) + selects `#` compression level \[1-19\] (default: 3). + Higher compression levels *generally* produce higher compression ratio at the expense of speed and memory. + A rough rule of thumb is that compression speed is expected to be divided by 2 every 2 levels. + Technically, each level is mapped to a set of advanced parameters (that can also be modified individually, see below). + Because the compressor's behavior highly depends on the content to compress, there's no guarantee of a smooth progression from one level to another. * `--ultra`: unlocks high compression levels 20+ (maximum 22), using a lot more memory. Note that decompression will also require more memory when using these levels. @@ -177,9 +182,10 @@ the last one takes effect. (i.e. 4096), and by setting a large `--zstd=chainLog=`. * `--rsyncable`: `zstd` will periodically synchronize the compression state to make the - compressed file more rsync-friendly. There is a negligible impact to - compression ratio, and the faster compression levels will see a small - compression speed hit. + compressed file more rsync-friendly. + There is a negligible impact to compression ratio, + and a potential impact to compression speed, perceptible at higher speeds, + for example when combining `--rsyncable` with many parallel worker threads. This feature does not work with `--single-thread`. You probably don't want to use it with long range mode, since it will decrease the effectiveness of the synchronization points, but your mileage may vary. @@ -217,15 +223,24 @@ the last one takes effect. expected. This feature allows for controlling the guess when needed. Exact guesses result in better compression ratios. Overestimates result in slightly degraded compression ratios, while underestimates may result in significant degradation. -* `-o FILE`: - save result into `FILE`. +* `--target-compressed-block-size=#`: + Attempt to produce compressed blocks of approximately this size. + This will split larger blocks in order to approach this target. + This feature is notably useful for improved latency, when the receiver can leverage receiving early incomplete data. + This parameter defines a loose target: compressed blocks will target this size "on average", but individual blocks can still be larger or smaller. + Enabling this feature can decrease compression speed by up to ~10% at level 1. + Higher levels will see smaller relative speed regression, becoming invisible at higher settings. * `-f`, `--force`: disable input and output checks. Allows overwriting existing files, input from console, output to stdout, operating on links, block devices, etc. During decompression and when the output destination is stdout, pass-through unrecognized formats as-is. * `-c`, `--stdout`: - write to standard output (even if it is the console); keep original files unchanged. + write to standard output (even if it is the console); keep original files (disable `--rm`). +* `-o FILE`: + save result into `FILE`. + Note that this operation is in conflict with `-c`. + If both operations are present on the command line, the last expressed one wins. * `--[no-]sparse`: enable / disable sparse FS support, to make files with many zeroes smaller on disk. @@ -282,10 +297,11 @@ the last one takes effect. * `-h`/`-H`, `--help`: display help/long help and exit * `-V`, `--version`: - display version number and exit. + display version number and immediately exit. + note that, since it exits, flags specified after `-V` are effectively ignored. Advanced: `-vV` also displays supported formats. `-vvV` also displays POSIX support. - `-q` will only display the version number, suitable for machine reading. + `-qV` will only display the version number, suitable for machine reading. * `-v`, `--verbose`: verbose mode, display more information * `-q`, `--quiet`: @@ -296,6 +312,8 @@ the last one takes effect. * `--show-default-cparams`: shows the default compression parameters that will be used for a particular input file, based on the provided compression level and the input size. If the provided file is not a regular file (e.g. a pipe), this flag will output the parameters used for inputs of unknown size. +* `--exclude-compressed`: + only compress files that are not already compressed. * `--`: All arguments after `--` are treated as files @@ -312,11 +330,10 @@ options that intend to mimic the `gzip` behavior: ### Environment Variables - Employing environment variables to set parameters has security implications. Therefore, this avenue is intentionally limited. Only `ZSTD_CLEVEL` and `ZSTD_NBTHREADS` are currently supported. -They set the compression level and number of threads to use during compression, respectively. +They set the default compression level and number of threads to use during compression, respectively. `ZSTD_CLEVEL` can be used to set the level between 1 and 19 (the "normal" range). If the value of `ZSTD_CLEVEL` is not a valid integer, it will be ignored with a warning message. @@ -325,12 +342,171 @@ If the value of `ZSTD_CLEVEL` is not a valid integer, it will be ignored with a `ZSTD_NBTHREADS` can be used to set the number of threads `zstd` will attempt to use during compression. If the value of `ZSTD_NBTHREADS` is not a valid unsigned integer, it will be ignored with a warning message. `ZSTD_NBTHREADS` has a default value of (`1`), and is capped at ZSTDMT_NBWORKERS_MAX==200. -`zstd` must be compiled with multithread support for this to have any effect. +`zstd` must be compiled with multithread support for this variable to have any effect. They can both be overridden by corresponding command line arguments: `-#` for compression level and `-T#` for number of compression threads. +ADVANCED COMPRESSION OPTIONS +---------------------------- +`zstd` provides 22 predefined regular compression levels plus the fast levels. +A compression level is translated internally into multiple advanced parameters that control the behavior of the compressor +(one can observe the result of this translation with `--show-default-cparams`). +These advanced parameters can be overridden using advanced compression options. + +### --zstd[=options]: +The _options_ are provided as a comma-separated list. +You may specify only the options you want to change and the rest will be +taken from the selected or default compression level. +The list of available _options_: + +- `strategy`=_strat_, `strat`=_strat_: + Specify a strategy used by a match finder. + + There are 9 strategies numbered from 1 to 9, from fastest to strongest: + 1=`ZSTD_fast`, 2=`ZSTD_dfast`, 3=`ZSTD_greedy`, + 4=`ZSTD_lazy`, 5=`ZSTD_lazy2`, 6=`ZSTD_btlazy2`, + 7=`ZSTD_btopt`, 8=`ZSTD_btultra`, 9=`ZSTD_btultra2`. + +- `windowLog`=_wlog_, `wlog`=_wlog_: + Specify the maximum number of bits for a match distance. + + The higher number of increases the chance to find a match which usually + improves compression ratio. + It also increases memory requirements for the compressor and decompressor. + The minimum _wlog_ is 10 (1 KiB) and the maximum is 30 (1 GiB) on 32-bit + platforms and 31 (2 GiB) on 64-bit platforms. + + Note: If `windowLog` is set to larger than 27, `--long=windowLog` or + `--memory=windowSize` needs to be passed to the decompressor. + +- `hashLog`=_hlog_, `hlog`=_hlog_: + Specify the maximum number of bits for a hash table. + + Bigger hash tables cause fewer collisions which usually makes compression + faster, but requires more memory during compression. + + The minimum _hlog_ is 6 (64 entries / 256 B) and the maximum is 30 (1B entries / 4 GiB). + +- `chainLog`=_clog_, `clog`=_clog_: + Specify the maximum number of bits for the secondary search structure, + whose form depends on the selected `strategy`. + + Higher numbers of bits increases the chance to find a match which usually + improves compression ratio. + It also slows down compression speed and increases memory requirements for + compression. + This option is ignored for the `ZSTD_fast` `strategy`, which only has the primary hash table. + + The minimum _clog_ is 6 (64 entries / 256 B) and the maximum is 29 (512M entries / 2 GiB) on 32-bit platforms + and 30 (1B entries / 4 GiB) on 64-bit platforms. + +- `searchLog`=_slog_, `slog`=_slog_: + Specify the maximum number of searches in a hash chain or a binary tree + using logarithmic scale. + + More searches increases the chance to find a match which usually increases + compression ratio but decreases compression speed. + + The minimum _slog_ is 1 and the maximum is 'windowLog' - 1. + +- `minMatch`=_mml_, `mml`=_mml_: + Specify the minimum searched length of a match in a hash table. + + Larger search lengths usually decrease compression ratio but improve + decompression speed. + + The minimum _mml_ is 3 and the maximum is 7. + +- `targetLength`=_tlen_, `tlen`=_tlen_: + The impact of this field vary depending on selected strategy. + + For `ZSTD_btopt`, `ZSTD_btultra` and `ZSTD_btultra2`, it specifies + the minimum match length that causes match finder to stop searching. + A larger `targetLength` usually improves compression ratio + but decreases compression speed. + + For `ZSTD_fast`, it triggers ultra-fast mode when > 0. + The value represents the amount of data skipped between match sampling. + Impact is reversed: a larger `targetLength` increases compression speed + but decreases compression ratio. + + For all other strategies, this field has no impact. + + The minimum _tlen_ is 0 and the maximum is 128 KiB. + +- `overlapLog`=_ovlog_, `ovlog`=_ovlog_: + Determine `overlapSize`, amount of data reloaded from previous job. + This parameter is only available when multithreading is enabled. + Reloading more data improves compression ratio, but decreases speed. + + The minimum _ovlog_ is 0, and the maximum is 9. + 1 means "no overlap", hence completely independent jobs. + 9 means "full overlap", meaning up to `windowSize` is reloaded from previous job. + Reducing _ovlog_ by 1 reduces the reloaded amount by a factor 2. + For example, 8 means "windowSize/2", and 6 means "windowSize/8". + Value 0 is special and means "default": _ovlog_ is automatically determined by `zstd`. + In which case, _ovlog_ will range from 6 to 9, depending on selected _strat_. + +- `ldmHashLog`=_lhlog_, `lhlog`=_lhlog_: + Specify the maximum size for a hash table used for long distance matching. + + This option is ignored unless long distance matching is enabled. + + Bigger hash tables usually improve compression ratio at the expense of more + memory during compression and a decrease in compression speed. + + The minimum _lhlog_ is 6 and the maximum is 30 (default: 20). + +- `ldmMinMatch`=_lmml_, `lmml`=_lmml_: + Specify the minimum searched length of a match for long distance matching. + + This option is ignored unless long distance matching is enabled. + + Larger/very small values usually decrease compression ratio. + + The minimum _lmml_ is 4 and the maximum is 4096 (default: 64). + +- `ldmBucketSizeLog`=_lblog_, `lblog`=_lblog_: + Specify the size of each bucket for the hash table used for long distance + matching. + + This option is ignored unless long distance matching is enabled. + + Larger bucket sizes improve collision resolution but decrease compression + speed. + + The minimum _lblog_ is 1 and the maximum is 8 (default: 3). + +- `ldmHashRateLog`=_lhrlog_, `lhrlog`=_lhrlog_: + Specify the frequency of inserting entries into the long distance matching + hash table. + + This option is ignored unless long distance matching is enabled. + + Larger values will improve compression speed. Deviating far from the + default value will likely result in a decrease in compression ratio. + + The default value is `wlog - lhlog`. + +### Example +The following parameters sets advanced compression options to something +similar to predefined level 19 for files bigger than 256 KB: + +`--zstd`=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6 + +### -B#: +Specify the size of each compression job. +This parameter is only available when multi-threading is enabled. +Each compression job is run in parallel, so this value indirectly impacts the nb of active threads. +Default job size varies depending on compression level (generally `4 * windowSize`). +`-B#` makes it possible to manually select a custom size. +Note that job size must respect a minimum value which is enforced transparently. +This minimum is either 512 KB, or `overlapSize`, whichever is largest. +Different job sizes will lead to non-identical compressed frames. + + DICTIONARY BUILDER ------------------ `zstd` offers _dictionary_ compression, @@ -483,178 +659,26 @@ Compression of small files similar to the sample set will be greatly improved. BENCHMARK --------- +The `zstd` CLI provides a benchmarking mode that can be used to easily find suitable compression parameters, or alternatively to benchmark a computer's performance. +Note that the results are highly dependent on the content being compressed. * `-b#`: benchmark file(s) using compression level # * `-e#`: benchmark file(s) using multiple compression levels, from `-b#` to `-e#` (inclusive) +* `-d`: + benchmark decompression speed only (requires providing an already zstd-compressed content) * `-i#`: minimum evaluation time, in seconds (default: 3s), benchmark mode only * `-B#`, `--block-size=#`: cut file(s) into independent chunks of size # (default: no chunking) * `--priority=rt`: - set process priority to real-time + set process priority to real-time (Windows) **Output Format:** CompressionLevel#Filename: InputSize -> OutputSize (CompressionRatio), CompressionSpeed, DecompressionSpeed **Methodology:** For both compression and decompression speed, the entire input is compressed/decompressed in-memory to measure speed. A run lasts at least 1 sec, so when files are small, they are compressed/decompressed several times per run, in order to improve measurement accuracy. -ADVANCED COMPRESSION OPTIONS ----------------------------- -### -B#: -Specify the size of each compression job. -This parameter is only available when multi-threading is enabled. -Each compression job is run in parallel, so this value indirectly impacts the nb of active threads. -Default job size varies depending on compression level (generally `4 * windowSize`). -`-B#` makes it possible to manually select a custom size. -Note that job size must respect a minimum value which is enforced transparently. -This minimum is either 512 KB, or `overlapSize`, whichever is largest. -Different job sizes will lead to non-identical compressed frames. - -### --zstd[=options]: -`zstd` provides 22 predefined regular compression levels plus the fast levels. -This compression level is translated internally into a number of specific parameters that actually control the behavior of the compressor. -(You can see the result of this translation with `--show-default-cparams`.) -These specific parameters can be overridden with advanced compression options. -The _options_ are provided as a comma-separated list. -You may specify only the options you want to change and the rest will be -taken from the selected or default compression level. -The list of available _options_: - -- `strategy`=_strat_, `strat`=_strat_: - Specify a strategy used by a match finder. - - There are 9 strategies numbered from 1 to 9, from fastest to strongest: - 1=`ZSTD_fast`, 2=`ZSTD_dfast`, 3=`ZSTD_greedy`, - 4=`ZSTD_lazy`, 5=`ZSTD_lazy2`, 6=`ZSTD_btlazy2`, - 7=`ZSTD_btopt`, 8=`ZSTD_btultra`, 9=`ZSTD_btultra2`. - -- `windowLog`=_wlog_, `wlog`=_wlog_: - Specify the maximum number of bits for a match distance. - - The higher number of increases the chance to find a match which usually - improves compression ratio. - It also increases memory requirements for the compressor and decompressor. - The minimum _wlog_ is 10 (1 KiB) and the maximum is 30 (1 GiB) on 32-bit - platforms and 31 (2 GiB) on 64-bit platforms. - - Note: If `windowLog` is set to larger than 27, `--long=windowLog` or - `--memory=windowSize` needs to be passed to the decompressor. - -- `hashLog`=_hlog_, `hlog`=_hlog_: - Specify the maximum number of bits for a hash table. - - Bigger hash tables cause fewer collisions which usually makes compression - faster, but requires more memory during compression. - - The minimum _hlog_ is 6 (64 entries / 256 B) and the maximum is 30 (1B entries / 4 GiB). - -- `chainLog`=_clog_, `clog`=_clog_: - Specify the maximum number of bits for the secondary search structure, - whose form depends on the selected `strategy`. - - Higher numbers of bits increases the chance to find a match which usually - improves compression ratio. - It also slows down compression speed and increases memory requirements for - compression. - This option is ignored for the `ZSTD_fast` `strategy`, which only has the primary hash table. - - The minimum _clog_ is 6 (64 entries / 256 B) and the maximum is 29 (512M entries / 2 GiB) on 32-bit platforms - and 30 (1B entries / 4 GiB) on 64-bit platforms. - -- `searchLog`=_slog_, `slog`=_slog_: - Specify the maximum number of searches in a hash chain or a binary tree - using logarithmic scale. - - More searches increases the chance to find a match which usually increases - compression ratio but decreases compression speed. - - The minimum _slog_ is 1 and the maximum is 'windowLog' - 1. - -- `minMatch`=_mml_, `mml`=_mml_: - Specify the minimum searched length of a match in a hash table. - - Larger search lengths usually decrease compression ratio but improve - decompression speed. - - The minimum _mml_ is 3 and the maximum is 7. - -- `targetLength`=_tlen_, `tlen`=_tlen_: - The impact of this field vary depending on selected strategy. - - For `ZSTD_btopt`, `ZSTD_btultra` and `ZSTD_btultra2`, it specifies - the minimum match length that causes match finder to stop searching. - A larger `targetLength` usually improves compression ratio - but decreases compression speed. - - For `ZSTD_fast`, it triggers ultra-fast mode when > 0. - The value represents the amount of data skipped between match sampling. - Impact is reversed: a larger `targetLength` increases compression speed - but decreases compression ratio. - - For all other strategies, this field has no impact. - - The minimum _tlen_ is 0 and the maximum is 128 KiB. - -- `overlapLog`=_ovlog_, `ovlog`=_ovlog_: - Determine `overlapSize`, amount of data reloaded from previous job. - This parameter is only available when multithreading is enabled. - Reloading more data improves compression ratio, but decreases speed. - - The minimum _ovlog_ is 0, and the maximum is 9. - 1 means "no overlap", hence completely independent jobs. - 9 means "full overlap", meaning up to `windowSize` is reloaded from previous job. - Reducing _ovlog_ by 1 reduces the reloaded amount by a factor 2. - For example, 8 means "windowSize/2", and 6 means "windowSize/8". - Value 0 is special and means "default": _ovlog_ is automatically determined by `zstd`. - In which case, _ovlog_ will range from 6 to 9, depending on selected _strat_. - -- `ldmHashLog`=_lhlog_, `lhlog`=_lhlog_: - Specify the maximum size for a hash table used for long distance matching. - - This option is ignored unless long distance matching is enabled. - - Bigger hash tables usually improve compression ratio at the expense of more - memory during compression and a decrease in compression speed. - - The minimum _lhlog_ is 6 and the maximum is 30 (default: 20). - -- `ldmMinMatch`=_lmml_, `lmml`=_lmml_: - Specify the minimum searched length of a match for long distance matching. - - This option is ignored unless long distance matching is enabled. - - Larger/very small values usually decrease compression ratio. - - The minimum _lmml_ is 4 and the maximum is 4096 (default: 64). - -- `ldmBucketSizeLog`=_lblog_, `lblog`=_lblog_: - Specify the size of each bucket for the hash table used for long distance - matching. - - This option is ignored unless long distance matching is enabled. - - Larger bucket sizes improve collision resolution but decrease compression - speed. - - The minimum _lblog_ is 1 and the maximum is 8 (default: 3). - -- `ldmHashRateLog`=_lhrlog_, `lhrlog`=_lhrlog_: - Specify the frequency of inserting entries into the long distance matching - hash table. - - This option is ignored unless long distance matching is enabled. - - Larger values will improve compression speed. Deviating far from the - default value will likely result in a decrease in compression ratio. - - The default value is `wlog - lhlog`. - -### Example -The following parameters sets advanced compression options to something -similar to predefined level 19 for files bigger than 256 KB: - -`--zstd`=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6 SEE ALSO -------- diff --git a/src/dependencies/zstd-1.5.4/programs/zstdcli.c b/src/dependencies/zstd-1.5.6/programs/zstdcli.c similarity index 96% rename from src/dependencies/zstd-1.5.4/programs/zstdcli.c rename to src/dependencies/zstd-1.5.6/programs/zstdcli.c index 93f75e2..9dd6b05 100644 --- a/src/dependencies/zstd-1.5.4/programs/zstdcli.c +++ b/src/dependencies/zstd-1.5.6/programs/zstdcli.c @@ -37,7 +37,7 @@ #include "fileio.h" /* stdinmark, stdoutmark, ZSTD_EXTENSION */ #ifndef ZSTD_NOBENCH -# include "benchzstd.h" /* BMK_benchFiles */ +# include "benchzstd.h" /* BMK_benchFilesAdvanced */ #endif #ifndef ZSTD_NODICT # include "dibio.h" /* ZDICT_cover_params_t, DiB_trainFromFiles() */ @@ -138,8 +138,8 @@ static int exeNameMatch(const char* exeName, const char* test) * Command Line **************************************/ /* print help either in `stderr` or `stdout` depending on originating request - * error (badusage) => stderr - * help (usage_advanced) => stdout + * error (badUsage) => stderr + * help (usageAdvanced) => stdout */ static void usage(FILE* f, const char* programName) { @@ -165,7 +165,7 @@ static void usage(FILE* f, const char* programName) #endif DISPLAY_F(f, " -D DICT Use DICT as the dictionary for compression or decompression.\n\n"); DISPLAY_F(f, " -f, --force Disable input and output checks. Allows overwriting existing files,\n"); - DISPLAY_F(f, " receiving input from the console, printing ouput to STDOUT, and\n"); + DISPLAY_F(f, " receiving input from the console, printing output to STDOUT, and\n"); DISPLAY_F(f, " operating on links, block devices, etc. Unrecognized formats will be\n"); DISPLAY_F(f, " passed-through through as-is.\n\n"); @@ -175,7 +175,7 @@ static void usage(FILE* f, const char* programName) DISPLAY_F(f, "\n"); } -static void usage_advanced(const char* programName) +static void usageAdvanced(const char* programName) { DISPLAYOUT(WELCOME_MESSAGE); DISPLAYOUT("\n"); @@ -254,6 +254,7 @@ static void usage_advanced(const char* programName) DISPLAYOUT("\n"); DISPLAYOUT(" --format=zstd Compress files to the `.zst` format. [Default]\n"); + DISPLAYOUT(" --[no-]mmap-dict Memory-map dictionary file rather than mallocing and loading all at once\n"); #ifdef ZSTD_GZCOMPRESS DISPLAYOUT(" --format=gzip Compress files to the `.gz` format.\n"); #endif @@ -315,9 +316,9 @@ static void usage_advanced(const char* programName) } -static void badusage(const char* programName) +static void badUsage(const char* programName, const char* parameter) { - DISPLAYLEVEL(1, "Incorrect parameters \n"); + DISPLAYLEVEL(1, "Incorrect parameter: %s \n", parameter); if (g_displayLevel >= 2) usage(stderr, programName); } @@ -588,7 +589,7 @@ static ZDICT_fastCover_params_t defaultFastCoverParams(void) /** parseAdaptParameters() : - * reads adapt parameters from *stringPtr (e.g. "--zstd=min=1,max=19) and store them into adaptMinPtr and adaptMaxPtr. + * reads adapt parameters from *stringPtr (e.g. "--adapt=min=1,max=19) and store them into adaptMinPtr and adaptMaxPtr. * Both adaptMinPtr and adaptMaxPtr must be already allocated and correctly initialized. * There is no guarantee that any of these values will be updated. * @return 1 means that parsing was successful, @@ -851,10 +852,11 @@ int main(int argCount, const char* argv[]) ultra=0, contentSize=1, removeSrcFile=0; + ZSTD_paramSwitch_e mmapDict=ZSTD_ps_auto; ZSTD_paramSwitch_e useRowMatchFinder = ZSTD_ps_auto; FIO_compressionType_t cType = FIO_zstdCompression; unsigned nbWorkers = 0; - double compressibility = 0.5; + double compressibility = -1.0; /* lorem ipsum generator */ unsigned bench_nbSeconds = 3; /* would be better if this value was synchronized from bench */ size_t blockSize = 0; @@ -931,6 +933,7 @@ int main(int argCount, const char* argv[]) /* command switches */ for (argNb=1; argNbfileNames[i]); for(c = cLevel; c <= cLevelLast; c++) { - BMK_benchOutcome_t const bo = BMK_benchFilesAdvanced(&filenames->fileNames[i], 1, dictFileName, c, &compressionParams, g_displayLevel, &benchParams); - if (!BMK_isSuccessful_benchOutcome(bo)) return 1; + operationResult = BMK_benchFilesAdvanced(&filenames->fileNames[i], 1, dictFileName, c, &compressionParams, g_displayLevel, &benchParams); } } } else { for(; cLevel <= cLevelLast; cLevel++) { - BMK_benchOutcome_t const bo = BMK_benchFilesAdvanced(filenames->fileNames, (unsigned)filenames->tableSize, dictFileName, cLevel, &compressionParams, g_displayLevel, &benchParams); - if (!BMK_isSuccessful_benchOutcome(bo)) return 1; + operationResult = BMK_benchFilesAdvanced(filenames->fileNames, (unsigned)filenames->tableSize, dictFileName, cLevel, &compressionParams, g_displayLevel, &benchParams); } } } else { for(; cLevel <= cLevelLast; cLevel++) { - BMK_benchOutcome_t const bo = BMK_syntheticTest(cLevel, compressibility, &compressionParams, g_displayLevel, &benchParams); - if (!BMK_isSuccessful_benchOutcome(bo)) return 1; + operationResult = BMK_syntheticTest(cLevel, compressibility, &compressionParams, g_displayLevel, &benchParams); } } #else @@ -1526,6 +1535,7 @@ int main(int argCount, const char* argv[]) FIO_setNotificationLevel(g_displayLevel); FIO_setAllowBlockDevices(prefs, allowBlockDevices); FIO_setPatchFromMode(prefs, patchFromDictFileName != NULL); + FIO_setMMapDict(prefs, mmapDict); if (memLimit == 0) { if (compressionParams.windowLog == 0) { memLimit = (U32)1 << g_defaultMaxWindowLog; diff --git a/src/dependencies/zstd-1.5.4/programs/zstdcli_trace.c b/src/dependencies/zstd-1.5.6/programs/zstdcli_trace.c similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/zstdcli_trace.c rename to src/dependencies/zstd-1.5.6/programs/zstdcli_trace.c diff --git a/src/dependencies/zstd-1.5.4/programs/zstdcli_trace.h b/src/dependencies/zstd-1.5.6/programs/zstdcli_trace.h similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/zstdcli_trace.h rename to src/dependencies/zstd-1.5.6/programs/zstdcli_trace.h diff --git a/src/dependencies/zstd-1.5.4/programs/zstdgrep b/src/dependencies/zstd-1.5.6/programs/zstdgrep similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/zstdgrep rename to src/dependencies/zstd-1.5.6/programs/zstdgrep diff --git a/src/dependencies/zstd-1.5.4/programs/zstdgrep.1 b/src/dependencies/zstd-1.5.6/programs/zstdgrep.1 similarity index 91% rename from src/dependencies/zstd-1.5.4/programs/zstdgrep.1 rename to src/dependencies/zstd-1.5.6/programs/zstdgrep.1 index 77d29b4..d7fda58 100644 --- a/src/dependencies/zstd-1.5.4/programs/zstdgrep.1 +++ b/src/dependencies/zstd-1.5.6/programs/zstdgrep.1 @@ -1,17 +1,26 @@ -.TH "ZSTDGREP" "1" "February 2023" "zstd 1.5.4" "User Commands" +. +.TH "ZSTDGREP" "1" "March 2024" "zstd 1.5.6" "User Commands" +. .SH "NAME" \fBzstdgrep\fR \- print lines matching a pattern in zstandard\-compressed files +. .SH "SYNOPSIS" -\fBzstdgrep\fR [\fIgrep\-flags\fR] [\-\-] \fIpattern\fR [\fIfiles\fR \|\.\|\.\|\.] +\fBzstdgrep\fR [\fIgrep\-flags\fR] [\-\-] \fIpattern\fR [\fIfiles\fR \.\.\.] +. .SH "DESCRIPTION" \fBzstdgrep\fR runs \fBgrep\fR(1) on files, or \fBstdin\fR if no files argument is given, after decompressing them with \fBzstdcat\fR(1)\. +. .P The \fIgrep\-flags\fR and \fIpattern\fR arguments are passed on to \fBgrep\fR(1)\. If an \fB\-e\fR flag is found in the \fIgrep\-flags\fR, \fBzstdgrep\fR will not look for a \fIpattern\fR argument\. +. .P Note that modern \fBgrep\fR alternatives such as \fBripgrep\fR (\fBrg\fR(1)) support \fBzstd\fR\-compressed files out of the box, and can prove better alternatives than \fBzstdgrep\fR notably for unsupported complex pattern searches\. Note though that such alternatives may also feature some minor command line differences\. +. .SH "EXIT STATUS" In case of missing arguments or missing pattern, 1 will be returned, otherwise 0\. +. .SH "SEE ALSO" \fBzstd\fR(1) +. .SH "AUTHORS" Thomas Klausner \fIwiz@NetBSD\.org\fR diff --git a/src/dependencies/zstd-1.5.4/programs/zstdgrep.1.md b/src/dependencies/zstd-1.5.6/programs/zstdgrep.1.md similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/zstdgrep.1.md rename to src/dependencies/zstd-1.5.6/programs/zstdgrep.1.md diff --git a/src/dependencies/zstd-1.5.4/programs/zstdless b/src/dependencies/zstd-1.5.6/programs/zstdless similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/zstdless rename to src/dependencies/zstd-1.5.6/programs/zstdless diff --git a/src/dependencies/zstd-1.5.4/programs/zstdless.1 b/src/dependencies/zstd-1.5.6/programs/zstdless.1 similarity index 68% rename from src/dependencies/zstd-1.5.4/programs/zstdless.1 rename to src/dependencies/zstd-1.5.6/programs/zstdless.1 index 6c82b9c..7dd65f8 100644 --- a/src/dependencies/zstd-1.5.4/programs/zstdless.1 +++ b/src/dependencies/zstd-1.5.6/programs/zstdless.1 @@ -1,9 +1,14 @@ -.TH "ZSTDLESS" "1" "February 2023" "zstd 1.5.4" "User Commands" +. +.TH "ZSTDLESS" "1" "March 2024" "zstd 1.5.6" "User Commands" +. .SH "NAME" \fBzstdless\fR \- view zstandard\-compressed files +. .SH "SYNOPSIS" -\fBzstdless\fR [\fIflags\fR] [\fIfile\fR \|\.\|\.\|\.] +\fBzstdless\fR [\fIflags\fR] [\fIfile\fR \.\.\.] +. .SH "DESCRIPTION" \fBzstdless\fR runs \fBless\fR(1) on files or stdin, if no \fIfile\fR argument is given, after decompressing them with \fBzstdcat\fR(1)\. +. .SH "SEE ALSO" \fBzstd\fR(1) diff --git a/src/dependencies/zstd-1.5.4/programs/zstdless.1.md b/src/dependencies/zstd-1.5.6/programs/zstdless.1.md similarity index 100% rename from src/dependencies/zstd-1.5.4/programs/zstdless.1.md rename to src/dependencies/zstd-1.5.6/programs/zstdless.1.md diff --git a/src/dependencies/zstd-1.5.4/tests/.gitignore b/src/dependencies/zstd-1.5.6/tests/.gitignore similarity index 93% rename from src/dependencies/zstd-1.5.4/tests/.gitignore rename to src/dependencies/zstd-1.5.6/tests/.gitignore index fcb865d..311a8b5 100644 --- a/src/dependencies/zstd-1.5.4/tests/.gitignore +++ b/src/dependencies/zstd-1.5.6/tests/.gitignore @@ -67,3 +67,6 @@ speedTest.pid *.exe *.out *.app + +# Specific exclusions +!golden-decompression/*.zst diff --git a/src/dependencies/zstd-1.5.4/tests/DEPRECATED-test-zstd-speed.py b/src/dependencies/zstd-1.5.6/tests/DEPRECATED-test-zstd-speed.py similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/DEPRECATED-test-zstd-speed.py rename to src/dependencies/zstd-1.5.6/tests/DEPRECATED-test-zstd-speed.py diff --git a/src/dependencies/zstd-1.5.4/tests/Makefile b/src/dependencies/zstd-1.5.6/tests/Makefile similarity index 81% rename from src/dependencies/zstd-1.5.4/tests/Makefile rename to src/dependencies/zstd-1.5.6/tests/Makefile index 3eed19e..ed3692a 100644 --- a/src/dependencies/zstd-1.5.4/tests/Makefile +++ b/src/dependencies/zstd-1.5.6/tests/Makefile @@ -20,43 +20,45 @@ # zstreamtest32: Same as zstreamtest, but forced to compile in 32-bits mode # ########################################################################## -LIBZSTD = ../lib - -ZSTD_LEGACY_SUPPORT ?= 0 +ZSTD_LEGACY_SUPPORT ?= 5 +export ZSTD_LEGACY_SUPPORT DEBUGLEVEL ?= 2 export DEBUGLEVEL # transmit value to sub-makefiles -include $(LIBZSTD)/libzstd.mk +LIBZSTD_MK_DIR := ../lib +include $(LIBZSTD_MK_DIR)/libzstd.mk -ZSTDDIR = $(LIBZSTD) PRGDIR = ../programs PYTHON ?= python3 TESTARTEFACT := versionsTest DEBUGFLAGS += -g -Wno-c++-compat -CPPFLAGS += -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \ - -I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(PRGDIR) \ +CPPFLAGS += -I$(LIB_SRCDIR) -I$(LIB_SRCDIR)/common -I$(LIB_SRCDIR)/compress -I$(LIB_SRCDIR)/legacy \ + -I$(LIB_SRCDIR)/dictBuilder -I$(LIB_SRCDIR)/deprecated -I$(PRGDIR) \ -DZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY=1 ZSTDCOMMON_FILES := $(sort $(ZSTD_COMMON_FILES)) ZSTDCOMP_FILES := $(sort $(ZSTD_COMPRESS_FILES)) ZSTDDECOMP_FILES := $(sort $(ZSTD_DECOMPRESS_FILES)) -ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) +ZSTDLEGACY_FILES := $(sort $(wildcard $(LIB_SRCDIR)/legacy/*.c)) +ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) $(ZSTDLEGACY_FILES) ZDICT_FILES := $(sort $(ZSTD_DICTBUILDER_FILES)) ZSTD_F1 := $(sort $(wildcard $(ZSTD_FILES))) -ZSTD_OBJ1 := $(subst $(ZSTDDIR)/common/,zstdm_,$(ZSTD_F1)) -ZSTD_OBJ2 := $(subst $(ZSTDDIR)/compress/,zstdc_,$(ZSTD_OBJ1)) -ZSTD_OBJ3 := $(subst $(ZSTDDIR)/decompress/,zstdd_,$(ZSTD_OBJ2)) -ZSTD_OBJ4 := $(ZSTD_OBJ3:.c=.o) -ZSTD_OBJECTS := $(ZSTD_OBJ4:.S=.o) +ZSTD_OBJ1 := $(subst $(LIB_SRCDIR)/common/,zstdm_,$(ZSTD_F1)) +ZSTD_OBJ2 := $(subst $(LIB_SRCDIR)/compress/,zstdc_,$(ZSTD_OBJ1)) +ZSTD_OBJ3 := $(subst $(LIB_SRCDIR)/decompress/,zstdd_,$(ZSTD_OBJ2)) +ZSTD_OBJ4 := $(subst $(LIB_SRCDIR)/legacy/,zstdl_,$(ZSTD_OBJ3)) +ZSTD_OBJ5 := $(ZSTD_OBJ4:.c=.o) +ZSTD_OBJECTS := $(ZSTD_OBJ5:.S=.o) -ZSTDMT_OBJ1 := $(subst $(ZSTDDIR)/common/,zstdmt_m_,$(ZSTD_F1)) -ZSTDMT_OBJ2 := $(subst $(ZSTDDIR)/compress/,zstdmt_c_,$(ZSTDMT_OBJ1)) -ZSTDMT_OBJ3 := $(subst $(ZSTDDIR)/decompress/,zstdmt_d_,$(ZSTDMT_OBJ2)) -ZSTDMT_OBJ4 := $(ZSTDMT_OBJ3:.c=.o) -ZSTDMT_OBJECTS := $(ZSTDMT_OBJ4:.S=.o) +ZSTDMT_OBJ1 := $(subst $(LIB_SRCDIR)/common/,zstdmt_m_,$(ZSTD_F1)) +ZSTDMT_OBJ2 := $(subst $(LIB_SRCDIR)/compress/,zstdmt_c_,$(ZSTDMT_OBJ1)) +ZSTDMT_OBJ3 := $(subst $(LIB_SRCDIR)/decompress/,zstdmt_d_,$(ZSTDMT_OBJ2)) +ZSTDMT_OBJ4 := $(subst $(LIB_SRCDIR)/legacy/,zstdmt_l_,$(ZSTDMT_OBJ3)) +ZSTDMT_OBJ5 := $(ZSTDMT_OBJ4:.c=.o) +ZSTDMT_OBJECTS := $(ZSTDMT_OBJ5:.S=.o) # Define *.exe as extension for Windows systems ifneq (,$(filter Windows%,$(OS))) @@ -95,45 +97,51 @@ allnothread: fullbench fuzzer paramgrill datagen decodecorpus dll: fuzzer-dll zstreamtest-dll .PHONY: zstd zstd32 zstd-nolegacy # only external makefile knows how to build or update them -zstd zstd32 zstd-nolegacy: +zstd zstd32 zstd-nolegacy zstd-dll: $(MAKE) -C $(PRGDIR) $@ MOREFLAGS+="$(DEBUGFLAGS)" .PHONY: libzstd libzstd : - $(MAKE) -C $(ZSTDDIR) libzstd MOREFLAGS+="$(DEBUGFLAGS)" + $(MAKE) -C $(LIB_SRCDIR) libzstd MOREFLAGS+="$(DEBUGFLAGS)" %-dll : libzstd -%-dll : LDFLAGS += -L$(ZSTDDIR) -lzstd +%-dll : LDFLAGS += -L$(LIB_BINDIR) -lzstd -$(ZSTDDIR)/libzstd.a : - $(MAKE) -C $(ZSTDDIR) libzstd.a +$(LIB_BINDIR)/libzstd.a : + $(MAKE) -C $(LIB_SRCDIR) libzstd.a -zstdm_%.o : $(ZSTDDIR)/common/%.c +zstdm_%.o : $(LIB_SRCDIR)/common/%.c $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ -zstdc_%.o : $(ZSTDDIR)/compress/%.c +zstdc_%.o : $(LIB_SRCDIR)/compress/%.c $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ -zstdd_%.o : $(ZSTDDIR)/decompress/%.c +zstdd_%.o : $(LIB_SRCDIR)/decompress/%.c $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ -zstdd_%.o : $(ZSTDDIR)/decompress/%.S +zstdd_%.o : $(LIB_SRCDIR)/decompress/%.S $(CC) -c $(CPPFLAGS) $(ASFLAGS) $< -o $@ +zstdl_%.o : $(LIB_SRCDIR)/legacy/%.c + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + zstdmt%.o : CPPFLAGS += $(MULTITHREAD_CPP) -zstdmt_m_%.o : $(ZSTDDIR)/common/%.c +zstdmt_m_%.o : $(LIB_SRCDIR)/common/%.c $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ -zstdmt_c_%.o : $(ZSTDDIR)/compress/%.c +zstdmt_c_%.o : $(LIB_SRCDIR)/compress/%.c $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ -zstdmt_d_%.o : $(ZSTDDIR)/decompress/%.c +zstdmt_d_%.o : $(LIB_SRCDIR)/decompress/%.c $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ -zstdmt_d_%.o : $(ZSTDDIR)/decompress/%.S +zstdmt_d_%.o : $(LIB_SRCDIR)/decompress/%.S $(CC) -c $(CPPFLAGS) $(ASFLAGS) $< -o $@ +zstdmt_l_%.o : $(LIB_SRCDIR)/legacy/%.c + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + FULLBENCHS := fullbench fullbench32 CLEAN += $(FULLBENCHS) fullbench32: CPPFLAGS += -m32 @@ -146,12 +154,12 @@ $(FULLBENCHS) : $(PRGDIR)/datagen.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR CLEAN += fullbench-lib fullbench-lib : CPPFLAGS += -DXXH_NAMESPACE=ZSTD_ -fullbench-lib : $(PRGDIR)/datagen.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/benchfn.c $(ZSTDDIR)/libzstd.a fullbench.c +fullbench-lib : $(PRGDIR)/datagen.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/benchfn.c $(LIB_SRCDIR)/libzstd.a fullbench.c $(LINK.c) $^ -o $@$(EXT) # note : broken : requires symbols unavailable from dynamic library fullbench-dll: $(PRGDIR)/datagen.c $(PRGDIR)/util.c $(PRGDIR)/benchfn.c $(PRGDIR)/timefn.c fullbench.c -# $(CC) $(FLAGS) $(filter %.c,$^) -o $@$(EXT) -DZSTD_DLL_IMPORT=1 $(ZSTDDIR)/dll/libzstd.dll +# $(CC) $(FLAGS) $(filter %.c,$^) -o $@$(EXT) -DZSTD_DLL_IMPORT=1 $(LIB_SRCDIR)/dll/libzstd.dll $(LINK.c) $^ $(LDLIBS) -o $@$(EXT) CLEAN += fuzzer fuzzer32 @@ -165,7 +173,7 @@ fuzzer32 : $(ZSTD_FILES) $(LINK.c) $^ -o $@$(EXT) # note : broken : requires symbols unavailable from dynamic library -fuzzer-dll : $(ZSTDDIR)/common/xxhash.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/datagen.c fuzzer.c +fuzzer-dll : $(LIB_SRCDIR)/common/xxhash.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/datagen.c fuzzer.c $(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) $(LDFLAGS) -o $@$(EXT) CLEAN += zstreamtest zstreamtest32 @@ -196,17 +204,17 @@ zstreamtest_ubsan : $(ZSTREAMFILES) $(LINK.c) $(MULTITHREAD) $^ -o $@$(EXT) # note : broken : requires symbols unavailable from dynamic library -zstreamtest-dll : $(ZSTDDIR)/common/xxhash.c # xxh symbols not exposed from dll +zstreamtest-dll : $(LIB_SRCDIR)/common/xxhash.c # xxh symbols not exposed from dll zstreamtest-dll : $(ZSTREAM_LOCAL_FILES) $(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) $(LDFLAGS) -o $@$(EXT) CLEAN += paramgrill paramgrill : DEBUGFLAGS = # turn off debug for speed measurements paramgrill : LDLIBS += -lm -paramgrill : $(ZSTD_FILES) $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/benchfn.c $(PRGDIR)/benchzstd.c $(PRGDIR)/datagen.c paramgrill.c +paramgrill : $(ZSTD_FILES) $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/benchfn.c $(PRGDIR)/benchzstd.c $(PRGDIR)/datagen.c $(PRGDIR)/lorem.c paramgrill.c CLEAN += datagen -datagen : $(PRGDIR)/datagen.c datagencli.c +datagen : $(PRGDIR)/datagen.c $(PRGDIR)/lorem.c loremOut.c datagencli.c $(LINK.c) $^ -o $@$(EXT) CLEAN += roundTripCrash @@ -224,15 +232,15 @@ CLEAN += invalidDictionaries invalidDictionaries : $(ZSTD_OBJECTS) invalidDictionaries.c CLEAN += legacy -legacy : CPPFLAGS += -I$(ZSTDDIR)/legacy -UZSTD_LEGACY_SUPPORT -DZSTD_LEGACY_SUPPORT=4 -legacy : $(ZSTD_FILES) $(sort $(wildcard $(ZSTDDIR)/legacy/*.c)) legacy.c +legacy : CPPFLAGS += -UZSTD_LEGACY_SUPPORT -DZSTD_LEGACY_SUPPORT=4 +legacy : $(ZSTD_FILES) legacy.c CLEAN += decodecorpus decodecorpus : LDLIBS += -lm decodecorpus : $(filter-out zstdc_zstd_compress.o, $(ZSTD_OBJECTS)) $(ZDICT_FILES) $(PRGDIR)/util.c $(PRGDIR)/timefn.c decodecorpus.c CLEAN += poolTests -poolTests : $(PRGDIR)/util.c $(PRGDIR)/timefn.c poolTests.c $(ZSTDDIR)/common/pool.c $(ZSTDDIR)/common/threading.c $(ZSTDDIR)/common/zstd_common.c $(ZSTDDIR)/common/error_private.c +poolTests : $(PRGDIR)/util.c $(PRGDIR)/timefn.c poolTests.c $(LIB_SRCDIR)/common/pool.c $(LIB_SRCDIR)/common/threading.c $(LIB_SRCDIR)/common/zstd_common.c $(LIB_SRCDIR)/common/error_private.c $(LINK.c) $(MULTITHREAD) $^ -o $@$(EXT) .PHONY: versionsTest @@ -245,14 +253,15 @@ automated_benchmarking: clean # make checkTag : check that release tag corresponds to release version CLEAN += checkTag -checkTag.o : $(ZSTDDIR)/zstd.h +checkTag.o : $(LIB_SRCDIR)/zstd.h .PHONY: clean clean: - $(MAKE) -C $(ZSTDDIR) clean + $(MAKE) -C $(LIB_SRCDIR) clean $(MAKE) -C $(PRGDIR) clean - $(RM) -fR $(TESTARTEFACT) - $(RM) -rf tmp* # some test directories are named tmp* + $(MAKE) -C fuzz clean + $(RM) -R $(TESTARTEFACT) + $(RM) -r tmp* # some test directories are named tmp* $(RM) $(CLEAN) core *.o *.tmp result* *.gcda dictionary *.zst \ $(PRGDIR)/zstd$(EXT) $(PRGDIR)/zstd32$(EXT) \ fullbench-dll$(EXT) fuzzer-dll$(EXT) zstreamtest-dll$(EXT) @@ -263,7 +272,7 @@ clean: # valgrind tests validated only for some posix platforms #---------------------------------------------------------------------------------- UNAME := $(shell uname) -ifneq (,$(filter $(UNAME),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS AIX)) +ifneq (,$(filter $(UNAME),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS AIX CYGWIN_NT)) HOST_OS = POSIX .PHONY: test-valgrind @@ -313,7 +322,7 @@ check: shortest fuzztest: test-fuzzer test-zstream test-decodecorpus .PHONY: test -test: test-zstd test-fullbench test-fuzzer test-zstream test-invalidDictionaries test-legacy test-decodecorpus test-cli-tests +test: test-zstd test-cli-tests test-fullbench test-fuzzer test-zstream test-invalidDictionaries test-legacy test-decodecorpus ifeq ($(QEMU_SYS),) test: test-pool endif @@ -328,13 +337,17 @@ test-all: test test32 test-decodecorpus-cli test-zstd: ZSTD = $(PRGDIR)/zstd test-zstd: zstd +.PHONY: test-zstd-dll +test-zstd-dll: ZSTD = $(PRGDIR)/zstd +test-zstd-dll: zstd-dll + test-zstd32: ZSTD = $(PRGDIR)/zstd32 test-zstd32: zstd32 test-zstd-nolegacy: ZSTD = $(PRGDIR)/zstd-nolegacy test-zstd-nolegacy: zstd-nolegacy -test-zstd test-zstd32 test-zstd-nolegacy: datagen +test-zstd test-zstd32 test-zstd-nolegacy test-zstd-dll: datagen file $(ZSTD) EXE_PREFIX="$(QEMU_SYS)" ZSTD_BIN="$(ZSTD)" DATAGEN_BIN=./datagen ./playTests.sh $(ZSTDRTTEST) diff --git a/src/dependencies/zstd-1.5.4/tests/README.md b/src/dependencies/zstd-1.5.6/tests/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/README.md rename to src/dependencies/zstd-1.5.6/tests/README.md diff --git a/src/dependencies/zstd-1.5.4/tests/automated_benchmarking.py b/src/dependencies/zstd-1.5.6/tests/automated_benchmarking.py similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/automated_benchmarking.py rename to src/dependencies/zstd-1.5.6/tests/automated_benchmarking.py diff --git a/src/dependencies/zstd-1.5.4/tests/bigdict.c b/src/dependencies/zstd-1.5.6/tests/bigdict.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/bigdict.c rename to src/dependencies/zstd-1.5.6/tests/bigdict.c diff --git a/src/dependencies/zstd-1.5.4/tests/checkTag.c b/src/dependencies/zstd-1.5.6/tests/checkTag.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/checkTag.c rename to src/dependencies/zstd-1.5.6/tests/checkTag.c diff --git a/src/dependencies/zstd-1.5.4/tests/check_size.py b/src/dependencies/zstd-1.5.6/tests/check_size.py similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/check_size.py rename to src/dependencies/zstd-1.5.6/tests/check_size.py diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/.gitignore b/src/dependencies/zstd-1.5.6/tests/cli-tests/.gitignore similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/.gitignore rename to src/dependencies/zstd-1.5.6/tests/cli-tests/.gitignore diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/README.md b/src/dependencies/zstd-1.5.6/tests/cli-tests/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/README.md rename to src/dependencies/zstd-1.5.6/tests/cli-tests/README.md diff --git a/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/args.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/args.sh new file mode 100755 index 0000000..9433101 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/args.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +println "+ zstd --blah" >&2 +zstd --blah +println "+ zstd -xz" >&2 +zstd -xz +println "+ zstd --adapt=min=1,maxx=2 file.txt" >&2 +zstd --adapt=min=1,maxx=2 file.txt +println "+ zstd --train-cover=k=48,d=8,steps32 file.txt" >&2 +zstd --train-cover=k=48,d=8,steps32 file.txt diff --git a/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/args.sh.exit b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/args.sh.exit new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/args.sh.exit @@ -0,0 +1 @@ +1 diff --git a/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/args.sh.stderr.glob b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/args.sh.stderr.glob new file mode 100644 index 0000000..df27547 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/args.sh.stderr.glob @@ -0,0 +1,28 @@ ++ zstd --blah +Incorrect parameter: --blah +... +Usage: zstd * + +Options: +... ++ zstd -xz +Incorrect parameter: -x +... +Usage: zstd * + +Options: +... ++ zstd --adapt=min=1,maxx=2 file.txt +Incorrect parameter: --adapt=min=1,maxx=2 +... +Usage: zstd * + +Options: +... ++ zstd --train-cover=k=48,d=8,steps32 file.txt +Incorrect parameter: --train-cover=k=48,d=8,steps32 +... +Usage: zstd * + +Options: +... diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/basic/help.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/help.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/basic/help.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/basic/help.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/basic/help.sh.stdout.glob b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/help.sh.stdout.glob similarity index 97% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/basic/help.sh.stdout.glob rename to src/dependencies/zstd-1.5.6/tests/cli-tests/basic/help.sh.stdout.glob index 5580dc6..21bc28c 100644 --- a/src/dependencies/zstd-1.5.4/tests/cli-tests/basic/help.sh.stdout.glob +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/help.sh.stdout.glob @@ -16,7 +16,7 @@ Options: -D DICT Use DICT as the dictionary for compression or decompression. -f, --force Disable input and output checks. Allows overwriting existing files, - receiving input from the console, printing ouput to STDOUT, and + receiving input from the console, printing output to STDOUT, and operating on links, block devices, etc. Unrecognized formats will be passed-through through as-is. diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/basic/memlimit.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/memlimit.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/basic/memlimit.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/basic/memlimit.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/basic/memlimit.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/memlimit.sh.stderr.exact similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/basic/memlimit.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/basic/memlimit.sh.stderr.exact diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/basic/memlimit.sh.stdout.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/memlimit.sh.stdout.exact similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/basic/memlimit.sh.stdout.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/basic/memlimit.sh.stdout.exact diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/basic/output_dir.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/output_dir.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/basic/output_dir.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/basic/output_dir.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/basic/output_dir.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/output_dir.sh.stderr.exact similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/basic/output_dir.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/basic/output_dir.sh.stderr.exact diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/basic/output_dir.sh.stdout.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/output_dir.sh.stdout.exact similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/basic/output_dir.sh.stdout.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/basic/output_dir.sh.stdout.exact diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/basic/version.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/version.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/basic/version.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/basic/version.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/basic/version.sh.stdout.glob b/src/dependencies/zstd-1.5.6/tests/cli-tests/basic/version.sh.stdout.glob similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/basic/version.sh.stdout.glob rename to src/dependencies/zstd-1.5.6/tests/cli-tests/basic/version.sh.stdout.glob diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/bin/cmp_size b/src/dependencies/zstd-1.5.6/tests/cli-tests/bin/cmp_size similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/bin/cmp_size rename to src/dependencies/zstd-1.5.6/tests/cli-tests/bin/cmp_size diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/bin/datagen b/src/dependencies/zstd-1.5.6/tests/cli-tests/bin/datagen similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/bin/datagen rename to src/dependencies/zstd-1.5.6/tests/cli-tests/bin/datagen diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/bin/die b/src/dependencies/zstd-1.5.6/tests/cli-tests/bin/die similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/bin/die rename to src/dependencies/zstd-1.5.6/tests/cli-tests/bin/die diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/bin/println b/src/dependencies/zstd-1.5.6/tests/cli-tests/bin/println similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/bin/println rename to src/dependencies/zstd-1.5.6/tests/cli-tests/bin/println diff --git a/src/dependencies/zstd-1.5.6/tests/cli-tests/bin/unzstd b/src/dependencies/zstd-1.5.6/tests/cli-tests/bin/unzstd new file mode 120000 index 0000000..613f917 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/bin/unzstd @@ -0,0 +1 @@ +zstd \ No newline at end of file diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/bin/zstd b/src/dependencies/zstd-1.5.6/tests/cli-tests/bin/zstd similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/bin/zstd rename to src/dependencies/zstd-1.5.6/tests/cli-tests/bin/zstd diff --git a/src/dependencies/zstd-1.5.6/tests/cli-tests/bin/zstdcat b/src/dependencies/zstd-1.5.6/tests/cli-tests/bin/zstdcat new file mode 120000 index 0000000..613f917 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/bin/zstdcat @@ -0,0 +1 @@ +zstd \ No newline at end of file diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/bin/zstdgrep b/src/dependencies/zstd-1.5.6/tests/cli-tests/bin/zstdgrep similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/bin/zstdgrep rename to src/dependencies/zstd-1.5.6/tests/cli-tests/bin/zstdgrep diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/bin/zstdless b/src/dependencies/zstd-1.5.6/tests/cli-tests/bin/zstdless similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/bin/zstdless rename to src/dependencies/zstd-1.5.6/tests/cli-tests/bin/zstdless diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/cltools/setup b/src/dependencies/zstd-1.5.6/tests/cli-tests/cltools/setup similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/cltools/setup rename to src/dependencies/zstd-1.5.6/tests/cli-tests/cltools/setup diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/cltools/zstdgrep.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/cltools/zstdgrep.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/cltools/zstdgrep.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/cltools/zstdgrep.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/cltools/zstdgrep.sh.exit b/src/dependencies/zstd-1.5.6/tests/cli-tests/cltools/zstdgrep.sh.exit similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/cltools/zstdgrep.sh.exit rename to src/dependencies/zstd-1.5.6/tests/cli-tests/cltools/zstdgrep.sh.exit diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/cltools/zstdgrep.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/cltools/zstdgrep.sh.stderr.exact similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/cltools/zstdgrep.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/cltools/zstdgrep.sh.stderr.exact diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/cltools/zstdgrep.sh.stdout.glob b/src/dependencies/zstd-1.5.6/tests/cli-tests/cltools/zstdgrep.sh.stdout.glob similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/cltools/zstdgrep.sh.stdout.glob rename to src/dependencies/zstd-1.5.6/tests/cli-tests/cltools/zstdgrep.sh.stdout.glob diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/cltools/zstdless.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/cltools/zstdless.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/cltools/zstdless.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/cltools/zstdless.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/cltools/zstdless.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/cltools/zstdless.sh.stderr.exact similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/cltools/zstdless.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/cltools/zstdless.sh.stderr.exact diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/cltools/zstdless.sh.stdout.glob b/src/dependencies/zstd-1.5.6/tests/cli-tests/cltools/zstdless.sh.stdout.glob similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/cltools/zstdless.sh.stdout.glob rename to src/dependencies/zstd-1.5.6/tests/cli-tests/cltools/zstdless.sh.stdout.glob diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/common/format.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/common/format.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/common/format.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/common/format.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/common/mtime.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/common/mtime.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/common/mtime.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/common/mtime.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/common/permissions.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/common/permissions.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/common/permissions.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/common/permissions.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/common/platform.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/common/platform.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/common/platform.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/common/platform.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/adapt.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/adapt.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/adapt.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/adapt.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/basic.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/basic.sh similarity index 82% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/basic.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/basic.sh index b6e2aa0..950c5a4 100755 --- a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/basic.sh +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/basic.sh @@ -25,8 +25,10 @@ zstd --stdout file | zstd -t println bob | zstd | zstd -t # Test keeping input file when compressing to stdout in gzip mode -$ZSTD_SYMLINK_DIR/gzip -c file | zstd -t ; test -f file -$ZSTD_SYMLINK_DIR/gzip --stdout file | zstd -t ; test -f file +if $(command -v $ZSTD_SYMLINK_DIR/gzip); then + $ZSTD_SYMLINK_DIR/gzip -c file | zstd -t ; test -f file + $ZSTD_SYMLINK_DIR/gzip --stdout file | zstd -t ; test -f file +fi # Test --rm cp file file-rm diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/compress-literals.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/compress-literals.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/compress-literals.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/compress-literals.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/format.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/format.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/format.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/format.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/golden.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/golden.sh similarity index 68% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/golden.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/golden.sh index 85dd3fd..458be9d 100755 --- a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/golden.sh +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/golden.sh @@ -10,3 +10,7 @@ zstd -r -t golden-compressed/ zstd --target-compressed-block-size=1024 -rf golden/ --output-dir-mirror golden-compressed/ zstd -r -t golden-compressed/ + +# PR #3517 block splitter corruption test +zstd -rf -19 --zstd=mml=7 golden/ --output-dir-mirror golden-compressed/ +zstd -r -t golden-compressed/ \ No newline at end of file diff --git a/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/gzip-compat.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/gzip-compat.sh new file mode 100755 index 0000000..b628b35 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/gzip-compat.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +set -e + +# Uncomment the set -v line for debugging +# set -v + +# Test gzip specific compression option +if $(command -v $ZSTD_SYMLINK_DIR/gzip); then + $ZSTD_SYMLINK_DIR/gzip --fast file ; $ZSTD_SYMLINK_DIR/gzip -d file.gz + $ZSTD_SYMLINK_DIR/gzip --best file ; $ZSTD_SYMLINK_DIR/gzip -d file.gz + + # Test -n / --no-name: do not embed original filename in archive + $ZSTD_SYMLINK_DIR/gzip -n file ; grep -qv file file.gz ; $ZSTD_SYMLINK_DIR/gzip -d file.gz + $ZSTD_SYMLINK_DIR/gzip --no-name file ; grep -qv file file.gz ; $ZSTD_SYMLINK_DIR/gzip -d file.gz + $ZSTD_SYMLINK_DIR/gzip -c --no-name file | grep -qv file +fi diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/levels.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/levels.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/levels.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/levels.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/levels.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/levels.sh.stderr.exact similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/levels.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/levels.sh.stderr.exact diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/long-distance-matcher.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/long-distance-matcher.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/long-distance-matcher.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/long-distance-matcher.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/multi-threaded.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/multi-threaded.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/multi-threaded.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/multi-threaded.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/multi-threaded.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/multi-threaded.sh.stderr.exact similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/multi-threaded.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/multi-threaded.sh.stderr.exact diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/multiple-files.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/multiple-files.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/multiple-files.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/multiple-files.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/multiple-files.sh.stdout.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/multiple-files.sh.stdout.exact similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/multiple-files.sh.stdout.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/multiple-files.sh.stdout.exact diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/row-match-finder.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/row-match-finder.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/row-match-finder.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/row-match-finder.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/setup b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/setup similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/setup rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/setup diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/stream-size.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/stream-size.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/stream-size.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/stream-size.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/verbose-wlog.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/verbose-wlog.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/verbose-wlog.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/verbose-wlog.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/verbose-wlog.sh.stderr.glob b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/verbose-wlog.sh.stderr.glob similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/verbose-wlog.sh.stderr.glob rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/verbose-wlog.sh.stderr.glob diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/verbose-wlog.sh.stdout.glob b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/verbose-wlog.sh.stdout.glob similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/verbose-wlog.sh.stdout.glob rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/verbose-wlog.sh.stdout.glob diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/window-resize.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/window-resize.sh similarity index 75% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/window-resize.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/window-resize.sh index 3b5e6fe..e4fe811 100755 --- a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/window-resize.sh +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/window-resize.sh @@ -1,6 +1,6 @@ #!/bin/sh datagen -g1G > file -zstd --long=31 -1 --single-thread --no-content-size -f file +zstd --long=30 -1 --single-thread --no-content-size -f file zstd -l -v file.zst # We want to ignore stderr (its outputting "*** zstd command line interface diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/window-resize.sh.stderr.ignore b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/window-resize.sh.stderr.ignore similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/window-resize.sh.stderr.ignore rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/window-resize.sh.stderr.ignore diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/compression/window-resize.sh.stdout.glob b/src/dependencies/zstd-1.5.6/tests/cli-tests/compression/window-resize.sh.stdout.glob similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/compression/window-resize.sh.stdout.glob rename to src/dependencies/zstd-1.5.6/tests/cli-tests/compression/window-resize.sh.stdout.glob diff --git a/src/dependencies/zstd-1.5.6/tests/cli-tests/decompression/detectErrors.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/decompression/detectErrors.sh new file mode 100755 index 0000000..300cde3 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/decompression/detectErrors.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +set -e + +GOLDEN_DIR="$ZSTD_REPO_DIR/tests/golden-decompression-errors/" + +for file in "$GOLDEN_DIR"/*; do + zstd -t $file && die "should have detected an error" +done +exit 0 + diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/decompression/golden.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/decompression/golden.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/decompression/golden.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/decompression/golden.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/decompression/pass-through.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/decompression/pass-through.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/decompression/pass-through.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/decompression/pass-through.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/decompression/pass-through.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/decompression/pass-through.sh.stderr.exact similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/decompression/pass-through.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/decompression/pass-through.sh.stderr.exact diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/decompression/pass-through.sh.stdout.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/decompression/pass-through.sh.stdout.exact similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/decompression/pass-through.sh.stdout.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/decompression/pass-through.sh.stdout.exact diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/dict-builder/empty-input.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/dict-builder/empty-input.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/dict-builder/empty-input.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/dict-builder/empty-input.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/dict-builder/empty-input.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/dict-builder/empty-input.sh.stderr.exact similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/dict-builder/empty-input.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/dict-builder/empty-input.sh.stderr.exact diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/dict-builder/no-inputs.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/dict-builder/no-inputs.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/dict-builder/no-inputs.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/dict-builder/no-inputs.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/dict-builder/no-inputs.sh.exit b/src/dependencies/zstd-1.5.6/tests/cli-tests/dict-builder/no-inputs.sh.exit similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/dict-builder/no-inputs.sh.exit rename to src/dependencies/zstd-1.5.6/tests/cli-tests/dict-builder/no-inputs.sh.exit diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/dict-builder/no-inputs.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/dict-builder/no-inputs.sh.stderr.exact similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/dict-builder/no-inputs.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/dict-builder/no-inputs.sh.stderr.exact diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/dictionaries/dictionary-mismatch.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/dictionaries/dictionary-mismatch.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/dictionaries/dictionary-mismatch.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/dictionaries/dictionary-mismatch.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/dictionaries/dictionary-mismatch.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/dictionaries/dictionary-mismatch.sh.stderr.exact similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/dictionaries/dictionary-mismatch.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/dictionaries/dictionary-mismatch.sh.stderr.exact diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/dictionaries/golden.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/dictionaries/golden.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/dictionaries/golden.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/dictionaries/golden.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/dictionaries/setup b/src/dependencies/zstd-1.5.6/tests/cli-tests/dictionaries/setup similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/dictionaries/setup rename to src/dependencies/zstd-1.5.6/tests/cli-tests/dictionaries/setup diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/dictionaries/setup_once b/src/dependencies/zstd-1.5.6/tests/cli-tests/dictionaries/setup_once similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/dictionaries/setup_once rename to src/dependencies/zstd-1.5.6/tests/cli-tests/dictionaries/setup_once diff --git a/src/dependencies/zstd-1.5.6/tests/cli-tests/file-handling/directory-mirror.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-handling/directory-mirror.sh new file mode 100755 index 0000000..b2f70b5 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-handling/directory-mirror.sh @@ -0,0 +1,49 @@ +#!/bin/sh +set -e + +# setup +mkdir -p src/.hidden src/dir +mkdir mid dst + +echo "file1" > src/file1 +echo "file2" > src/.file2 +echo "file3" > src/.hidden/.file3 +echo "file4" > src/dir/.file4 + +# relative paths +zstd -q -r --output-dir-mirror mid/ src/ +zstd -q -d -r --output-dir-mirror dst/ mid/src/ + +diff --brief --recursive --new-file src/ dst/mid/src/ + +# reset +rm -rf mid dst +mkdir mid dst + +# from inside the directory +(cd src; zstd -q -r --output-dir-mirror ../mid/ ./) +(cd mid; zstd -q -d -r --output-dir-mirror ../dst/ ./) + +diff --brief --recursive --new-file src/ dst/ + +# reset +rm -rf mid dst +mkdir mid dst + +# absolute paths +export BASE_PATH="$(pwd)" + +zstd -q -r --output-dir-mirror mid/ "${BASE_PATH}/src/" +zstd -q -d -r --output-dir-mirror dst/ "${BASE_PATH}/mid/${BASE_PATH}/src/" + +diff --brief --recursive --new-file src/ "dst/${BASE_PATH}/mid/${BASE_PATH}/src/" + +# reset +rm -rf mid dst +mkdir mid dst + +# dots +zstd -q -r --output-dir-mirror mid/ ./src/./ +zstd -q -d -r --output-dir-mirror dst/ ./mid/./src/./ + +diff --brief --recursive --new-file src/ dst/mid/src/ diff --git a/src/dependencies/zstd-1.5.4/build/LICENSE b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-handling/directory-mirror.sh.stderr.exact similarity index 100% rename from src/dependencies/zstd-1.5.4/build/LICENSE rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-handling/directory-mirror.sh.stderr.exact diff --git a/src/dependencies/zstd-1.5.6/tests/cli-tests/file-handling/directory-mirror.sh.stdout.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-handling/directory-mirror.sh.stdout.exact new file mode 100644 index 0000000..e69de29 diff --git a/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-file-to-dir-without-write-perm.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-file-to-dir-without-write-perm.sh new file mode 100755 index 0000000..1aa4525 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-file-to-dir-without-write-perm.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +# motivated by issue #3523 + +datagen > file +mkdir out +chmod 000 out + +zstd file -q --trace-file-stat -o out/file.zst +zstd -tq out/file.zst + +chmod 777 out diff --git a/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-file-to-dir-without-write-perm.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-file-to-dir-without-write-perm.sh.stderr.exact new file mode 100644 index 0000000..95deaf2 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-file-to-dir-without-write-perm.sh.stderr.exact @@ -0,0 +1,26 @@ +Trace:FileStat: > UTIL_isLink(file) +Trace:FileStat: < 0 +Trace:FileStat: > UTIL_isConsole(2) +Trace:FileStat: < 0 +Trace:FileStat: > UTIL_getFileSize(file) +Trace:FileStat: > UTIL_stat(-1, file) +Trace:FileStat: < 1 +Trace:FileStat: < 65537 +Trace:FileStat: > UTIL_stat(-1, file) +Trace:FileStat: < 1 +Trace:FileStat: > UTIL_isDirectoryStat() +Trace:FileStat: < 0 +Trace:FileStat: > UTIL_stat(-1, file) +Trace:FileStat: < 1 +Trace:FileStat: > UTIL_isSameFile(file, out/file.zst) +Trace:FileStat: > UTIL_stat(-1, file) +Trace:FileStat: < 1 +Trace:FileStat: > UTIL_stat(-1, out/file.zst) +Trace:FileStat: < 0 +Trace:FileStat: < 0 +Trace:FileStat: > UTIL_isRegularFile(out/file.zst) +Trace:FileStat: > UTIL_stat(-1, out/file.zst) +Trace:FileStat: < 0 +Trace:FileStat: < 0 +zstd: out/file.zst: Permission denied +zstd: can't stat out/file.zst : Permission denied -- ignored diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-file-to-file.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-file-to-file.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-file-to-file.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-file-to-file.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-file-to-file.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-file-to-file.sh.stderr.exact similarity index 61% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-file-to-file.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-file-to-file.sh.stderr.exact index a1ad09e..32d248e 100644 --- a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-file-to-file.sh.stderr.exact +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-file-to-file.sh.stderr.exact @@ -3,40 +3,40 @@ Trace:FileStat: < 0 Trace:FileStat: > UTIL_isConsole(2) Trace:FileStat: < 0 Trace:FileStat: > UTIL_getFileSize(file) -Trace:FileStat: > UTIL_stat(file) +Trace:FileStat: > UTIL_stat(-1, file) Trace:FileStat: < 1 Trace:FileStat: < 65537 -Trace:FileStat: > UTIL_stat(file) +Trace:FileStat: > UTIL_stat(-1, file) Trace:FileStat: < 1 Trace:FileStat: > UTIL_isDirectoryStat() Trace:FileStat: < 0 -Trace:FileStat: > UTIL_stat(file) +Trace:FileStat: > UTIL_stat(-1, file) Trace:FileStat: < 1 Trace:FileStat: > UTIL_isSameFile(file, file.zst) -Trace:FileStat: > UTIL_stat(file) +Trace:FileStat: > UTIL_stat(-1, file) Trace:FileStat: < 1 -Trace:FileStat: > UTIL_stat(file.zst) +Trace:FileStat: > UTIL_stat(-1, file.zst) Trace:FileStat: < 0 Trace:FileStat: < 0 Trace:FileStat: > UTIL_isRegularFile(file.zst) -Trace:FileStat: > UTIL_stat(file.zst) +Trace:FileStat: > UTIL_stat(-1, file.zst) Trace:FileStat: < 0 Trace:FileStat: < 0 Trace:FileStat: > UTIL_isRegularFile(file.zst) -Trace:FileStat: > UTIL_stat(file.zst) +Trace:FileStat: > UTIL_stat(-1, file.zst) Trace:FileStat: < 1 Trace:FileStat: < 1 Trace:FileStat: > UTIL_getFileSize(file) -Trace:FileStat: > UTIL_stat(file) +Trace:FileStat: > UTIL_stat(-1, file) Trace:FileStat: < 1 Trace:FileStat: < 65537 -Trace:FileStat: > UTIL_setFileStat(file.zst) -Trace:FileStat: > UTIL_stat(file.zst) +Trace:FileStat: > UTIL_setFileStat(4, file.zst) +Trace:FileStat: > UTIL_stat(4, file.zst) Trace:FileStat: < 1 -Trace:FileStat: > UTIL_utime(file.zst) -Trace:FileStat: < 0 Trace:FileStat: > UTIL_chmod(file.zst, 0642) -Trace:FileStat: > chmod +Trace:FileStat: > fchmod Trace:FileStat: < 0 Trace:FileStat: < 0 Trace:FileStat: < 0 +Trace:FileStat: > UTIL_utime(file.zst) +Trace:FileStat: < 0 diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-file-to-stdout.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-file-to-stdout.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-file-to-stdout.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-file-to-stdout.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-file-to-stdout.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-file-to-stdout.sh.stderr.exact similarity index 72% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-file-to-stdout.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-file-to-stdout.sh.stderr.exact index 7c690d2..a25a355 100644 --- a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-file-to-stdout.sh.stderr.exact +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-file-to-stdout.sh.stderr.exact @@ -5,20 +5,20 @@ Trace:FileStat: < 0 Trace:FileStat: > UTIL_isConsole(2) Trace:FileStat: < 0 Trace:FileStat: > UTIL_getFileSize(file) -Trace:FileStat: > UTIL_stat(file) +Trace:FileStat: > UTIL_stat(-1, file) Trace:FileStat: < 1 Trace:FileStat: < 65537 -Trace:FileStat: > UTIL_stat(file) +Trace:FileStat: > UTIL_stat(-1, file) Trace:FileStat: < 1 Trace:FileStat: > UTIL_isDirectoryStat() Trace:FileStat: < 0 -Trace:FileStat: > UTIL_stat(file) +Trace:FileStat: > UTIL_stat(-1, file) Trace:FileStat: < 1 Trace:FileStat: > UTIL_isRegularFile(/*stdout*\) -Trace:FileStat: > UTIL_stat(/*stdout*\) +Trace:FileStat: > UTIL_stat(-1, /*stdout*\) Trace:FileStat: < 0 Trace:FileStat: < 0 Trace:FileStat: > UTIL_getFileSize(file) -Trace:FileStat: > UTIL_stat(file) +Trace:FileStat: > UTIL_stat(-1, file) Trace:FileStat: < 1 Trace:FileStat: < 65537 diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-stdin-to-file.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-stdin-to-file.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-stdin-to-file.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-stdin-to-file.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-stdin-to-file.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-stdin-to-file.sh.stderr.exact similarity index 71% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-stdin-to-file.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-stdin-to-file.sh.stderr.exact index 00afd97..9183c46 100644 --- a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-stdin-to-file.sh.stderr.exact +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-stdin-to-file.sh.stderr.exact @@ -3,22 +3,22 @@ Trace:FileStat: < 0 Trace:FileStat: > UTIL_isConsole(2) Trace:FileStat: < 0 Trace:FileStat: > UTIL_getFileSize(/*stdin*\) -Trace:FileStat: > UTIL_stat(/*stdin*\) +Trace:FileStat: > UTIL_stat(-1, /*stdin*\) Trace:FileStat: < 0 Trace:FileStat: < -1 Trace:FileStat: > UTIL_isSameFile(/*stdin*\, file.zst) -Trace:FileStat: > UTIL_stat(/*stdin*\) +Trace:FileStat: > UTIL_stat(-1, /*stdin*\) Trace:FileStat: < 0 Trace:FileStat: < 0 Trace:FileStat: > UTIL_isRegularFile(file.zst) -Trace:FileStat: > UTIL_stat(file.zst) +Trace:FileStat: > UTIL_stat(-1, file.zst) Trace:FileStat: < 0 Trace:FileStat: < 0 Trace:FileStat: > UTIL_isRegularFile(file.zst) -Trace:FileStat: > UTIL_stat(file.zst) +Trace:FileStat: > UTIL_stat(-1, file.zst) Trace:FileStat: < 1 Trace:FileStat: < 1 Trace:FileStat: > UTIL_getFileSize(/*stdin*\) -Trace:FileStat: > UTIL_stat(/*stdin*\) +Trace:FileStat: > UTIL_stat(-1, /*stdin*\) Trace:FileStat: < 0 Trace:FileStat: < -1 diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-stdin-to-stdout.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-stdin-to-stdout.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-stdin-to-stdout.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-stdin-to-stdout.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-stdin-to-stdout.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-stdin-to-stdout.sh.stderr.exact similarity index 76% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-stdin-to-stdout.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-stdin-to-stdout.sh.stderr.exact index 8bf05e6..66b630e 100644 --- a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/compress-stdin-to-stdout.sh.stderr.exact +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/compress-stdin-to-stdout.sh.stderr.exact @@ -5,14 +5,14 @@ Trace:FileStat: < 0 Trace:FileStat: > UTIL_isConsole(2) Trace:FileStat: < 0 Trace:FileStat: > UTIL_getFileSize(/*stdin*\) -Trace:FileStat: > UTIL_stat(/*stdin*\) +Trace:FileStat: > UTIL_stat(-1, /*stdin*\) Trace:FileStat: < 0 Trace:FileStat: < -1 Trace:FileStat: > UTIL_isRegularFile(/*stdout*\) -Trace:FileStat: > UTIL_stat(/*stdout*\) +Trace:FileStat: > UTIL_stat(-1, /*stdout*\) Trace:FileStat: < 0 Trace:FileStat: < 0 Trace:FileStat: > UTIL_getFileSize(/*stdin*\) -Trace:FileStat: > UTIL_stat(/*stdin*\) +Trace:FileStat: > UTIL_stat(-1, /*stdin*\) Trace:FileStat: < 0 Trace:FileStat: < -1 diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-file-to-file.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-file-to-file.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-file-to-file.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-file-to-file.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-file-to-file.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-file-to-file.sh.stderr.exact similarity index 64% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-file-to-file.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-file-to-file.sh.stderr.exact index d264c63..ad3a0de 100644 --- a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-file-to-file.sh.stderr.exact +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-file-to-file.sh.stderr.exact @@ -5,34 +5,34 @@ Trace:FileStat: < 0 Trace:FileStat: > UTIL_isConsole(2) Trace:FileStat: < 0 Trace:FileStat: > UTIL_isDirectory(file.zst) -Trace:FileStat: > UTIL_stat(file.zst) +Trace:FileStat: > UTIL_stat(-1, file.zst) Trace:FileStat: < 1 Trace:FileStat: > UTIL_isDirectoryStat() Trace:FileStat: < 0 Trace:FileStat: < 0 -Trace:FileStat: > UTIL_stat(file.zst) +Trace:FileStat: > UTIL_stat(-1, file.zst) Trace:FileStat: < 1 Trace:FileStat: > UTIL_isSameFile(file.zst, file) -Trace:FileStat: > UTIL_stat(file.zst) +Trace:FileStat: > UTIL_stat(-1, file.zst) Trace:FileStat: < 1 -Trace:FileStat: > UTIL_stat(file) +Trace:FileStat: > UTIL_stat(-1, file) Trace:FileStat: < 0 Trace:FileStat: < 0 Trace:FileStat: > UTIL_isRegularFile(file) -Trace:FileStat: > UTIL_stat(file) +Trace:FileStat: > UTIL_stat(-1, file) Trace:FileStat: < 0 Trace:FileStat: < 0 Trace:FileStat: > UTIL_isRegularFile(file) -Trace:FileStat: > UTIL_stat(file) +Trace:FileStat: > UTIL_stat(-1, file) Trace:FileStat: < 1 Trace:FileStat: < 1 -Trace:FileStat: > UTIL_setFileStat(file) -Trace:FileStat: > UTIL_stat(file) +Trace:FileStat: > UTIL_setFileStat(4, file) +Trace:FileStat: > UTIL_stat(4, file) Trace:FileStat: < 1 -Trace:FileStat: > UTIL_utime(file) -Trace:FileStat: < 0 Trace:FileStat: > UTIL_chmod(file, 0642) -Trace:FileStat: > chmod +Trace:FileStat: > fchmod Trace:FileStat: < 0 Trace:FileStat: < 0 Trace:FileStat: < 0 +Trace:FileStat: > UTIL_utime(file) +Trace:FileStat: < 0 diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-file-to-stdout.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-file-to-stdout.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-file-to-stdout.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-file-to-stdout.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-file-to-stdout.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-file-to-stdout.sh.stderr.exact similarity index 76% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-file-to-stdout.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-file-to-stdout.sh.stderr.exact index 7fe6dda..8b60063 100644 --- a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-file-to-stdout.sh.stderr.exact +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-file-to-stdout.sh.stderr.exact @@ -5,14 +5,14 @@ Trace:FileStat: < 0 Trace:FileStat: > UTIL_isConsole(2) Trace:FileStat: < 0 Trace:FileStat: > UTIL_isDirectory(file.zst) -Trace:FileStat: > UTIL_stat(file.zst) +Trace:FileStat: > UTIL_stat(-1, file.zst) Trace:FileStat: < 1 Trace:FileStat: > UTIL_isDirectoryStat() Trace:FileStat: < 0 Trace:FileStat: < 0 -Trace:FileStat: > UTIL_stat(file.zst) +Trace:FileStat: > UTIL_stat(-1, file.zst) Trace:FileStat: < 1 Trace:FileStat: > UTIL_isRegularFile(/*stdout*\) -Trace:FileStat: > UTIL_stat(/*stdout*\) +Trace:FileStat: > UTIL_stat(-1, /*stdout*\) Trace:FileStat: < 0 Trace:FileStat: < 0 diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-stdin-to-file.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-stdin-to-file.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-stdin-to-file.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-stdin-to-file.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-stdin-to-file.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-stdin-to-file.sh.stderr.exact similarity index 73% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-stdin-to-file.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-stdin-to-file.sh.stderr.exact index 749fd39..716a7ac 100644 --- a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-stdin-to-file.sh.stderr.exact +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-stdin-to-file.sh.stderr.exact @@ -3,18 +3,18 @@ Trace:FileStat: < 0 Trace:FileStat: > UTIL_isConsole(2) Trace:FileStat: < 0 Trace:FileStat: > UTIL_isDirectory(/*stdin*\) -Trace:FileStat: > UTIL_stat(/*stdin*\) +Trace:FileStat: > UTIL_stat(-1, /*stdin*\) Trace:FileStat: < 0 Trace:FileStat: < 0 Trace:FileStat: > UTIL_isSameFile(/*stdin*\, file) -Trace:FileStat: > UTIL_stat(/*stdin*\) +Trace:FileStat: > UTIL_stat(-1, /*stdin*\) Trace:FileStat: < 0 Trace:FileStat: < 0 Trace:FileStat: > UTIL_isRegularFile(file) -Trace:FileStat: > UTIL_stat(file) +Trace:FileStat: > UTIL_stat(-1, file) Trace:FileStat: < 0 Trace:FileStat: < 0 Trace:FileStat: > UTIL_isRegularFile(file) -Trace:FileStat: > UTIL_stat(file) +Trace:FileStat: > UTIL_stat(-1, file) Trace:FileStat: < 1 Trace:FileStat: < 1 diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-stdin-to-stdout.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-stdin-to-stdout.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-stdin-to-stdout.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-stdin-to-stdout.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-stdin-to-stdout.sh.stderr.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-stdin-to-stdout.sh.stderr.exact similarity index 79% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-stdin-to-stdout.sh.stderr.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-stdin-to-stdout.sh.stderr.exact index e36cb9d..2f64120 100644 --- a/src/dependencies/zstd-1.5.4/tests/cli-tests/file-stat/decompress-stdin-to-stdout.sh.stderr.exact +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/file-stat/decompress-stdin-to-stdout.sh.stderr.exact @@ -5,10 +5,10 @@ Trace:FileStat: < 0 Trace:FileStat: > UTIL_isConsole(2) Trace:FileStat: < 0 Trace:FileStat: > UTIL_isDirectory(/*stdin*\) -Trace:FileStat: > UTIL_stat(/*stdin*\) +Trace:FileStat: > UTIL_stat(-1, /*stdin*\) Trace:FileStat: < 0 Trace:FileStat: < 0 Trace:FileStat: > UTIL_isRegularFile(/*stdout*\) -Trace:FileStat: > UTIL_stat(/*stdout*\) +Trace:FileStat: > UTIL_stat(-1, /*stdout*\) Trace:FileStat: < 0 Trace:FileStat: < 0 diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/progress/no-progress.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/progress/no-progress.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/progress/no-progress.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/progress/no-progress.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/progress/no-progress.sh.stderr.glob b/src/dependencies/zstd-1.5.6/tests/cli-tests/progress/no-progress.sh.stderr.glob similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/progress/no-progress.sh.stderr.glob rename to src/dependencies/zstd-1.5.6/tests/cli-tests/progress/no-progress.sh.stderr.glob diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/progress/progress.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/progress/progress.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/progress/progress.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/progress/progress.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/progress/progress.sh.stderr.glob b/src/dependencies/zstd-1.5.6/tests/cli-tests/progress/progress.sh.stderr.glob similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/progress/progress.sh.stderr.glob rename to src/dependencies/zstd-1.5.6/tests/cli-tests/progress/progress.sh.stderr.glob diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/run.py b/src/dependencies/zstd-1.5.6/tests/cli-tests/run.py similarity index 98% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/run.py rename to src/dependencies/zstd-1.5.6/tests/cli-tests/run.py index 45af512..46564d2 100755 --- a/src/dependencies/zstd-1.5.4/tests/cli-tests/run.py +++ b/src/dependencies/zstd-1.5.6/tests/cli-tests/run.py @@ -109,25 +109,17 @@ def pop_line(data: bytes) -> typing.Tuple[typing.Optional[bytes], bytes]: the first line always ends in a :\n:, even if it is the last line and :data: doesn't end in :\n:. """ - NEWLINE = b"\n"[0] + NEWLINE = b"\n" if data == b'': return (None, data) - newline_idx = data.find(b"\n") - if newline_idx == -1: - end_idx = len(data) - else: - end_idx = newline_idx + 1 + parts = data.split(NEWLINE, maxsplit=1) + line = parts[0] + NEWLINE + if len(parts) == 1: + return line, b'' - line = data[:end_idx] - data = data[end_idx:] - - assert len(line) != 0 - if line[-1] != NEWLINE: - line += NEWLINE - - return (line, data) + return line, parts[1] def glob_line_matches(actual: bytes, expect: bytes) -> bool: @@ -535,7 +527,8 @@ class TestSuite: subprocess.run( args=[script], stdin=subprocess.DEVNULL, - capture_output=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, cwd=cwd, env=env, check=True, @@ -647,7 +640,7 @@ if __name__ == "__main__": help="Preserve the scratch directory TEST_DIR/scratch/ for debugging purposes." ) parser.add_argument("--verbose", action="store_true", help="Verbose test output.") - parser.add_argument("--timeout", default=60, type=int, help="Test case timeout in seconds. Set to 0 to disable timeouts.") + parser.add_argument("--timeout", default=200, type=int, help="Test case timeout in seconds. Set to 0 to disable timeouts.") parser.add_argument( "--exec-prefix", default=None, diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/zstd-symlinks/setup b/src/dependencies/zstd-1.5.6/tests/cli-tests/zstd-symlinks/setup similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/zstd-symlinks/setup rename to src/dependencies/zstd-1.5.6/tests/cli-tests/zstd-symlinks/setup diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/zstd-symlinks/zstdcat.sh b/src/dependencies/zstd-1.5.6/tests/cli-tests/zstd-symlinks/zstdcat.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/zstd-symlinks/zstdcat.sh rename to src/dependencies/zstd-1.5.6/tests/cli-tests/zstd-symlinks/zstdcat.sh diff --git a/src/dependencies/zstd-1.5.4/tests/cli-tests/zstd-symlinks/zstdcat.sh.stdout.exact b/src/dependencies/zstd-1.5.6/tests/cli-tests/zstd-symlinks/zstdcat.sh.stdout.exact similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/cli-tests/zstd-symlinks/zstdcat.sh.stdout.exact rename to src/dependencies/zstd-1.5.6/tests/cli-tests/zstd-symlinks/zstdcat.sh.stdout.exact diff --git a/src/dependencies/zstd-1.5.6/tests/datagencli.c b/src/dependencies/zstd-1.5.6/tests/datagencli.c new file mode 100644 index 0000000..56616be --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/datagencli.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/*-************************************ + * Dependencies + **************************************/ +#include /* fprintf, stderr */ +#include "datagen.h" /* RDG_generate */ +#include "loremOut.h" /* LOREM_genOut */ +#include "util.h" /* Compiler options */ + +/*-************************************ + * Constants + **************************************/ +#define KB *(1 << 10) +#define MB *(1 << 20) +#define GB *(1U << 30) + +#define SIZE_DEFAULT ((64 KB) + 1) +#define SEED_DEFAULT 0 +#define COMPRESSIBILITY_DEFAULT 9999 + +/*-************************************ + * Macros + **************************************/ +#define DISPLAY(...) fprintf(stderr, __VA_ARGS__) +#define DISPLAYLEVEL(l, ...) \ + if (displayLevel >= l) { \ + DISPLAY(__VA_ARGS__); \ + } +static unsigned displayLevel = 2; + +/*-******************************************************* + * Command line + *********************************************************/ +static int usage(const char* programName) +{ + DISPLAY("Compressible data generator\n"); + DISPLAY("Usage :\n"); + DISPLAY(" %s [args]\n", programName); + DISPLAY("\n"); + DISPLAY("Arguments :\n"); + DISPLAY(" -g# : generate # data (default:%i)\n", SIZE_DEFAULT); + DISPLAY(" -s# : Select seed (default:%i)\n", SEED_DEFAULT); + DISPLAY(" -P# : Select compressibility in %% (range [0-100])\n"); + DISPLAY(" -h : display help and exit\n"); + return 0; +} + +int main(int argc, const char** argv) +{ + unsigned probaU32 = COMPRESSIBILITY_DEFAULT; + double litProba = 0.0; + U64 size = SIZE_DEFAULT; + U32 seed = SEED_DEFAULT; + const char* const programName = argv[0]; + + int argNb; + for (argNb = 1; argNb < argc; argNb++) { + const char* argument = argv[argNb]; + + if (!argument) + continue; /* Protection if argument empty */ + + /* Handle commands. Aggregated commands are allowed */ + if (*argument == '-') { + argument++; + while (*argument != 0) { + switch (*argument) { + case 'h': + return usage(programName); + case 'g': + argument++; + size = 0; + while ((*argument >= '0') && (*argument <= '9')) + size *= 10, size += (U64)(*argument++ - '0'); + if (*argument == 'K') { + size <<= 10; + argument++; + } + if (*argument == 'M') { + size <<= 20; + argument++; + } + if (*argument == 'G') { + size <<= 30; + argument++; + } + if (*argument == 'B') { + argument++; + } + break; + case 's': + argument++; + seed = 0; + while ((*argument >= '0') && (*argument <= '9')) + seed *= 10, seed += (U32)(*argument++ - '0'); + break; + case 'P': + argument++; + probaU32 = 0; + while ((*argument >= '0') && (*argument <= '9')) + probaU32 *= 10, + probaU32 += (U32)(*argument++ - '0'); + if (probaU32 > 100) + probaU32 = 100; + break; + case 'L': /* hidden argument : Literal distribution + probability */ + argument++; + litProba = 0.; + while ((*argument >= '0') && (*argument <= '9')) + litProba *= 10, litProba += *argument++ - '0'; + if (litProba > 100.) + litProba = 100.; + litProba /= 100.; + break; + case 'v': + displayLevel = 4; + argument++; + break; + default: + return usage(programName); + } + } + } + } /* for(argNb=1; argNb (size_t)((BYTE*)srcPtr - (BYTE*)frame->srcStart))) || offset == 0); - { BYTE* const dictEnd = info.dictContent + info.dictContentSize; + { BYTE* const dictEnd = ZSTD_maybeNullPtrAdd(info.dictContent, info.dictContentSize); size_t j; for (j = 0; j < matchLen; j++) { if ((U32)((BYTE*)srcPtr - (BYTE*)frame->srcStart) < offset) { @@ -824,7 +825,7 @@ static size_t writeSequences(U32* seed, frame_t* frame, seqStore_t* seqStorePtr, /* Sequences Header */ if ((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead */) return ERROR(dstSize_tooSmall); - if (nbSeq < 0x7F) *op++ = (BYTE)nbSeq; + if (nbSeq < 128) *op++ = (BYTE)nbSeq; else if (nbSeq < LONGNBSEQ) op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2; else op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3; @@ -1434,7 +1435,7 @@ static size_t testDecodeWithDict(U32 seed, genType_e genType) ZSTD_freeDCtx(dctx); goto dictTestCleanup; } - ret = ZSTD_decompressBlock(dctx, DECOMPRESSED_BUFFER, MAX_DECOMPRESSED_SIZE, + ret = ZSTD_decompressBlock_deprecated(dctx, DECOMPRESSED_BUFFER, MAX_DECOMPRESSED_SIZE, fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart); } ZSTD_freeDCtx(dctx); @@ -1461,7 +1462,7 @@ static size_t testDecodeRawBlock(frame_t* fr) size_t ret = ZSTD_decompressBegin(dctx); if (ZSTD_isError(ret)) return ret; - ret = ZSTD_decompressBlock( + ret = ZSTD_decompressBlock_deprecated( dctx, DECOMPRESSED_BUFFER, MAX_DECOMPRESSED_SIZE, fr->dataStart, (BYTE*)fr->data - (BYTE*)fr->dataStart); diff --git a/src/dependencies/zstd-1.5.4/tests/dict-files/zero-weight-dict b/src/dependencies/zstd-1.5.6/tests/dict-files/zero-weight-dict similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/dict-files/zero-weight-dict rename to src/dependencies/zstd-1.5.6/tests/dict-files/zero-weight-dict diff --git a/src/dependencies/zstd-1.5.4/tests/external_matchfinder.c b/src/dependencies/zstd-1.5.6/tests/external_matchfinder.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/external_matchfinder.c rename to src/dependencies/zstd-1.5.6/tests/external_matchfinder.c diff --git a/src/dependencies/zstd-1.5.4/tests/external_matchfinder.h b/src/dependencies/zstd-1.5.6/tests/external_matchfinder.h similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/external_matchfinder.h rename to src/dependencies/zstd-1.5.6/tests/external_matchfinder.h diff --git a/src/dependencies/zstd-1.5.4/tests/fullbench.c b/src/dependencies/zstd-1.5.6/tests/fullbench.c similarity index 97% rename from src/dependencies/zstd-1.5.4/tests/fullbench.c rename to src/dependencies/zstd-1.5.6/tests/fullbench.c index 3a72d89..c8f0c0a 100644 --- a/src/dependencies/zstd-1.5.4/tests/fullbench.c +++ b/src/dependencies/zstd-1.5.6/tests/fullbench.c @@ -138,18 +138,24 @@ static size_t local_ZSTD_decompress(const void* src, size_t srcSize, return ZSTD_decompress(dst, dstSize, buff2, g_cSize); } -static ZSTD_DCtx* g_zdc = NULL; +static ZSTD_DCtx* g_zdc = NULL; /* will be initialized within benchMem */ +static size_t local_ZSTD_decompressDCtx(const void* src, size_t srcSize, + void* dst, size_t dstSize, + void* buff2) +{ + (void)src; (void)srcSize; + return ZSTD_decompressDCtx(g_zdc, dst, dstSize, buff2, g_cSize); +} #ifndef ZSTD_DLL_IMPORT -typedef enum { - not_streaming = 0, - is_streaming = 1 -} streaming_operation; -extern size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* ctx, const void* src, size_t srcSize, void* dst, size_t dstCapacity, const streaming_operation streaming); + +extern size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx, + const void* src, size_t srcSize, + void* dst, size_t dstCapacity); static size_t local_ZSTD_decodeLiteralsBlock(const void* src, size_t srcSize, void* dst, size_t dstSize, void* buff2) { (void)src; (void)srcSize; (void)dst; (void)dstSize; - return ZSTD_decodeLiteralsBlock(g_zdc, buff2, g_cSize, dst, dstSize, not_streaming); + return ZSTD_decodeLiteralsBlock_wrapper(g_zdc, buff2, g_cSize, dst, dstSize); } static size_t local_ZSTD_decodeSeqHeaders(const void* src, size_t srcSize, void* dst, size_t dstSize, void* buff2) @@ -453,6 +459,9 @@ static int benchMem(unsigned benchNb, case 3: benchFunction = local_ZSTD_compress_freshCCtx; benchName = "compress_freshCCtx"; break; + case 4: + benchFunction = local_ZSTD_decompressDCtx; benchName = "decompressDCtx"; + break; #ifndef ZSTD_DLL_IMPORT case 11: benchFunction = local_ZSTD_compressContinue; benchName = "compressContinue"; @@ -552,6 +561,9 @@ static int benchMem(unsigned benchNb, case 3: payload = &cparams; break; + case 4: + g_cSize = ZSTD_compress(dstBuff2, dstBuffSize, src, srcSize, cLevel); + break; #ifndef ZSTD_DLL_IMPORT case 11: payload = &cparams; @@ -606,7 +618,7 @@ static int benchMem(unsigned benchNb, ip += ZSTD_blockHeaderSize; /* skip block header */ ZSTD_decompressBegin(g_zdc); CONTROL(iend > ip); - ip += ZSTD_decodeLiteralsBlock(g_zdc, ip, (size_t)(iend-ip), dstBuff, dstBuffSize, not_streaming); /* skip literal segment */ + ip += ZSTD_decodeLiteralsBlock_wrapper(g_zdc, ip, (size_t)(iend-ip), dstBuff, dstBuffSize); /* skip literal segment */ g_cSize = (size_t)(iend-ip); memcpy(dstBuff2, ip, g_cSize); /* copy rest of block (it starts by SeqHeader) */ srcSize = srcSize > 128 KB ? 128 KB : srcSize; /* speed relative to block */ @@ -774,7 +786,9 @@ static int benchFiles(U32 benchNb, } else { for (benchNb=0; benchNb<100; benchNb++) { benchMem(benchNb, origBuff, benchedSize, cLevel, cparams); - } } + } + benchNb = 0; + } free(origBuff); } } diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/.gitignore b/src/dependencies/zstd-1.5.6/tests/fuzz/.gitignore similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/fuzz/.gitignore rename to src/dependencies/zstd-1.5.6/tests/fuzz/.gitignore diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/Makefile b/src/dependencies/zstd-1.5.6/tests/fuzz/Makefile similarity index 75% rename from src/dependencies/zstd-1.5.4/tests/fuzz/Makefile rename to src/dependencies/zstd-1.5.6/tests/fuzz/Makefile index bbb262a..430f6df 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/Makefile +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/Makefile @@ -24,23 +24,22 @@ else endif CORPORA_URL_PREFIX:=https://github.com/facebook/zstd/releases/download/fuzz-corpora/ -LIBZSTD = ../../lib +LIBZSTD_MK_DIR = ../../lib DEBUGLEVEL ?= 2 ZSTD_LEGACY_SUPPORT ?= 1 -include $(LIBZSTD)/libzstd.mk +include $(LIBZSTD_MK_DIR)/libzstd.mk -ZSTDDIR = ../../lib PRGDIR = ../../programs CONTRIBDIR = ../../contrib -# TODO(embg) make it possible to plug in an arbitrary matchfinder as a .o file -MATCHFINDER_DIR = $(CONTRIBDIR)/externalSequenceProducer -MATCHFINDER_SRC = $(MATCHFINDER_DIR)/sequence_producer.c +DEFAULT_SEQ_PROD_DIR = $(CONTRIBDIR)/externalSequenceProducer +DEFAULT_SEQ_PROD_SRC = $(DEFAULT_SEQ_PROD_DIR)/sequence_producer.c +THIRD_PARTY_SEQ_PROD_OBJ ?= -FUZZ_CPPFLAGS := -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \ - -I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(ZSTDDIR)/legacy \ - -I$(CONTRIBDIR)/seekable_format -I$(PRGDIR) -I$(MATCHFINDER_DIR) \ +FUZZ_CPPFLAGS := -I$(LIB_SRCDIR) -I$(LIB_SRCDIR)/common -I$(LIB_SRCDIR)/compress \ + -I$(LIB_SRCDIR)/dictBuilder -I$(LIB_SRCDIR)/deprecated -I$(LIB_SRCDIR)/legacy \ + -I$(CONTRIBDIR)/seekable_format -I$(PRGDIR) -I$(DEFAULT_SEQ_PROD_DIR) \ -DZSTD_MULTITHREAD -DZSTD_LEGACY_SUPPORT=1 $(CPPFLAGS) FUZZ_EXTRA_FLAGS := -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ @@ -75,30 +74,32 @@ FUZZ_SRC := \ $(ZSTDCOMP_SRC) \ $(ZSTDDICT_SRC) \ $(ZSTDLEGACY_SRC) \ - $(MATCHFINDER_SRC) + $(DEFAULT_SEQ_PROD_SRC) FUZZ_SRC := $(sort $(wildcard $(FUZZ_SRC))) -FUZZ_D_OBJ1 := $(subst $(ZSTDDIR)/common/,d_lib_common_,$(FUZZ_SRC)) -FUZZ_D_OBJ2 := $(subst $(ZSTDDIR)/compress/,d_lib_compress_,$(FUZZ_D_OBJ1)) -FUZZ_D_OBJ3 := $(subst $(ZSTDDIR)/decompress/,d_lib_decompress_,$(FUZZ_D_OBJ2)) -FUZZ_D_OBJ4 := $(subst $(ZSTDDIR)/dictBuilder/,d_lib_dictBuilder_,$(FUZZ_D_OBJ3)) -FUZZ_D_OBJ5 := $(subst $(ZSTDDIR)/legacy/,d_lib_legacy_,$(FUZZ_D_OBJ4)) +FUZZ_D_OBJ1 := $(subst $(LIB_SRCDIR)/common/,d_lib_common_,$(FUZZ_SRC)) +FUZZ_D_OBJ2 := $(subst $(LIB_SRCDIR)/compress/,d_lib_compress_,$(FUZZ_D_OBJ1)) +FUZZ_D_OBJ3 := $(subst $(LIB_SRCDIR)/decompress/,d_lib_decompress_,$(FUZZ_D_OBJ2)) +FUZZ_D_OBJ4 := $(subst $(LIB_SRCDIR)/dictBuilder/,d_lib_dictBuilder_,$(FUZZ_D_OBJ3)) +FUZZ_D_OBJ5 := $(subst $(LIB_SRCDIR)/legacy/,d_lib_legacy_,$(FUZZ_D_OBJ4)) FUZZ_D_OBJ6 := $(subst $(PRGDIR)/,d_prg_,$(FUZZ_D_OBJ5)) -FUZZ_D_OBJ7 := $(subst $(MATCHFINDER_DIR)/,d_matchfinder_,$(FUZZ_D_OBJ6)) +FUZZ_D_OBJ7 := $(subst $(DEFAULT_SEQ_PROD_DIR)/,d_default_seq_prod_,$(FUZZ_D_OBJ6)) FUZZ_D_OBJ8 := $(subst $\./,d_fuzz_,$(FUZZ_D_OBJ7)) FUZZ_D_OBJ9 := $(FUZZ_D_OBJ8:.c=.o) -FUZZ_DECOMPRESS_OBJ := $(FUZZ_D_OBJ9:.S=.o) +FUZZ_D_OBJ10 := $(THIRD_PARTY_SEQ_PROD_OBJ) $(FUZZ_D_OBJ9) +FUZZ_DECOMPRESS_OBJ := $(FUZZ_D_OBJ10:.S=.o) -FUZZ_RT_OBJ1 := $(subst $(ZSTDDIR)/common/,rt_lib_common_,$(FUZZ_SRC)) -FUZZ_RT_OBJ2 := $(subst $(ZSTDDIR)/compress/,rt_lib_compress_,$(FUZZ_RT_OBJ1)) -FUZZ_RT_OBJ3 := $(subst $(ZSTDDIR)/decompress/,rt_lib_decompress_,$(FUZZ_RT_OBJ2)) -FUZZ_RT_OBJ4 := $(subst $(ZSTDDIR)/dictBuilder/,rt_lib_dictBuilder_,$(FUZZ_RT_OBJ3)) -FUZZ_RT_OBJ5 := $(subst $(ZSTDDIR)/legacy/,rt_lib_legacy_,$(FUZZ_RT_OBJ4)) +FUZZ_RT_OBJ1 := $(subst $(LIB_SRCDIR)/common/,rt_lib_common_,$(FUZZ_SRC)) +FUZZ_RT_OBJ2 := $(subst $(LIB_SRCDIR)/compress/,rt_lib_compress_,$(FUZZ_RT_OBJ1)) +FUZZ_RT_OBJ3 := $(subst $(LIB_SRCDIR)/decompress/,rt_lib_decompress_,$(FUZZ_RT_OBJ2)) +FUZZ_RT_OBJ4 := $(subst $(LIB_SRCDIR)/dictBuilder/,rt_lib_dictBuilder_,$(FUZZ_RT_OBJ3)) +FUZZ_RT_OBJ5 := $(subst $(LIB_SRCDIR)/legacy/,rt_lib_legacy_,$(FUZZ_RT_OBJ4)) FUZZ_RT_OBJ6 := $(subst $(PRGDIR)/,rt_prg_,$(FUZZ_RT_OBJ5)) -FUZZ_RT_OBJ7 := $(subst $(MATCHFINDER_DIR)/,rt_matchfinder_,$(FUZZ_RT_OBJ6)) +FUZZ_RT_OBJ7 := $(subst $(DEFAULT_SEQ_PROD_DIR)/,rt_default_seq_prod_,$(FUZZ_RT_OBJ6)) FUZZ_RT_OBJ8 := $(subst $\./,rt_fuzz_,$(FUZZ_RT_OBJ7)) FUZZ_RT_OBJ9 := $(FUZZ_RT_OBJ8:.c=.o) -FUZZ_ROUND_TRIP_OBJ := $(FUZZ_RT_OBJ9:.S=.o) +FUZZ_RT_OBJ10 := $(THIRD_PARTY_SEQ_PROD_OBJ) $(FUZZ_RT_OBJ9) +FUZZ_ROUND_TRIP_OBJ := $(FUZZ_RT_OBJ10:.S=.o) .PHONY: default all clean cleanall @@ -123,26 +124,28 @@ FUZZ_TARGETS := \ sequence_compression_api \ seekable_roundtrip \ huf_round_trip \ - huf_decompress + huf_decompress \ + decompress_cross_format \ + generate_sequences all: libregression.a $(FUZZ_TARGETS) -rt_lib_common_%.o: $(ZSTDDIR)/common/%.c +rt_lib_common_%.o: $(LIB_SRCDIR)/common/%.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $(FUZZ_ROUND_TRIP_FLAGS) $< -c -o $@ -rt_lib_compress_%.o: $(ZSTDDIR)/compress/%.c +rt_lib_compress_%.o: $(LIB_SRCDIR)/compress/%.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $(FUZZ_ROUND_TRIP_FLAGS) $< -c -o $@ -rt_lib_decompress_%.o: $(ZSTDDIR)/decompress/%.c +rt_lib_decompress_%.o: $(LIB_SRCDIR)/decompress/%.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $(FUZZ_ROUND_TRIP_FLAGS) $< -c -o $@ -rt_lib_decompress_%.o: $(ZSTDDIR)/decompress/%.S +rt_lib_decompress_%.o: $(LIB_SRCDIR)/decompress/%.S $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_ASFLAGS) $(FUZZ_ROUND_TRIP_FLAGS) $< -c -o $@ -rt_lib_dictBuilder_%.o: $(ZSTDDIR)/dictBuilder/%.c +rt_lib_dictBuilder_%.o: $(LIB_SRCDIR)/dictBuilder/%.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $(FUZZ_ROUND_TRIP_FLAGS) $< -c -o $@ -rt_lib_legacy_%.o: $(ZSTDDIR)/legacy/%.c +rt_lib_legacy_%.o: $(LIB_SRCDIR)/legacy/%.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $(FUZZ_ROUND_TRIP_FLAGS) $< -c -o $@ rt_prg_%.o: $(PRGDIR)/%.c @@ -151,25 +154,25 @@ rt_prg_%.o: $(PRGDIR)/%.c rt_fuzz_%.o: %.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $(FUZZ_ROUND_TRIP_FLAGS) $< -c -o $@ -rt_matchfinder_%.o: $(MATCHFINDER_DIR)/%.c +rt_default_seq_prod_%.o: $(DEFAULT_SEQ_PROD_DIR)/%.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $(FUZZ_ROUND_TRIP_FLAGS) $< -c -o $@ -d_lib_common_%.o: $(ZSTDDIR)/common/%.c +d_lib_common_%.o: $(LIB_SRCDIR)/common/%.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $< -c -o $@ -d_lib_compress_%.o: $(ZSTDDIR)/compress/%.c +d_lib_compress_%.o: $(LIB_SRCDIR)/compress/%.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $< -c -o $@ -d_lib_decompress_%.o: $(ZSTDDIR)/decompress/%.c +d_lib_decompress_%.o: $(LIB_SRCDIR)/decompress/%.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $< -c -o $@ -d_lib_decompress_%.o: $(ZSTDDIR)/decompress/%.S +d_lib_decompress_%.o: $(LIB_SRCDIR)/decompress/%.S $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_ASFLAGS) $< -c -o $@ -d_lib_dictBuilder_%.o: $(ZSTDDIR)/dictBuilder/%.c +d_lib_dictBuilder_%.o: $(LIB_SRCDIR)/dictBuilder/%.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $< -c -o $@ -d_lib_legacy_%.o: $(ZSTDDIR)/legacy/%.c +d_lib_legacy_%.o: $(LIB_SRCDIR)/legacy/%.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $< -c -o $@ d_prg_%.o: $(PRGDIR)/%.c @@ -178,7 +181,7 @@ d_prg_%.o: $(PRGDIR)/%.c d_fuzz_%.o: %.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $< -c -o $@ -d_matchfinder_%.o: $(MATCHFINDER_DIR)/%.c +d_default_seq_prod_%.o: $(DEFAULT_SEQ_PROD_DIR)/%.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $< -c -o $@ simple_round_trip: $(FUZZ_HEADERS) $(FUZZ_ROUND_TRIP_OBJ) rt_fuzz_simple_round_trip.o @@ -238,6 +241,12 @@ huf_round_trip: $(FUZZ_HEADERS) $(FUZZ_ROUND_TRIP_OBJ) rt_fuzz_huf_round_trip.o huf_decompress: $(FUZZ_HEADERS) $(FUZZ_DECOMPRESS_OBJ) d_fuzz_huf_decompress.o $(CXX) $(FUZZ_TARGET_FLAGS) $(FUZZ_DECOMPRESS_OBJ) d_fuzz_huf_decompress.o $(LIB_FUZZING_ENGINE) -o $@ +decompress_cross_format: $(FUZZ_HEADERS) $(FUZZ_DECOMPRESS_OBJ) d_fuzz_decompress_cross_format.o + $(CXX) $(FUZZ_TARGET_FLAGS) $(FUZZ_DECOMPRESS_OBJ) d_fuzz_decompress_cross_format.o $(LIB_FUZZING_ENGINE) -o $@ + +generate_sequences: $(FUZZ_HEADERS) $(FUZZ_ROUND_TRIP_OBJ) rt_fuzz_generate_sequences.o + $(CXX) $(FUZZ_TARGET_FLAGS) $(FUZZ_ROUND_TRIP_OBJ) rt_fuzz_generate_sequences.o $(LIB_FUZZING_ENGINE) -o $@ + libregression.a: $(FUZZ_HEADERS) $(PRGDIR)/util.h $(PRGDIR)/util.c d_fuzz_regression_driver.o $(AR) $(FUZZ_ARFLAGS) $@ d_fuzz_regression_driver.o @@ -255,7 +264,7 @@ corpora: $(patsubst %,corpora/%,$(FUZZ_TARGETS)) seedcorpora: $(patsubst %,corpora/%_seed_corpus.zip,$(FUZZ_TARGETS)) regressiontest: corpora - CC="$(CC)" CXX="$(CXX)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" $(PYTHON) ./fuzz.py build all + CC="$(CC)" CXX="$(CXX)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" $(PYTHON) ./fuzz.py build all --debug=$(DEBUGLEVEL) $(PYTHON) ./fuzz.py regression all clean: diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/README.md b/src/dependencies/zstd-1.5.6/tests/fuzz/README.md similarity index 63% rename from src/dependencies/zstd-1.5.4/tests/fuzz/README.md rename to src/dependencies/zstd-1.5.6/tests/fuzz/README.md index 4ff7fe3..e2196e8 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/README.md +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/README.md @@ -61,7 +61,7 @@ Alternatively, you can fuzz all targets in parallel, using one core per target: ``` python3 ./fuzz.py list | xargs -P$(python3 ./fuzz.py list | wc -l) -I__ sh -c "python3 ./fuzz.py libfuzzer __ 2>&1 | tee __.log" ``` -Either way, to double-check that no crashes were found, run `ls corpora/*crash`. +Either way, to double-check that no crashes were found, run `ls corpora/*crash`. If any crashes were found, you can use the hashes to reproduce them. ## LibFuzzer @@ -113,3 +113,49 @@ CC=clang CXX=clang++ ./fuzz.py build all --enable-asan --enable-ubsan CC=clang CXX=clang++ ./fuzz.py build all --enable-msan ./fuzz.py regression all ``` + +## Fuzzing a custom sequence producer plugin +Sequence producer plugin authors can use the zstd fuzzers to stress-test their code. +See the documentation in `fuzz_third_party_seq_prod.h` for details. + +## Adding a new fuzzer +There are several steps involved in adding a new fuzzer harness. + +### Build your harness +1. Create a new your fuzzer harness `tests/fuzz/your_harness.c`. + +2. Add your harness to the Makefile + + 2.1 Follow [this example](https://github.com/facebook/zstd/blob/e124e39301381de8f323436a3e4c46539747ba24/tests/fuzz/Makefile#L216) if your fuzzer requires both compression and decompression symbols (prefix `rt_`). If your fuzzer only requires decompression symbols, follow [this example](https://github.com/facebook/zstd/blob/6a0052a409e2604bd40354b76b86272b712edd7d/tests/fuzz/Makefile#L194) (prefix `d_`). + + 2.2 Add your target to [`FUZZ_TARGETS`](https://github.com/facebook/zstd/blob/6a0052a409e2604bd40354b76b86272b712edd7d/tests/fuzz/Makefile#L108). + +3. Add your harness to [`fuzz.py`](https://github.com/facebook/zstd/blob/6a0052a409e2604bd40354b76b86272b712edd7d/tests/fuzz/fuzz.py#L48). + +### Generate seed data +Follow the instructions above to generate seed data: +``` +make -C ../tests decodecorpus +./fuzz.py gen your_harness +``` + +### Run the harness +Follow the instructions above to run your harness and fix any crashes: +``` +./fuzz.py build your_harness --enable-fuzzer --enable-asan --enable-ubsan --cc clang --cxx clang++ +./fuzz.py libfuzzer your_harness +``` + +### Minimize and zip the corpus +After running the fuzzer for a while, you will have a large corpus at `tests/fuzz/corpora/your_harness*`. +This corpus must be minimized and zipped before uploading to GitHub for regression testing: +``` +./fuzz.py minimize your_harness +./fuzz.py zip your_harness +``` + +### Upload the zip file to GitHub +The previous step should produce a `.zip` file containing the corpus for your new harness. +This corpus must be uploaded to GitHub here: https://github.com/facebook/zstd/releases/tag/fuzz-corpora + + diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/block_decompress.c b/src/dependencies/zstd-1.5.6/tests/fuzz/block_decompress.c similarity index 86% rename from src/dependencies/zstd-1.5.4/tests/fuzz/block_decompress.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/block_decompress.c index e4767b3..9cc6005 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/block_decompress.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/block_decompress.c @@ -13,6 +13,7 @@ * decompression function to ensure the decompressor never crashes. */ +#include "fuzz_data_producer.h" #define ZSTD_STATIC_LINKING_ONLY #include @@ -28,11 +29,12 @@ static size_t bufSize = 0; int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { size_t const neededBufSize = ZSTD_BLOCKSIZE_MAX; + FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); /* Allocate all buffers and contexts if not already allocated */ if (neededBufSize > bufSize) { free(rBuf); - rBuf = FUZZ_malloc(neededBufSize); + rBuf = FUZZ_malloc_rand(neededBufSize, producer); bufSize = neededBufSize; } if (!dctx) { @@ -42,6 +44,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) ZSTD_decompressBegin(dctx); ZSTD_decompressBlock(dctx, rBuf, neededBufSize, src, size); + FUZZ_dataProducer_free(producer); + #ifndef STATEFUL_FUZZING ZSTD_freeDCtx(dctx); dctx = NULL; #endif diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/block_round_trip.c b/src/dependencies/zstd-1.5.6/tests/fuzz/block_round_trip.c similarity index 97% rename from src/dependencies/zstd-1.5.4/tests/fuzz/block_round_trip.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/block_round_trip.c index 54012a1..c17146d 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/block_round_trip.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/block_round_trip.c @@ -23,6 +23,7 @@ #include "zstd.h" #include "zstd_helpers.h" #include "fuzz_data_producer.h" +#include "fuzz_third_party_seq_prod.h" static ZSTD_CCtx *cctx = NULL; static ZSTD_DCtx *dctx = NULL; @@ -54,6 +55,8 @@ static size_t roundTripTest(void *result, size_t resultCapacity, int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { + FUZZ_SEQ_PROD_SETUP(); + /* Give a random portion of src data to the producer, to use for parameter generation. The rest will be used for (de)compression */ FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); @@ -95,5 +98,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) ZSTD_freeCCtx(cctx); cctx = NULL; ZSTD_freeDCtx(dctx); dctx = NULL; #endif + FUZZ_SEQ_PROD_TEARDOWN(); return 0; } diff --git a/src/dependencies/zstd-1.5.6/tests/fuzz/decompress_cross_format.c b/src/dependencies/zstd-1.5.6/tests/fuzz/decompress_cross_format.c new file mode 100644 index 0000000..da10702 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/decompress_cross_format.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +// This fuzz target validates decompression of magicless-format compressed data. + +#include +#include +#include +#include +#include "fuzz_helpers.h" +#define ZSTD_STATIC_LINKING_ONLY +#include "zstd.h" +#include "fuzz_data_producer.h" + +static ZSTD_DCtx *dctx = NULL; + +int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) +{ + // Give a random portion of src data to the producer, to use for parameter generation. + // The rest will be interpreted as magicless compressed data. + FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); + size_t magiclessSize = FUZZ_dataProducer_reserveDataPrefix(producer); + const uint8_t* const magiclessSrc = src; + size_t const dstSize = FUZZ_dataProducer_uint32Range(producer, 0, 10 * size); + uint8_t* const standardDst = (uint8_t*)FUZZ_malloc(dstSize); + uint8_t* const magiclessDst = (uint8_t*)FUZZ_malloc(dstSize); + + // Create standard-format src from magicless-format src + const uint32_t zstd_magic = ZSTD_MAGICNUMBER; + size_t standardSize = sizeof(zstd_magic) + magiclessSize; + uint8_t* const standardSrc = (uint8_t*)FUZZ_malloc(standardSize); + memcpy(standardSrc, &zstd_magic, sizeof(zstd_magic)); // assume fuzzing on little-endian machine + memcpy(standardSrc + sizeof(zstd_magic), magiclessSrc, magiclessSize); + + // Truncate to a single frame + { + const size_t standardFrameCompressedSize = ZSTD_findFrameCompressedSize(standardSrc, standardSize); + if (ZSTD_isError(standardFrameCompressedSize)) { + goto cleanup_and_return; + } + standardSize = standardFrameCompressedSize; + magiclessSize = standardFrameCompressedSize - sizeof(zstd_magic); + } + + // Create DCtx if needed + if (!dctx) { + dctx = ZSTD_createDCtx(); + FUZZ_ASSERT(dctx); + } + + // Test one-shot decompression + { + FUZZ_ZASSERT(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_and_parameters)); + FUZZ_ZASSERT(ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, ZSTD_f_zstd1)); + const size_t standardRet = ZSTD_decompressDCtx( + dctx, standardDst, dstSize, standardSrc, standardSize); + + FUZZ_ZASSERT(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_and_parameters)); + FUZZ_ZASSERT(ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, ZSTD_f_zstd1_magicless)); + const size_t magiclessRet = ZSTD_decompressDCtx( + dctx, magiclessDst, dstSize, magiclessSrc, magiclessSize); + + // Standard accepts => magicless should accept + if (!ZSTD_isError(standardRet)) FUZZ_ZASSERT(magiclessRet); + + // Magicless accepts => standard should accept + // NOTE: this is nice-to-have, please disable this check if it is difficult to satisfy. + if (!ZSTD_isError(magiclessRet)) FUZZ_ZASSERT(standardRet); + + // If both accept, decompressed size and data should match + if (!ZSTD_isError(standardRet) && !ZSTD_isError(magiclessRet)) { + FUZZ_ASSERT(standardRet == magiclessRet); + if (standardRet > 0) { + FUZZ_ASSERT( + memcmp(standardDst, magiclessDst, standardRet) == 0 + ); + } + } + } + + // Test streaming decompression + { + ZSTD_inBuffer standardIn = { standardSrc, standardSize, 0 }; + ZSTD_inBuffer magiclessIn = { magiclessSrc, magiclessSize, 0 }; + ZSTD_outBuffer standardOut = { standardDst, dstSize, 0 }; + ZSTD_outBuffer magiclessOut = { magiclessDst, dstSize, 0 }; + + FUZZ_ZASSERT(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_and_parameters)); + FUZZ_ZASSERT(ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, ZSTD_f_zstd1)); + const size_t standardRet = ZSTD_decompressStream(dctx, &standardOut, &standardIn); + + FUZZ_ZASSERT(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_and_parameters)); + FUZZ_ZASSERT(ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, ZSTD_f_zstd1_magicless)); + const size_t magiclessRet = ZSTD_decompressStream(dctx, &magiclessOut, &magiclessIn); + + // Standard accepts => magicless should accept + if (standardRet == 0) FUZZ_ASSERT(magiclessRet == 0); + + // Magicless accepts => standard should accept + // NOTE: this is nice-to-have, please disable this check if it is difficult to satisfy. + if (magiclessRet == 0) FUZZ_ASSERT(standardRet == 0); + + // If both accept, decompressed size and data should match + if (standardRet == 0 && magiclessRet == 0) { + FUZZ_ASSERT(standardOut.pos == magiclessOut.pos); + if (standardOut.pos > 0) { + FUZZ_ASSERT( + memcmp(standardOut.dst, magiclessOut.dst, standardOut.pos) == 0 + ); + } + } + } + +cleanup_and_return: +#ifndef STATEFUL_FUZZING + ZSTD_freeDCtx(dctx); dctx = NULL; +#endif + free(standardSrc); + free(standardDst); + free(magiclessDst); + FUZZ_dataProducer_free(producer); + return 0; +} diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/decompress_dstSize_tooSmall.c b/src/dependencies/zstd-1.5.6/tests/fuzz/decompress_dstSize_tooSmall.c similarity index 95% rename from src/dependencies/zstd-1.5.4/tests/fuzz/decompress_dstSize_tooSmall.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/decompress_dstSize_tooSmall.c index 8ad3ea1..3f7095d 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/decompress_dstSize_tooSmall.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/decompress_dstSize_tooSmall.c @@ -22,12 +22,15 @@ #include "zstd_errors.h" #include "zstd_helpers.h" #include "fuzz_data_producer.h" +#include "fuzz_third_party_seq_prod.h" static ZSTD_CCtx *cctx = NULL; static ZSTD_DCtx *dctx = NULL; int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { + FUZZ_SEQ_PROD_SETUP(); + /* Give a random portion of src data to the producer, to use for parameter generation. The rest will be used for (de)compression */ FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); @@ -66,5 +69,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) ZSTD_freeCCtx(cctx); cctx = NULL; ZSTD_freeDCtx(dctx); dctx = NULL; #endif + FUZZ_SEQ_PROD_TEARDOWN(); return 0; } diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/dictionary_decompress.c b/src/dependencies/zstd-1.5.6/tests/fuzz/dictionary_decompress.c similarity index 96% rename from src/dependencies/zstd-1.5.4/tests/fuzz/dictionary_decompress.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/dictionary_decompress.c index 8dea3e5..c37d143 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/dictionary_decompress.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/dictionary_decompress.c @@ -20,11 +20,14 @@ #include "fuzz_helpers.h" #include "zstd_helpers.h" #include "fuzz_data_producer.h" +#include "fuzz_third_party_seq_prod.h" static ZSTD_DCtx *dctx = NULL; int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { + FUZZ_SEQ_PROD_SETUP(); + /* Give a random portion of src data to the producer, to use for parameter generation. The rest will be used for (de)compression */ FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); @@ -69,5 +72,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) #ifndef STATEFUL_FUZZING ZSTD_freeDCtx(dctx); dctx = NULL; #endif + FUZZ_SEQ_PROD_TEARDOWN(); return 0; } diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/dictionary_loader.c b/src/dependencies/zstd-1.5.6/tests/fuzz/dictionary_loader.c similarity index 97% rename from src/dependencies/zstd-1.5.4/tests/fuzz/dictionary_loader.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/dictionary_loader.c index 1ac2274..7b7c004 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/dictionary_loader.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/dictionary_loader.c @@ -20,6 +20,7 @@ #include "fuzz_helpers.h" #include "zstd_helpers.h" #include "fuzz_data_producer.h" +#include "fuzz_third_party_seq_prod.h" /** * Compresses the data and returns the compressed size or an error. @@ -35,7 +36,7 @@ static size_t compress(void* compressed, size_t compressedCapacity, if (refPrefix) FUZZ_ZASSERT(ZSTD_CCtx_refPrefix_advanced( cctx, dict, dictSize, dictContentType)); - else + else FUZZ_ZASSERT(ZSTD_CCtx_loadDictionary_advanced( cctx, dict, dictSize, dictLoadMethod, dictContentType)); size_t const compressedSize = ZSTD_compress2( @@ -67,6 +68,7 @@ static size_t decompress(void* result, size_t resultCapacity, int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { + FUZZ_SEQ_PROD_SETUP(); FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); int const refPrefix = FUZZ_dataProducer_uint32Range(producer, 0, 1) != 0; ZSTD_dictLoadMethod_e const dlm = @@ -99,5 +101,6 @@ out: free(cBuf); free(rBuf); FUZZ_dataProducer_free(producer); + FUZZ_SEQ_PROD_TEARDOWN(); return 0; } diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/dictionary_round_trip.c b/src/dependencies/zstd-1.5.6/tests/fuzz/dictionary_round_trip.c similarity index 93% rename from src/dependencies/zstd-1.5.4/tests/fuzz/dictionary_round_trip.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/dictionary_round_trip.c index 6dd78c3..0470fbf 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/dictionary_round_trip.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/dictionary_round_trip.c @@ -21,14 +21,15 @@ #include "fuzz_helpers.h" #include "zstd_helpers.h" #include "fuzz_data_producer.h" +#include "fuzz_third_party_seq_prod.h" -static ZSTD_CCtx *cctx = NULL; -static ZSTD_DCtx *dctx = NULL; +static ZSTD_CCtx* cctx = NULL; +static ZSTD_DCtx* dctx = NULL; -static size_t roundTripTest(void *result, size_t resultCapacity, - void *compressed, size_t compressedCapacity, - const void *src, size_t srcSize, - FUZZ_dataProducer_t *producer) +static size_t roundTripTest(void* result, size_t resultCapacity, + void* compressed, size_t compressedCapacity, + const void* src, size_t srcSize, + FUZZ_dataProducer_t* producer) { ZSTD_dictContentType_e dictContentType = ZSTD_dct_auto; FUZZ_dict_t dict = FUZZ_train(src, srcSize, producer); @@ -108,6 +109,8 @@ static size_t roundTripTest(void *result, size_t resultCapacity, int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { + FUZZ_SEQ_PROD_SETUP(); + /* Give a random portion of src data to the producer, to use for parameter generation. The rest will be used for (de)compression */ FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); @@ -147,5 +150,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) ZSTD_freeCCtx(cctx); cctx = NULL; ZSTD_freeDCtx(dctx); dctx = NULL; #endif + FUZZ_SEQ_PROD_TEARDOWN(); return 0; } diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/dictionary_stream_round_trip.c b/src/dependencies/zstd-1.5.6/tests/fuzz/dictionary_stream_round_trip.c similarity index 98% rename from src/dependencies/zstd-1.5.4/tests/fuzz/dictionary_stream_round_trip.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/dictionary_stream_round_trip.c index 3ebbd84..3a15553 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/dictionary_stream_round_trip.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/dictionary_stream_round_trip.c @@ -22,6 +22,7 @@ #include "fuzz_helpers.h" #include "zstd_helpers.h" #include "fuzz_data_producer.h" +#include "fuzz_third_party_seq_prod.h" ZSTD_CCtx *cctx = NULL; static ZSTD_DCtx *dctx = NULL; @@ -147,6 +148,7 @@ static size_t compress(uint8_t *dst, size_t capacity, int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { + FUZZ_SEQ_PROD_SETUP(); size_t neededBufSize; /* Give a random portion of src data to the producer, to use for @@ -202,5 +204,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) ZSTD_freeCCtx(cctx); cctx = NULL; ZSTD_freeDCtx(dctx); dctx = NULL; #endif + FUZZ_SEQ_PROD_TEARDOWN(); return 0; } diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/fse_read_ncount.c b/src/dependencies/zstd-1.5.6/tests/fuzz/fse_read_ncount.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/fuzz/fse_read_ncount.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/fse_read_ncount.c diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/fuzz.h b/src/dependencies/zstd-1.5.6/tests/fuzz/fuzz.h similarity index 84% rename from src/dependencies/zstd-1.5.4/tests/fuzz/fuzz.h rename to src/dependencies/zstd-1.5.6/tests/fuzz/fuzz.h index d1e439f..8064c70 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/fuzz.h +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/fuzz.h @@ -31,6 +31,11 @@ * This is the canonical flag to enable deterministic builds for fuzzing. * Changes to zstd for fuzzing are gated behind this define. * It is recommended to define this when building zstd for fuzzing. + * @param FUZZ_THIRD_PARTY_SEQ_PROD + * This flag allows sequence producer plugin authors to replace the built-in + * default sequence producer with their own code. If you are not a plugin + * author, you should not define this flag. See the docs at + * fuzz_third_party_seq_prod.h for more information. */ #ifndef FUZZ_H diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/fuzz.py b/src/dependencies/zstd-1.5.6/tests/fuzz/fuzz.py similarity index 96% rename from src/dependencies/zstd-1.5.4/tests/fuzz/fuzz.py rename to src/dependencies/zstd-1.5.6/tests/fuzz/fuzz.py index 03ffeee..d59df92 100755 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/fuzz.py +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/fuzz.py @@ -65,6 +65,8 @@ TARGET_INFO = { 'seekable_roundtrip': TargetInfo(InputType.RAW_DATA), 'huf_round_trip': TargetInfo(InputType.RAW_DATA), 'huf_decompress': TargetInfo(InputType.RAW_DATA), + 'decompress_cross_format': TargetInfo(InputType.RAW_DATA), + 'generate_sequences': TargetInfo(InputType.RAW_DATA), } TARGETS = list(TARGET_INFO.keys()) ALL_TARGETS = TARGETS + ['all'] @@ -78,6 +80,7 @@ CFLAGS = os.environ.get('CFLAGS', '-O3') CXXFLAGS = os.environ.get('CXXFLAGS', CFLAGS) LDFLAGS = os.environ.get('LDFLAGS', '') MFLAGS = os.environ.get('MFLAGS', '-j') +THIRD_PARTY_SEQ_PROD_OBJ = os.environ.get('THIRD_PARTY_SEQ_PROD_OBJ', '') # Fuzzing environment variables LIB_FUZZING_ENGINE = os.environ.get('LIB_FUZZING_ENGINE', 'libregression.a') @@ -249,10 +252,10 @@ def build_parser(args): action='store_true', help='Enable UBSAN') parser.add_argument( - '--enable-ubsan-pointer-overflow', + '--disable-ubsan-pointer-overflow', dest='ubsan_pointer_overflow', - action='store_true', - help='Enable UBSAN pointer overflow check (known failure)') + action='store_false', + help='Disable UBSAN pointer overflow check (known failure)') parser.add_argument( '--enable-msan', dest='msan', action='store_true', help='Enable MSAN') parser.add_argument( @@ -319,6 +322,12 @@ def build_parser(args): dest='stateful_fuzzing', action='store_true', help='Reuse contexts between runs (makes reproduction impossible)') + parser.add_argument( + '--custom-seq-prod', + dest='third_party_seq_prod_obj', + type=str, + default=THIRD_PARTY_SEQ_PROD_OBJ, + help='Path to an object file with symbols for fuzzing your sequence producer plugin.') parser.add_argument( '--cc', dest='cc', @@ -376,8 +385,6 @@ def build_parser(args): raise RuntimeError('MSAN may not be used with any other sanitizers') if args.msan_track_origins and not args.msan: raise RuntimeError('--enable-msan-track-origins requires MSAN') - if args.ubsan_pointer_overflow and not args.ubsan: - raise RuntimeError('--enable-ubsan-pointer-overflow requires UBSAN') if args.sanitize_recover and not args.sanitize: raise RuntimeError('--enable-sanitize-recover but no sanitizers used') @@ -400,7 +407,12 @@ def build(args): cxxflags = shlex.split(args.cxxflags) mflags = shlex.split(args.mflags) # Flags to be added to both cflags and cxxflags - common_flags = [] + common_flags = [ + '-Werror', + '-Wno-error=declaration-after-statement', + '-Wno-error=c++-compat', + '-Wno-error=deprecated' # C files are sometimes compiled with CXX + ] cppflags += [ '-DDEBUGLEVEL={}'.format(args.debug), @@ -450,6 +462,10 @@ def build(args): if args.stateful_fuzzing: cppflags += ['-DSTATEFUL_FUZZING'] + if args.third_party_seq_prod_obj: + cppflags += ['-DFUZZ_THIRD_PARTY_SEQ_PROD'] + mflags += ['THIRD_PARTY_SEQ_PROD_OBJ={}'.format(args.third_party_seq_prod_obj)] + if args.fuzzing_mode: cppflags += ['-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION'] @@ -483,6 +499,7 @@ def build(args): subprocess.check_call(clean_cmd) build_cmd = [ 'make', + '-j', cc_str, cxx_str, cppflags_str, diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/fuzz_data_producer.c b/src/dependencies/zstd-1.5.6/tests/fuzz/fuzz_data_producer.c similarity index 92% rename from src/dependencies/zstd-1.5.4/tests/fuzz/fuzz_data_producer.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/fuzz_data_producer.c index a93e8ba..056de3e 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/fuzz_data_producer.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/fuzz_data_producer.c @@ -8,6 +8,7 @@ * You may select, at your option, one of the above-listed licenses. */ +#include "fuzz_helpers.h" #include "fuzz_data_producer.h" struct FUZZ_dataProducer_s{ @@ -27,12 +28,12 @@ void FUZZ_dataProducer_free(FUZZ_dataProducer_t *producer) { free(producer); } uint32_t FUZZ_dataProducer_uint32Range(FUZZ_dataProducer_t *producer, uint32_t min, uint32_t max) { - FUZZ_ASSERT(min <= max); - uint32_t range = max - min; uint32_t rolling = range; uint32_t result = 0; + FUZZ_ASSERT(min <= max); + while (rolling > 0 && producer->size > 0) { uint8_t next = *(producer->data + producer->size - 1); producer->size -= 1; @@ -78,11 +79,11 @@ int FUZZ_dataProducer_empty(FUZZ_dataProducer_t *producer) { size_t FUZZ_dataProducer_contract(FUZZ_dataProducer_t *producer, size_t newSize) { - newSize = newSize > producer->size ? producer->size : newSize; + const size_t effectiveNewSize = newSize > producer->size ? producer->size : newSize; - size_t remaining = producer->size - newSize; + size_t remaining = producer->size - effectiveNewSize; producer->data = producer->data + remaining; - producer->size = newSize; + producer->size = effectiveNewSize; return remaining; } diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/fuzz_data_producer.h b/src/dependencies/zstd-1.5.6/tests/fuzz/fuzz_data_producer.h similarity index 99% rename from src/dependencies/zstd-1.5.4/tests/fuzz/fuzz_data_producer.h rename to src/dependencies/zstd-1.5.6/tests/fuzz/fuzz_data_producer.h index 8ca501f..f488ceb 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/fuzz_data_producer.h +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/fuzz_data_producer.h @@ -24,7 +24,6 @@ #include #include -#include "fuzz_helpers.h" /* Struct used for maintaining the state of the data */ typedef struct FUZZ_dataProducer_s FUZZ_dataProducer_t; diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/fuzz_helpers.c b/src/dependencies/zstd-1.5.6/tests/fuzz/fuzz_helpers.c similarity index 64% rename from src/dependencies/zstd-1.5.4/tests/fuzz/fuzz_helpers.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/fuzz_helpers.c index 1b6ad97..f47ff2e 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/fuzz_helpers.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/fuzz_helpers.c @@ -23,6 +23,22 @@ void* FUZZ_malloc(size_t size) return NULL; } +void* FUZZ_malloc_rand(size_t size, FUZZ_dataProducer_t *producer) +{ + if (size > 0) { + void* const mem = malloc(size); + FUZZ_ASSERT(mem); + return mem; + } else { + uintptr_t ptr = 0; + /* Add +- 1M 50% of the time */ + if (FUZZ_dataProducer_uint32Range(producer, 0, 1)) + FUZZ_dataProducer_int32Range(producer, -1000000, 1000000); + return (void*)ptr; + } + +} + int FUZZ_memcmp(void const* lhs, void const* rhs, size_t size) { if (size == 0) { diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/fuzz_helpers.h b/src/dependencies/zstd-1.5.6/tests/fuzz/fuzz_helpers.h similarity index 90% rename from src/dependencies/zstd-1.5.4/tests/fuzz/fuzz_helpers.h rename to src/dependencies/zstd-1.5.6/tests/fuzz/fuzz_helpers.h index aaf4c1d..f21ec47 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/fuzz_helpers.h +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/fuzz_helpers.h @@ -19,6 +19,7 @@ #include "fuzz.h" #include "xxhash.h" #include "zstd.h" +#include "fuzz_data_producer.h" #include #include #include @@ -62,6 +63,12 @@ extern "C" { */ void* FUZZ_malloc(size_t size); +/** + * malloc except returns random pointer for zero sized data and FUZZ_ASSERT + * that malloc doesn't fail. + */ +void* FUZZ_malloc_rand(size_t size, FUZZ_dataProducer_t *producer); + /** * memcmp but accepts NULL. */ diff --git a/src/dependencies/zstd-1.5.6/tests/fuzz/fuzz_third_party_seq_prod.h b/src/dependencies/zstd-1.5.6/tests/fuzz/fuzz_third_party_seq_prod.h new file mode 100644 index 0000000..f0771e4 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/fuzz_third_party_seq_prod.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) Yann Collet, Meta Platforms, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef EXAMPLE_SEQ_PROD_H +#define EXAMPLE_SEQ_PROD_H + +#define ZSTD_STATIC_LINKING_ONLY +#include "zstd.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* *** INTERFACE FOR FUZZING THIRD-PARTY SEQUENCE PRODUCER PLUGINS *** + * Fuzz-testing for the external sequence producer API was introduced in PR #3437. + * However, the setup in #3437 only allows fuzzers to exercise the implementation of the + * API itself (the code in the core zstd library which interacts with your plugin). + * + * This header defines an interface for plugin authors to link their code into the fuzzer + * build. Plugin authors can provide an object file implementing the symbols below, + * and those symbols will replace the default ones provided by #3437. + * + * To fuzz your plugin, follow these steps: + * - Build your object file with a recent version of clang. Building with gcc is not supported. + * - Build your object file using appropriate flags for fuzzing. For example: + * `-g -fno-omit-frame-pointer -fsanitize=undefined,address,fuzzer` + * - Build the fuzzer binaries with options corresponding to the flags you chose. Use --custom-seq-prod= to pass in your object file: + * `./fuzz.py build all --enable-fuzzer --enable-asan --enable-ubsan --cc clang --cxx clang++ --custom-seq-prod=your_object.o` + * + * An example implementation of this header is provided at tests/fuzz/seq_prod_fuzz_example/. + * Use these commands to fuzz with the example code: + * $ make corpora + * $ make -C seq_prod_fuzz_example/ + * $ python3 ./fuzz.py build all --enable-fuzzer --enable-asan --enable-ubsan --cc clang --cxx clang++ --custom-seq-prod=seq_prod_fuzz_example/example_seq_prod.o + * $ python3 ./fuzz.py libfuzzer simple_round_trip + */ + +/* The fuzzer will call this function before each test-case. It should run any + * setup actions (such as starting a hardware device) needed for fuzzing. + * + * The fuzzer will assert() that the return value is zero. To signal an error, + * please return a non-zero value. */ +size_t FUZZ_seqProdSetup(void); + +/* The fuzzer will call this function after each test-case. It should free + * resources acquired by FUZZ_seqProdSetup() to prevent leaks across test-cases. + * + * The fuzzer will assert() that the return value is zero. To signal an error, + * please return a non-zero value. */ +size_t FUZZ_seqProdTearDown(void); + +/* The fuzzer will call this function before each test-case, only after calling + * FUZZ_seqProdSetup(), to obtain a sequence producer state which can be passed + * into ZSTD_registerSequenceProducer(). + * + * All compressions which are part of a test-case will share a single sequence + * producer state. Sharing the state object is safe because the fuzzers currently + * don't exercise the sequence producer API in multi-threaded scenarios. We may + * need a new approach in the future to support multi-threaded fuzzing. + * + * The fuzzer will assert() that the return value is not NULL. To signal an error, + * please return NULL. */ +void* FUZZ_createSeqProdState(void); + +/* The fuzzer will call this function after each test-case. It should free any + * resources acquired by FUZZ_createSeqProdState(). + * + * The fuzzer will assert() that the return value is zero. To signal an error, + * please return a non-zero value. */ +size_t FUZZ_freeSeqProdState(void* sequenceProducerState); + +/* This is the sequence producer function you would like to fuzz! It will receive + * the void* returned by FUZZ_createSeqProdState() on each invocation. */ +size_t FUZZ_thirdPartySeqProd(void* sequenceProducerState, + ZSTD_Sequence* outSeqs, size_t outSeqsCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize, + int compressionLevel, + size_t windowSize); + +/* These macros are internal helpers. You do not need to worry about them. */ +#ifdef FUZZ_THIRD_PARTY_SEQ_PROD +#define FUZZ_SEQ_PROD_SETUP() \ + do { \ + FUZZ_ASSERT(FUZZ_seqProdSetup() == 0); \ + FUZZ_seqProdState = FUZZ_createSeqProdState(); \ + FUZZ_ASSERT(FUZZ_seqProdState != NULL); \ + } while (0) +#else +#define FUZZ_SEQ_PROD_SETUP() +#endif + +#ifdef FUZZ_THIRD_PARTY_SEQ_PROD +#define FUZZ_SEQ_PROD_TEARDOWN() \ + do { \ + FUZZ_ASSERT(FUZZ_freeSeqProdState(FUZZ_seqProdState) == 0); \ + FUZZ_ASSERT(FUZZ_seqProdTearDown() == 0); \ + } while (0) +#else +#define FUZZ_SEQ_PROD_TEARDOWN() +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EXAMPLE_SEQ_PROD_H */ diff --git a/src/dependencies/zstd-1.5.6/tests/fuzz/generate_sequences.c b/src/dependencies/zstd-1.5.6/tests/fuzz/generate_sequences.c new file mode 100644 index 0000000..1cc57e8 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/generate_sequences.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#define ZSTD_STATIC_LINKING_ONLY + +#include +#include +#include +#include + +#include "fuzz_data_producer.h" +#include "fuzz_helpers.h" +#include "zstd_helpers.h" + +/** + * This fuzz target ensures that ZSTD_generateSequences() does not crash and + * if it succeeds that ZSTD_compressSequences() round trips. + */ + +static void testRoundTrip(ZSTD_CCtx* cctx, ZSTD_Sequence const* seqs, size_t nbSeqs, const void* src, size_t srcSize) { + /* Compress the sequences with block delimiters */ + const size_t compressBound = ZSTD_compressBound(srcSize); + void* dst = FUZZ_malloc(compressBound); + FUZZ_ASSERT(dst); + + size_t compressedSize = ZSTD_compressSequences(cctx, dst, compressBound, seqs, nbSeqs, src, srcSize); + FUZZ_ZASSERT(compressedSize); + + void* decompressed = FUZZ_malloc(srcSize); + FUZZ_ASSERT(srcSize == 0 || decompressed); + size_t decompressedSize = ZSTD_decompress(decompressed, srcSize, dst, compressedSize); + FUZZ_ZASSERT(decompressedSize); + FUZZ_ASSERT(decompressedSize == srcSize); + if (srcSize != 0) { + FUZZ_ASSERT(!memcmp(src, decompressed, srcSize)); + } + + free(decompressed); + free(dst); +} + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + + FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(data, size); + size = FUZZ_dataProducer_reserveDataPrefix(producer); + + ZSTD_CCtx* cctx = ZSTD_createCCtx(); + FUZZ_ASSERT(cctx); + + const size_t seqsCapacity = FUZZ_dataProducer_uint32Range(producer, 0, 2 * ZSTD_sequenceBound(size)); + ZSTD_Sequence* seqs = (ZSTD_Sequence*)FUZZ_malloc(sizeof(ZSTD_Sequence) * seqsCapacity); + FUZZ_ASSERT(seqsCapacity == 0 || seqs); + + FUZZ_setRandomParameters(cctx, size, producer); + FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetCBlockSize, 0)); + FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 0)); + + const size_t nbSeqs = ZSTD_generateSequences(cctx, seqs, seqsCapacity, data, size); + if (ZSTD_isError(nbSeqs)) { + /* Allowed to error if the destination is too small */ + if (ZSTD_getErrorCode(nbSeqs) == ZSTD_error_dstSize_tooSmall) { + FUZZ_ASSERT(seqsCapacity < ZSTD_sequenceBound(size)); + } + } else { + /* Ensure we round trip with and without block delimiters*/ + + FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_blockDelimiters, ZSTD_sf_explicitBlockDelimiters)); + testRoundTrip(cctx, seqs, nbSeqs, data, size); + + const size_t nbMergedSeqs = ZSTD_mergeBlockDelimiters(seqs, nbSeqs); + FUZZ_ASSERT(nbMergedSeqs <= nbSeqs); + FUZZ_ZASSERT(ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only)); + FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_blockDelimiters, ZSTD_sf_noBlockDelimiters)); + testRoundTrip(cctx, seqs, nbMergedSeqs, data, size); + } + + free(seqs); + ZSTD_freeCCtx(cctx); + FUZZ_dataProducer_free(producer); + return 0; +} diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/huf_decompress.c b/src/dependencies/zstd-1.5.6/tests/fuzz/huf_decompress.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/fuzz/huf_decompress.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/huf_decompress.c diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/huf_round_trip.c b/src/dependencies/zstd-1.5.6/tests/fuzz/huf_round_trip.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/fuzz/huf_round_trip.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/huf_round_trip.c diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/raw_dictionary_round_trip.c b/src/dependencies/zstd-1.5.6/tests/fuzz/raw_dictionary_round_trip.c similarity index 97% rename from src/dependencies/zstd-1.5.4/tests/fuzz/raw_dictionary_round_trip.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/raw_dictionary_round_trip.c index 7ceab2b..7536f55 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/raw_dictionary_round_trip.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/raw_dictionary_round_trip.c @@ -21,6 +21,7 @@ #include "fuzz_helpers.h" #include "zstd_helpers.h" #include "fuzz_data_producer.h" +#include "fuzz_third_party_seq_prod.h" static ZSTD_CCtx *cctx = NULL; static ZSTD_DCtx *dctx = NULL; @@ -42,7 +43,7 @@ static size_t roundTripTest(void *result, size_t resultCapacity, FUZZ_ZASSERT(ZSTD_CCtx_refPrefix_advanced( cctx, dict, dictSize, ZSTD_dct_rawContent)); - else + else FUZZ_ZASSERT(ZSTD_CCtx_loadDictionary_advanced( cctx, dict, dictSize, (ZSTD_dictLoadMethod_e)FUZZ_dataProducer_uint32Range(producer, 0, 1), @@ -68,6 +69,8 @@ static size_t roundTripTest(void *result, size_t resultCapacity, int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { + FUZZ_SEQ_PROD_SETUP(); + /* Give a random portion of src data to the producer, to use for parameter generation. The rest will be used for (de)compression */ FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); @@ -111,5 +114,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) ZSTD_freeCCtx(cctx); cctx = NULL; ZSTD_freeDCtx(dctx); dctx = NULL; #endif + FUZZ_SEQ_PROD_TEARDOWN(); return 0; } diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/regression_driver.c b/src/dependencies/zstd-1.5.6/tests/fuzz/regression_driver.c similarity index 99% rename from src/dependencies/zstd-1.5.4/tests/fuzz/regression_driver.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/regression_driver.c index 550c65d..26e2b6a 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/regression_driver.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/regression_driver.c @@ -44,11 +44,12 @@ int main(int argc, char const **argv) { fprintf(stderr, "WARNING: No files passed to %s\n", argv[0]); for (i = 0; i < files->tableSize; ++i) { char const *fileName = files->fileNames[i]; - DEBUGLOG(3, "Running %s", fileName); size_t const fileSize = UTIL_getFileSize(fileName); size_t readSize; FILE *file; + DEBUGLOG(3, "Running %s", fileName); + /* Check that it is a regular file, and that the fileSize is valid. * If it is not a regular file, then it may have been deleted since we * constructed the list, so just skip it, but return an error exit code. diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/seekable_roundtrip.c b/src/dependencies/zstd-1.5.6/tests/fuzz/seekable_roundtrip.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/fuzz/seekable_roundtrip.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/seekable_roundtrip.c diff --git a/src/dependencies/zstd-1.5.6/tests/fuzz/seq_prod_fuzz_example/Makefile b/src/dependencies/zstd-1.5.6/tests/fuzz/seq_prod_fuzz_example/Makefile new file mode 100644 index 0000000..f9d9fad --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/seq_prod_fuzz_example/Makefile @@ -0,0 +1,16 @@ +# Copyright (c) Yann Collet, Meta Platforms, Inc. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# You may select, at your option, one of the above-listed licenses. + +CC = clang +CFLAGS = -g -fno-omit-frame-pointer -fsanitize=undefined,address,fuzzer -I../ -I../../../lib/ + +.PHONY: default +default: example_seq_prod.o + +example_seq_prod.o: example_seq_prod.c + $(CC) -c $(CFLAGS) $^ -o $@ diff --git a/src/dependencies/zstd-1.5.6/tests/fuzz/seq_prod_fuzz_example/README.md b/src/dependencies/zstd-1.5.6/tests/fuzz/seq_prod_fuzz_example/README.md new file mode 100644 index 0000000..16fff68 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/seq_prod_fuzz_example/README.md @@ -0,0 +1,12 @@ +# Fuzzing a Custom Sequence Producer Plugin +This directory contains example code for using a custom sequence producer in the zstd fuzzers. + +You can build and run the code in this directory using these commands: +``` +$ make corpora +$ make -C seq_prod_fuzz_example/ +$ python3 ./fuzz.py build all --enable-fuzzer --enable-asan --enable-ubsan --cc clang --cxx clang++ --custom-seq-prod=seq_prod_fuzz_example/example_seq_prod.o +$ python3 ./fuzz.py libfuzzer simple_round_trip +``` + +See `../fuzz_third_party_seq_prod.h` and `../README.md` for more information on zstd fuzzing. diff --git a/src/dependencies/zstd-1.5.6/tests/fuzz/seq_prod_fuzz_example/example_seq_prod.c b/src/dependencies/zstd-1.5.6/tests/fuzz/seq_prod_fuzz_example/example_seq_prod.c new file mode 100644 index 0000000..fb4473c --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/seq_prod_fuzz_example/example_seq_prod.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) Yann Collet, Meta Platforms, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "fuzz_third_party_seq_prod.h" + +#include +#include +#include + +_Thread_local size_t threadLocalState; + +size_t FUZZ_seqProdSetup(void) { + threadLocalState = 0; + return 0; +} + +size_t FUZZ_seqProdTearDown(void) { + return 0; +} + +void* FUZZ_createSeqProdState(void) { + return calloc(1, sizeof(size_t)); +} + +size_t FUZZ_freeSeqProdState(void* state) { + free(state); + return 0; +} + +size_t FUZZ_thirdPartySeqProd( + void* sequenceProducerState, + ZSTD_Sequence* outSeqs, size_t outSeqsCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize, + int compressionLevel, + size_t windowSize +) { + /* Try to catch unsafe use of the shared state */ + size_t* const sharedStatePtr = (size_t*)sequenceProducerState; + assert(*sharedStatePtr == threadLocalState); + (*sharedStatePtr)++; threadLocalState++; + + /* Check that fallback is enabled when FUZZ_THIRD_PARTY_SEQ_PROD is defined */ + return ZSTD_SEQUENCE_PRODUCER_ERROR; +} diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/sequence_compression_api.c b/src/dependencies/zstd-1.5.6/tests/fuzz/sequence_compression_api.c similarity index 98% rename from src/dependencies/zstd-1.5.4/tests/fuzz/sequence_compression_api.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/sequence_compression_api.c index 9d3f0a1..ec0106c 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/sequence_compression_api.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/sequence_compression_api.c @@ -25,6 +25,7 @@ #include "fuzz_helpers.h" #include "zstd_helpers.h" #include "fuzz_data_producer.h" +#include "fuzz_third_party_seq_prod.h" static ZSTD_CCtx* cctx = NULL; static ZSTD_DCtx* dctx = NULL; @@ -115,7 +116,7 @@ static size_t decodeSequences(void* dst, size_t nbSequences, } } for (; j < matchLength; ++j) { - op[j] = op[j - generatedSequences[i].offset]; + op[j] = op[(ptrdiff_t)(j - generatedSequences[i].offset)]; } op += j; FUZZ_ASSERT(generatedSequences[i].matchLength == j + k); @@ -263,6 +264,8 @@ static size_t roundTripTest(void* result, size_t resultCapacity, int LLVMFuzzerTestOneInput(const uint8_t* src, size_t size) { + FUZZ_SEQ_PROD_SETUP(); + void* rBuf; size_t rBufSize; void* cBuf; @@ -373,5 +376,6 @@ int LLVMFuzzerTestOneInput(const uint8_t* src, size_t size) free(generatedSrc); generatedSrc = NULL; free(literalsBuffer); literalsBuffer = NULL; #endif + FUZZ_SEQ_PROD_TEARDOWN(); return 0; } diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/simple_compress.c b/src/dependencies/zstd-1.5.6/tests/fuzz/simple_compress.c similarity index 94% rename from src/dependencies/zstd-1.5.4/tests/fuzz/simple_compress.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/simple_compress.c index c9fea22..74f0356 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/simple_compress.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/simple_compress.c @@ -22,11 +22,14 @@ #include "zstd_errors.h" #include "zstd_helpers.h" #include "fuzz_data_producer.h" +#include "fuzz_third_party_seq_prod.h" static ZSTD_CCtx *cctx = NULL; int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { + FUZZ_SEQ_PROD_SETUP(); + /* Give a random portion of src data to the producer, to use for parameter generation. The rest will be used for (de)compression */ FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); @@ -52,5 +55,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) #ifndef STATEFUL_FUZZING ZSTD_freeCCtx(cctx); cctx = NULL; #endif + FUZZ_SEQ_PROD_TEARDOWN(); return 0; } diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/simple_decompress.c b/src/dependencies/zstd-1.5.6/tests/fuzz/simple_decompress.c similarity index 64% rename from src/dependencies/zstd-1.5.4/tests/fuzz/simple_decompress.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/simple_decompress.c index ce5f9f0..0dc9e5b 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/simple_decompress.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/simple_decompress.c @@ -16,6 +16,9 @@ #include #include #include + +#define ZSTD_STATIC_LINKING_ONLY + #include "fuzz_helpers.h" #include "zstd.h" #include "fuzz_data_producer.h" @@ -34,11 +37,18 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) FUZZ_ASSERT(dctx); } - size_t const bufSize = FUZZ_dataProducer_uint32Range(producer, 0, 10 * size); - void *rBuf = FUZZ_malloc(bufSize); - - ZSTD_decompressDCtx(dctx, rBuf, bufSize, src, size); - free(rBuf); + { + size_t const bufSize = FUZZ_dataProducer_uint32Range(producer, 0, 10 * size); + void *rBuf = FUZZ_malloc(bufSize); + size_t const dSize = ZSTD_decompressDCtx(dctx, rBuf, bufSize, src, size); + if (!ZSTD_isError(dSize)) { + /* If decompression was successful, the content size from the frame header(s) should be valid. */ + unsigned long long const expectedSize = ZSTD_findDecompressedSize(src, size); + FUZZ_ASSERT(expectedSize != ZSTD_CONTENTSIZE_ERROR); + FUZZ_ASSERT(expectedSize == ZSTD_CONTENTSIZE_UNKNOWN || expectedSize == dSize); + } + free(rBuf); + } FUZZ_dataProducer_free(producer); diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/simple_round_trip.c b/src/dependencies/zstd-1.5.6/tests/fuzz/simple_round_trip.c similarity index 90% rename from src/dependencies/zstd-1.5.4/tests/fuzz/simple_round_trip.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/simple_round_trip.c index c2c69d9..660092e 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/simple_round_trip.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/simple_round_trip.c @@ -22,11 +22,12 @@ #include "fuzz_helpers.h" #include "zstd_helpers.h" #include "fuzz_data_producer.h" +#include "fuzz_third_party_seq_prod.h" static ZSTD_CCtx *cctx = NULL; static ZSTD_DCtx *dctx = NULL; -static size_t getDecompressionMargin(void const* compressed, size_t cSize, size_t srcSize, int hasSmallBlocks) +static size_t getDecompressionMargin(void const* compressed, size_t cSize, size_t srcSize, int hasSmallBlocks, int maxBlockSize) { size_t margin = ZSTD_decompressionMargin(compressed, cSize); if (!hasSmallBlocks) { @@ -36,7 +37,12 @@ static size_t getDecompressionMargin(void const* compressed, size_t cSize, size_ ZSTD_frameHeader zfh; size_t marginM; FUZZ_ZASSERT(ZSTD_getFrameHeader(&zfh, compressed, cSize)); - marginM = ZSTD_DECOMPRESSION_MARGIN(srcSize, zfh.blockSizeMax); + if (maxBlockSize == 0) { + maxBlockSize = zfh.blockSizeMax; + } else { + maxBlockSize = MIN(maxBlockSize, (int)zfh.blockSizeMax); + } + marginM = ZSTD_DECOMPRESSION_MARGIN(srcSize, maxBlockSize); if (marginM < margin) margin = marginM; } @@ -51,12 +57,14 @@ static size_t roundTripTest(void *result, size_t resultCapacity, size_t cSize; size_t dSize; int targetCBlockSize = 0; + int maxBlockSize = 0; if (FUZZ_dataProducer_uint32Range(producer, 0, 1)) { size_t const remainingBytes = FUZZ_dataProducer_remainingBytes(producer); FUZZ_setRandomParameters(cctx, srcSize, producer); cSize = ZSTD_compress2(cctx, compressed, compressedCapacity, src, srcSize); FUZZ_ZASSERT(cSize); FUZZ_ZASSERT(ZSTD_CCtx_getParameter(cctx, ZSTD_c_targetCBlockSize, &targetCBlockSize)); + FUZZ_ZASSERT(ZSTD_CCtx_getParameter(cctx, ZSTD_c_maxBlockSize, &maxBlockSize)); // Compress a second time and check for determinism { size_t const cSize0 = cSize; @@ -82,13 +90,16 @@ static size_t roundTripTest(void *result, size_t resultCapacity, FUZZ_ASSERT(XXH64(compressed, cSize, 0) == hash0); } } + if (FUZZ_dataProducer_uint32Range(producer, 0, 1)) { + FUZZ_ZASSERT(ZSTD_DCtx_setParameter(dctx, ZSTD_d_maxBlockSize, maxBlockSize)); + } dSize = ZSTD_decompressDCtx(dctx, result, resultCapacity, compressed, cSize); FUZZ_ZASSERT(dSize); FUZZ_ASSERT_MSG(dSize == srcSize, "Incorrect regenerated size"); FUZZ_ASSERT_MSG(!FUZZ_memcmp(src, result, dSize), "Corruption!"); { - size_t margin = getDecompressionMargin(compressed, cSize, srcSize, targetCBlockSize); + size_t margin = getDecompressionMargin(compressed, cSize, srcSize, targetCBlockSize, maxBlockSize); size_t const outputSize = srcSize + margin; char* const output = (char*)FUZZ_malloc(outputSize); char* const input = output + outputSize - cSize; @@ -129,6 +140,8 @@ static size_t roundTripTest(void *result, size_t resultCapacity, int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { + FUZZ_SEQ_PROD_SETUP(); + size_t const rBufSize = size; void* rBuf = FUZZ_malloc(rBufSize); size_t cBufSize = ZSTD_compressBound(size); @@ -164,5 +177,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) ZSTD_freeCCtx(cctx); cctx = NULL; ZSTD_freeDCtx(dctx); dctx = NULL; #endif + FUZZ_SEQ_PROD_TEARDOWN(); return 0; } diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/stream_decompress.c b/src/dependencies/zstd-1.5.6/tests/fuzz/stream_decompress.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/fuzz/stream_decompress.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/stream_decompress.c diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/stream_round_trip.c b/src/dependencies/zstd-1.5.6/tests/fuzz/stream_round_trip.c similarity index 85% rename from src/dependencies/zstd-1.5.4/tests/fuzz/stream_round_trip.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/stream_round_trip.c index fae9ccb..6e340c8 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/stream_round_trip.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/stream_round_trip.c @@ -22,6 +22,7 @@ #include "fuzz_helpers.h" #include "zstd_helpers.h" #include "fuzz_data_producer.h" +#include "fuzz_third_party_seq_prod.h" ZSTD_CCtx *cctx = NULL; static ZSTD_DCtx *dctx = NULL; @@ -62,6 +63,8 @@ static size_t compress(uint8_t *dst, size_t capacity, size_t dstSize = 0; ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only); FUZZ_setRandomParameters(cctx, srcSize, producer); + int maxBlockSize; + FUZZ_ZASSERT(ZSTD_CCtx_getParameter(cctx, ZSTD_c_maxBlockSize, &maxBlockSize)); while (srcSize > 0) { ZSTD_inBuffer in = makeInBuffer(&src, &srcSize, producer); @@ -92,6 +95,8 @@ static size_t compress(uint8_t *dst, size_t capacity, if (FUZZ_dataProducer_uint32Range(producer, 0, 7) == 0) { size_t const remaining = in.size - in.pos; FUZZ_setRandomParameters(cctx, remaining, producer); + /* Always use the same maxBlockSize */ + FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_maxBlockSize, maxBlockSize)); } mode = -1; } @@ -131,8 +136,26 @@ static size_t compress(uint8_t *dst, size_t capacity, return dstSize; } +static size_t decompress(void* dst, size_t dstCapacity, void const* src, size_t srcSize, FUZZ_dataProducer_t* producer) +{ + ZSTD_inBuffer in = {src, srcSize, 0}; + ZSTD_outBuffer out = {dst, dstCapacity, 0}; + int maxBlockSize; + FUZZ_ZASSERT(ZSTD_CCtx_getParameter(cctx, ZSTD_c_maxBlockSize, &maxBlockSize)); + if (FUZZ_dataProducer_uint32Range(producer, 0, 1)) { + FUZZ_ZASSERT(ZSTD_DCtx_setParameter(dctx, ZSTD_d_maxBlockSize, maxBlockSize)); + } + while (in.pos < in.size) { + size_t const ret = ZSTD_decompressStream(dctx, &out, &in); + FUZZ_ZASSERT(ret); + FUZZ_ASSERT(ret == 0); + } + return out.pos; +} + int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { + FUZZ_SEQ_PROD_SETUP(); size_t neededBufSize; /* Give a random portion of src data to the producer, to use for @@ -161,8 +184,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) { size_t const cSize = compress(cBuf, neededBufSize, src, size, producer); - size_t const rSize = - ZSTD_decompressDCtx(dctx, rBuf, neededBufSize, cBuf, cSize); + size_t const rSize = decompress(rBuf, neededBufSize, cBuf, cSize, producer); FUZZ_ZASSERT(rSize); FUZZ_ASSERT_MSG(rSize == size, "Incorrect regenerated size"); FUZZ_ASSERT_MSG(!FUZZ_memcmp(src, rBuf, size), "Corruption!"); @@ -191,5 +213,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) ZSTD_freeCCtx(cctx); cctx = NULL; ZSTD_freeDCtx(dctx); dctx = NULL; #endif + FUZZ_SEQ_PROD_TEARDOWN(); return 0; } diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/zstd_frame_info.c b/src/dependencies/zstd-1.5.6/tests/fuzz/zstd_frame_info.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/fuzz/zstd_frame_info.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/zstd_frame_info.c diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/zstd_helpers.c b/src/dependencies/zstd-1.5.6/tests/fuzz/zstd_helpers.c similarity index 94% rename from src/dependencies/zstd-1.5.4/tests/fuzz/zstd_helpers.c rename to src/dependencies/zstd-1.5.6/tests/fuzz/zstd_helpers.c index 411b639..f4cb108 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/zstd_helpers.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/zstd_helpers.c @@ -18,10 +18,13 @@ #include "zstd.h" #include "zdict.h" #include "sequence_producer.h" +#include "fuzz_third_party_seq_prod.h" const int kMinClevel = -3; const int kMaxClevel = 19; +void* FUZZ_seqProdState = NULL; + static void set(ZSTD_CCtx *cctx, ZSTD_cParameter param, int value) { FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, param, value)); @@ -72,12 +75,25 @@ ZSTD_parameters FUZZ_randomParams(size_t srcSize, FUZZ_dataProducer_t *producer) } static void setSequenceProducerParams(ZSTD_CCtx *cctx, FUZZ_dataProducer_t *producer) { +#ifdef FUZZ_THIRD_PARTY_SEQ_PROD + ZSTD_registerSequenceProducer( + cctx, + FUZZ_seqProdState, + FUZZ_thirdPartySeqProd + ); +#else ZSTD_registerSequenceProducer( cctx, NULL, simpleSequenceProducer ); +#endif + +#ifdef FUZZ_THIRD_PARTY_SEQ_PROD + FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_enableSeqProducerFallback, 1)); +#else setRand(cctx, ZSTD_c_enableSeqProducerFallback, 0, 1, producer); +#endif FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 0)); FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_enableLongDistanceMatching, ZSTD_ps_disable)); } @@ -137,11 +153,15 @@ void FUZZ_setRandomParameters(ZSTD_CCtx *cctx, size_t srcSize, FUZZ_dataProducer setRand(cctx, ZSTD_c_targetCBlockSize, ZSTD_TARGETCBLOCKSIZE_MIN, ZSTD_TARGETCBLOCKSIZE_MAX, producer); } +#ifdef FUZZ_THIRD_PARTY_SEQ_PROD + setSequenceProducerParams(cctx, producer); +#else if (FUZZ_dataProducer_uint32Range(producer, 0, 10) == 1) { setSequenceProducerParams(cctx, producer); } else { ZSTD_registerSequenceProducer(cctx, NULL, NULL); } +#endif } FUZZ_dict_t FUZZ_train(void const* src, size_t srcSize, FUZZ_dataProducer_t *producer) diff --git a/src/dependencies/zstd-1.5.4/tests/fuzz/zstd_helpers.h b/src/dependencies/zstd-1.5.6/tests/fuzz/zstd_helpers.h similarity index 95% rename from src/dependencies/zstd-1.5.4/tests/fuzz/zstd_helpers.h rename to src/dependencies/zstd-1.5.6/tests/fuzz/zstd_helpers.h index a4cfe32..be3071d 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzz/zstd_helpers.h +++ b/src/dependencies/zstd-1.5.6/tests/fuzz/zstd_helpers.h @@ -45,6 +45,10 @@ typedef struct { */ FUZZ_dict_t FUZZ_train(void const* src, size_t srcSize, FUZZ_dataProducer_t *producer); +#ifdef FUZZ_THIRD_PARTY_SEQ_PROD +extern void* FUZZ_seqProdState; +#endif + #ifdef __cplusplus } #endif diff --git a/src/dependencies/zstd-1.5.4/tests/fuzzer.c b/src/dependencies/zstd-1.5.6/tests/fuzzer.c similarity index 95% rename from src/dependencies/zstd-1.5.4/tests/fuzzer.c rename to src/dependencies/zstd-1.5.6/tests/fuzzer.c index fc78c7f..f7bdae9 100644 --- a/src/dependencies/zstd-1.5.4/tests/fuzzer.c +++ b/src/dependencies/zstd-1.5.6/tests/fuzzer.c @@ -328,7 +328,7 @@ static void FUZ_decodeSequences(BYTE* dst, ZSTD_Sequence* seqs, size_t seqsSize, if (seqs[i].offset != 0) { for (j = 0; j < seqs[i].matchLength; ++j) - dst[j] = dst[j - seqs[i].offset]; + dst[j] = dst[(ptrdiff_t)(j - seqs[i].offset)]; dst += seqs[i].matchLength; src += seqs[i].matchLength; size -= seqs[i].matchLength; @@ -376,7 +376,7 @@ static int threadPoolTests(void) { RDG_genBuffer(CNBuffer, CNBuffSize, 0.5, 0.5, 0); - DISPLAYLEVEL(3, "thread pool test : threadPool re-use roundtrips: "); + DISPLAYLEVEL(3, "thread pool test : threadPool reuse roundtrips: "); { ZSTD_CCtx* cctx = ZSTD_createCCtx(); ZSTD_threadPool* pool = ZSTD_createThreadPool(kPoolNumThreads); @@ -531,7 +531,7 @@ static void test_decompressBound(unsigned tnb) CHECK_EQ( ZSTD_flushStream(cctx, &out), 0 ); } CHECK_EQ( ZSTD_endStream(cctx, &out), 0 ); - CHECK( ZSTD_decompressBound(outBuffer, out.pos) > 0x100000000LLU /* 4 GB */ ); + CHECK( ZSTD_decompressBound(outBuffer, out.pos) > 0x100000000ULL /* 4 GB */ ); ZSTD_freeCCtx(cctx); free(outBuffer); } @@ -953,6 +953,25 @@ static int basicUnitTests(U32 const seed, double compressibility) ZSTD_freeCCtx(cctx); } + DISPLAYLEVEL(3, "test%3i : maxBlockSize = 2K", testNb++); + { + ZSTD_CCtx* cctx = ZSTD_createCCtx(); + ZSTD_DCtx* dctx = ZSTD_createDCtx(); + CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1)); + CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_maxBlockSize, 2048)); + CHECK_Z(ZSTD_DCtx_setParameter(dctx, ZSTD_d_maxBlockSize, 2048)); + + cSize = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize); + CHECK_Z(cSize); + CHECK_Z(ZSTD_decompressDCtx(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize)); + + CHECK_Z(ZSTD_DCtx_setParameter(dctx, ZSTD_d_maxBlockSize, 1024)); + CHECK(ZSTD_isError(ZSTD_decompressDCtx(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize))); + + ZSTD_freeDCtx(dctx); + ZSTD_freeCCtx(cctx); + } + DISPLAYLEVEL(3, "test%3i : ldm fill dict out-of-bounds check", testNb++); { ZSTD_CCtx* const cctx = ZSTD_createCCtx(); @@ -1100,6 +1119,9 @@ static int basicUnitTests(U32 const seed, double compressibility) size_t const srcSize1 = kWindowSize / 2; size_t const srcSize2 = kWindowSize * 10; + CHECK(cctx!=NULL); + CHECK(dctx!=NULL); + CHECK(dict!=NULL); if (CNBuffSize < dictSize) goto _output_error; RDG_genBuffer(dict, dictSize, 0.5, 0.5, seed); @@ -1121,6 +1143,7 @@ static int basicUnitTests(U32 const seed, double compressibility) cSize = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, srcSize1); CHECK_Z(cSize); CHECK_Z(ZSTD_decompress_usingDict(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize, dict, dictSize)); + cSize = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, srcSize2); /* Streaming decompression to catch out of bounds offsets. */ { @@ -1134,24 +1157,22 @@ static int basicUnitTests(U32 const seed, double compressibility) CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 2)); /* Round trip once with a dictionary. */ CHECK_Z(ZSTD_CCtx_refPrefix(cctx, dict, dictSize)); - { - ZSTD_inBuffer in = {CNBuffer, srcSize1, 0}; + { ZSTD_inBuffer in = {CNBuffer, srcSize1, 0}; ZSTD_outBuffer out = {compressedBuffer, compressedBufferSize, 0}; CHECK_Z(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_flush)); CHECK_Z(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_end)); cSize = out.pos; } CHECK_Z(ZSTD_decompress_usingDict(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize, dict, dictSize)); - { - ZSTD_inBuffer in = {CNBuffer, srcSize2, 0}; + + { ZSTD_inBuffer in = {CNBuffer, srcSize2, 0}; ZSTD_outBuffer out = {compressedBuffer, compressedBufferSize, 0}; CHECK_Z(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_flush)); CHECK_Z(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_end)); cSize = out.pos; } /* Streaming decompression to catch out of bounds offsets. */ - { - ZSTD_inBuffer in = {compressedBuffer, cSize, 0}; + { ZSTD_inBuffer in = {compressedBuffer, cSize, 0}; ZSTD_outBuffer out = {decodedBuffer, CNBuffSize, 0}; size_t const dSize = ZSTD_decompressStream(dctx, &out, &in); CHECK_Z(dSize); @@ -1286,7 +1307,74 @@ static int basicUnitTests(U32 const seed, double compressibility) } DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(3, "test%3d: superblock uncompressible data, too many nocompress superblocks : ", testNb++); + DISPLAYLEVEL(3, "test%3i : Check block splitter with 64K literal length : ", testNb++); + { ZSTD_CCtx* cctx = ZSTD_createCCtx(); + size_t const srcSize = 256 * 1024; + U32 const compressibleLenU32 = 32 * 1024 / 4; + U32 const blockSizeU32 = 128 * 1024 / 4; + U32 const litLenU32 = 64 * 1024 / 4; + U32* data = (U32*)malloc(srcSize); + size_t dSize; + + if (data == NULL || cctx == NULL) goto _output_error; + + /* Generate data without any matches */ + RDG_genBuffer(data, srcSize, 0.0, 0.01, 2654435761U); + /* Generate 32K of compressible data */ + RDG_genBuffer(data, compressibleLenU32 * 4, 0.5, 0.5, 0xcafebabe); + + /* Add a match of offset=12, length=8 at idx=16, 32, 48, 64 */ + data[compressibleLenU32 + 0] = 0xFFFFFFFF; + data[compressibleLenU32 + 1] = 0xEEEEEEEE; + data[compressibleLenU32 + 4] = 0xFFFFFFFF; + data[compressibleLenU32 + 5] = 0xEEEEEEEE; + + /* Add a match of offset=16, length=8 at idx=64K + 64. + * This generates a sequence with llen=64K, and repeat code 1. + * The block splitter thought this was ll0, and corrupted the + * repeat offset history. + */ + data[compressibleLenU32 + litLenU32 + 2 + 0] = 0xDDDDDDDD; + data[compressibleLenU32 + litLenU32 + 2 + 1] = 0xCCCCCCCC; + data[compressibleLenU32 + litLenU32 + 2 + 4] = 0xDDDDDDDD; + data[compressibleLenU32 + litLenU32 + 2 + 5] = 0xCCCCCCCC; + + /* Add a match of offset=16, length=8 at idx=128K + 16. + * This should generate a sequence with repeat code = 1. + * But the block splitters mistake caused zstd to generate + * repeat code = 2, corrupting the data. + */ + data[blockSizeU32] = 0xBBBBBBBB; + data[blockSizeU32 + 1] = 0xAAAAAAAA; + data[blockSizeU32 + 4] = 0xBBBBBBBB; + data[blockSizeU32 + 5] = 0xAAAAAAAA; + + /* Generate a golden file from this data in case datagen changes and + * doesn't generate the exact same data. We will also test this golden file. + */ + if (0) { + FILE* f = fopen("golden-compression/PR-3517-block-splitter-corruption-test", "wb"); + fwrite(data, 1, srcSize, f); + fclose(f); + } + + CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, 19)); + CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, 7)); + CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_useBlockSplitter, ZSTD_ps_enable)); + + cSize = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, data, srcSize); + CHECK_Z(cSize); + dSize = ZSTD_decompress(decodedBuffer, CNBuffSize, compressedBuffer, cSize); + CHECK_Z(dSize); + CHECK_EQ(dSize, srcSize); + CHECK(!memcmp(decodedBuffer, data, srcSize)); + + free(data); + ZSTD_freeCCtx(cctx); + } + DISPLAYLEVEL(3, "OK \n"); + + DISPLAYLEVEL(3, "test%3d : superblock uncompressible data: too many nocompress superblocks : ", testNb++); { ZSTD_CCtx* const cctx = ZSTD_createCCtx(); const BYTE* src = (BYTE*)CNBuffer; BYTE* dst = (BYTE*)compressedBuffer; @@ -1439,14 +1527,14 @@ static int basicUnitTests(U32 const seed, double compressibility) } DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(3, "test%3d : re-use CCtx with expanding block size : ", testNb++); + DISPLAYLEVEL(3, "test%3d : reuse CCtx with expanding block size : ", testNb++); { ZSTD_CCtx* const cctx = ZSTD_createCCtx(); ZSTD_parameters const params = ZSTD_getParams(1, ZSTD_CONTENTSIZE_UNKNOWN, 0); assert(params.fParams.contentSizeFlag == 1); /* block size will be adapted if pledgedSrcSize is enabled */ CHECK_Z( ZSTD_compressBegin_advanced(cctx, NULL, 0, params, 1 /*pledgedSrcSize*/) ); CHECK_Z( ZSTD_compressEnd(cctx, compressedBuffer, compressedBufferSize, CNBuffer, 1) ); /* creates a block size of 1 */ - CHECK_Z( ZSTD_compressBegin_advanced(cctx, NULL, 0, params, ZSTD_CONTENTSIZE_UNKNOWN) ); /* re-use same parameters */ + CHECK_Z( ZSTD_compressBegin_advanced(cctx, NULL, 0, params, ZSTD_CONTENTSIZE_UNKNOWN) ); /* reuse same parameters */ { size_t const inSize = 2* 128 KB; size_t const outSize = ZSTD_compressBound(inSize); CHECK_Z( ZSTD_compressEnd(cctx, compressedBuffer, outSize, CNBuffer, inSize) ); @@ -1583,6 +1671,133 @@ static int basicUnitTests(U32 const seed, double compressibility) } DISPLAYLEVEL(3, "OK \n"); + DISPLAYLEVEL(3, "test%3d : ZSTD_CCtx_setCParams() : ", testNb++); + { ZSTD_CCtx* const cctx = ZSTD_createCCtx(); + int value; + ZSTD_compressionParameters cparams = ZSTD_getCParams(1, 0, 0); + cparams.strategy = -1; + /* Set invalid cParams == no change. */ + CHECK(ZSTD_isError(ZSTD_CCtx_setCParams(cctx, cparams))); + + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_windowLog, &value)); + CHECK_EQ(value, 0); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_chainLog, &value)); + CHECK_EQ(value, 0); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_hashLog, &value)); + CHECK_EQ(value, 0); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_searchLog, &value)); + CHECK_EQ(value, 0); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_minMatch, &value)); + CHECK_EQ(value, 0); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_targetLength, &value)); + CHECK_EQ(value, 0); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_strategy, &value)); + CHECK_EQ(value, 0); + + cparams = ZSTD_getCParams(12, 0, 0); + CHECK_Z(ZSTD_CCtx_setCParams(cctx, cparams)); + + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_windowLog, &value)); + CHECK_EQ(value, (int)cparams.windowLog); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_chainLog, &value)); + CHECK_EQ(value, (int)cparams.chainLog); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_hashLog, &value)); + CHECK_EQ(value, (int)cparams.hashLog); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_searchLog, &value)); + CHECK_EQ(value, (int)cparams.searchLog); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_minMatch, &value)); + CHECK_EQ(value, (int)cparams.minMatch); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_targetLength, &value)); + CHECK_EQ(value, (int)cparams.targetLength); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_strategy, &value)); + CHECK_EQ(value, (int)cparams.strategy); + + ZSTD_freeCCtx(cctx); + } + + DISPLAYLEVEL(3, "test%3d : ZSTD_CCtx_setFParams() : ", testNb++); + { ZSTD_CCtx* const cctx = ZSTD_createCCtx(); + int value; + ZSTD_frameParameters fparams = {0, 1, 1}; + + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_contentSizeFlag, &value)); + CHECK_EQ(value, 1); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_checksumFlag, &value)); + CHECK_EQ(value, 0); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_dictIDFlag, &value)); + CHECK_EQ(value, 1); + + CHECK_Z(ZSTD_CCtx_setFParams(cctx, fparams)); + + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_contentSizeFlag, &value)); + CHECK_EQ(value, fparams.contentSizeFlag); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_checksumFlag, &value)); + CHECK_EQ(value, fparams.checksumFlag); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_dictIDFlag, &value)); + CHECK_EQ(value, !fparams.noDictIDFlag); + + ZSTD_freeCCtx(cctx); + } + + DISPLAYLEVEL(3, "test%3d : ZSTD_CCtx_setCarams() : ", testNb++); + { ZSTD_CCtx* const cctx = ZSTD_createCCtx(); + int value; + ZSTD_parameters params = ZSTD_getParams(1, 0, 0); + params.cParams.strategy = -1; + /* Set invalid params == no change. */ + CHECK(ZSTD_isError(ZSTD_CCtx_setParams(cctx, params))); + + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_windowLog, &value)); + CHECK_EQ(value, 0); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_chainLog, &value)); + CHECK_EQ(value, 0); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_hashLog, &value)); + CHECK_EQ(value, 0); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_searchLog, &value)); + CHECK_EQ(value, 0); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_minMatch, &value)); + CHECK_EQ(value, 0); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_targetLength, &value)); + CHECK_EQ(value, 0); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_strategy, &value)); + CHECK_EQ(value, 0); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_contentSizeFlag, &value)); + CHECK_EQ(value, 1); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_checksumFlag, &value)); + CHECK_EQ(value, 0); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_dictIDFlag, &value)); + CHECK_EQ(value, 1); + + params = ZSTD_getParams(12, 0, 0); + params.fParams.contentSizeFlag = 0; + params.fParams.checksumFlag = 1; + params.fParams.noDictIDFlag = 1; + CHECK_Z(ZSTD_CCtx_setParams(cctx, params)); + + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_windowLog, &value)); + CHECK_EQ(value, (int)params.cParams.windowLog); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_chainLog, &value)); + CHECK_EQ(value, (int)params.cParams.chainLog); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_hashLog, &value)); + CHECK_EQ(value, (int)params.cParams.hashLog); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_searchLog, &value)); + CHECK_EQ(value, (int)params.cParams.searchLog); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_minMatch, &value)); + CHECK_EQ(value, (int)params.cParams.minMatch); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_targetLength, &value)); + CHECK_EQ(value, (int)params.cParams.targetLength); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_strategy, &value)); + CHECK_EQ(value, (int)params.cParams.strategy); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_contentSizeFlag, &value)); + CHECK_EQ(value, params.fParams.contentSizeFlag); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_checksumFlag, &value)); + CHECK_EQ(value, params.fParams.checksumFlag); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_c_dictIDFlag, &value)); + CHECK_EQ(value, !params.fParams.noDictIDFlag); + + ZSTD_freeCCtx(cctx); + } + DISPLAYLEVEL(3, "test%3d : ldm conditionally enabled by default doesn't change cctx params: ", testNb++); { ZSTD_CCtx* const cctx = ZSTD_createCCtx(); ZSTD_outBuffer out = {NULL, 0, 0}; @@ -1614,7 +1829,7 @@ static int basicUnitTests(U32 const seed, double compressibility) params.cParams.windowLog = ZSTD_WINDOWLOG_MAX; for (cnb = 0; cnb < nbCompressions; ++cnb) { DISPLAYLEVEL(6, "run %zu / %zu \n", cnb, nbCompressions); - CHECK_Z( ZSTD_compressBegin_advanced(cctx, NULL, 0, params, ZSTD_CONTENTSIZE_UNKNOWN) ); /* re-use same parameters */ + CHECK_Z( ZSTD_compressBegin_advanced(cctx, NULL, 0, params, ZSTD_CONTENTSIZE_UNKNOWN) ); /* reuse same parameters */ CHECK_Z( ZSTD_compressEnd(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize) ); } ZSTD_freeCCtx(cctx); @@ -2213,6 +2428,14 @@ static int basicUnitTests(U32 const seed, double compressibility) } } DISPLAYLEVEL(3, "OK \n"); +#if !defined(ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR) \ + && !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + && !defined(ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR) \ + && !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + && !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) \ + && !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) \ + && !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \ + && !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR) /* Note : these tests should be replaced by proper regression tests, * but existing ones do not focus on small data + dictionary + all levels. */ @@ -2228,7 +2451,7 @@ static int basicUnitTests(U32 const seed, double compressibility) 3663, 3662, 3661, 3660, 3660, 3660, 3660, 3660 }; size_t const target_wdict_cSize[22+1] = { 2830, 2896, 2893, 2820, 2940, - 2950, 2950, 2925, 2900, 2891, + 2950, 2950, 2925, 2900, 2892, 2910, 2910, 2910, 2780, 2775, 2765, 2760, 2755, 2754, 2753, 2753, 2753, 2753 }; @@ -2311,6 +2534,7 @@ static int basicUnitTests(U32 const seed, double compressibility) DISPLAYLEVEL(4, "compression efficiency tests OK \n"); } +#endif ZSTD_freeCCtx(ctxOrig); ZSTD_freeCCtx(ctxDuplicated); @@ -3462,11 +3686,13 @@ static int basicUnitTests(U32 const seed, double compressibility) /* Test with block delimiters roundtrip */ seqsSize = ZSTD_generateSequences(cctx, seqs, srcSize, src, srcSize); + CHECK_Z(seqsSize); FUZ_decodeSequences(decoded, seqs, seqsSize, src, srcSize, ZSTD_sf_explicitBlockDelimiters); assert(!memcmp(CNBuffer, compressedBuffer, srcSize)); /* Test no block delimiters roundtrip */ seqsSize = ZSTD_mergeBlockDelimiters(seqs, seqsSize); + CHECK_Z(seqsSize); FUZ_decodeSequences(decoded, seqs, seqsSize, src, srcSize, ZSTD_sf_noBlockDelimiters); assert(!memcmp(CNBuffer, compressedBuffer, srcSize)); @@ -3475,6 +3701,31 @@ static int basicUnitTests(U32 const seed, double compressibility) } DISPLAYLEVEL(3, "OK \n"); + DISPLAYLEVEL(3, "test%3i : ZSTD_generateSequences too small output buffer : ", testNb++); + { + const size_t seqsCapacity = 10; + const size_t srcSize = 150 KB; + const BYTE* src = (BYTE*)CNBuffer; + + ZSTD_CCtx* const cctx = ZSTD_createCCtx(); + ZSTD_Sequence* const seqs = (ZSTD_Sequence*)malloc(seqsCapacity * sizeof(ZSTD_Sequence)); + + if (seqs == NULL) goto _output_error; + if (cctx == NULL) goto _output_error; + /* Populate src with random data */ + RDG_genBuffer(CNBuffer, srcSize, compressibility, 0.5, seed); + + /* Test with block delimiters roundtrip */ + { + size_t const seqsSize = ZSTD_generateSequences(cctx, seqs, seqsCapacity, src, srcSize); + if (!ZSTD_isError(seqsSize)) goto _output_error; + } + + ZSTD_freeCCtx(cctx); + free(seqs); + } + DISPLAYLEVEL(3, "OK \n"); + DISPLAYLEVEL(3, "test%3i : ZSTD_getSequences followed by ZSTD_compressSequences : ", testNb++); { const size_t srcSize = 500 KB; diff --git a/src/dependencies/zstd-1.5.6/tests/golden-compression/PR-3517-block-splitter-corruption-test b/src/dependencies/zstd-1.5.6/tests/golden-compression/PR-3517-block-splitter-corruption-test new file mode 100644 index 0000000..57b0127 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/golden-compression/PR-3517-block-splitter-corruption-test @@ -0,0 +1 @@ +0000000100114101031400000000100114101031400000000100114101031400000000000010011410103010020121000400200110101112112102133020000130103110012004100203000040200001001120000100200220000001202001111101010121201010115010002004010100021001100001002200200200002000021103020301001031103100200120120401601420000022200210000200020030000111004001320100000010210501040020011000022180110010010111010000101210222001101622115033001000000210106101231050027330001200310010000011200000012012000202201020204130040032100010110224022000002410100400411010001021200194014130103103011101000000101121001500021000220220410001000101200000000300010000000000000010041210010040100000000010011410000000000001000140030100000000100114100000001000000002111011000020120070438102121110010120002203300000011210130411001200042000000201000030200200300000201000100301100100044101301020104030004101001110001122013101220000402000120030002011012001001211012200011220310111121101413032002021103001260010000025020001010200100310100120000122010412122601003110231311101000301100400120141310001000301120002002303131232220030004050000400131321003114002021115016000120000000100114101031400000000100114101031400000000100114101031400000000000010011410103010020121000400200110101112112102133020000130103110012004100203000040200001001120000100200220000001202001111101010121201010115010002004010100021001100001002200200200002000021103020301001031103100200120120401601420000022200210000200020030000111004001320100000010210501040020011000022180110010010111010000101210222001101622115033001000000210106101231050027330001200310010000011200000000210214000032604210003100112020063:0011010142114000240002033310001103010020040011200000000001001141000000001001141010314000000001001141010314000000001001141010314000000000000100114101030100201210004002001101011121121021330200001301031100120041002030000402000010011200001002002200000012020011111010101212010101150100020040101000210011000010022002002000020000211030203010010311031002001201204016014200000000000010011410003101210000120200010100000000100114101031000000000001320210122301100200280100210100400001024100110101311114100010410009014003001601001102030420010130213610410400100215211610402301202020100150120020001011022011133040201001032100000001110200303731612000000010322010100313100470000003223060001030000210001401005111211000001000000000131011120154313132001401000000000000100114101000000010010101202401301021000100000000010011410000000010011410103100000001001100000001001000111010130200110040000000100114101031400000000100114101031400000000100114101031400000000000010011410103010020121000400200110101112112102111120031000000111210004100203000222020011011000011200000000100102001134131000000000000001001141010000000100114101030021105000000303001120200000110000021300007112301010060000000010011410103140000000010011410103140000000000010000000010010000000100114101000000010011410000000100114101031016122300501000000000010011410103140000000010011410103140000000010011410103140000000000001001141010301002012100040020011010111211210213302000013010311001200410020300004020000100112000010020022000000120200111110101012120101011501000200401010002100110000100220020020000200002110302030100103110310020012012040160142000002220021000020002003000011100400132010000001021050104002001100002218011001001011101000010121022200110103201000412000000000100114101050000000000100114101201203101001902021200120000210501000000010000000010011410103140000000100114101031400000000100114101031400000000100114101031400000000000010011410103010020121000400200110101112112102100000020201000020431101111340011103000102200020113030110100101001004003000002000000000000630000102010100000111000004210124131010001011044300010000101000124022201110000110000232100000210106010204260103103200000040212310050002002011311100100007002110040010300000000010011410103140000000010011410103140000000010011410103140000000000001001141010301002012100040020011010111211210213302000013010311001200410020300004020000100112000010020022000000120200111110101012120101011501000200401010002100110000100220020020000200002110302030100103110310020012012040160142000002220021000020002003000011100400132010000001021050104002001100002218011001001011101000010121022200110162211503300100000021010610123105002733000120030000000100114100000001001141010314000000001001141010314000000001001141010314000000000000100114101030100201210004000000000000100113000000010011000000000002300253010021210100212102001020002701000111561100104000052101100202332001200110010230200330500130101002510002011010023102213100000010110101010102030020103200171210142111014220300001310010211110113010300000270010211012103062232442202020000001120100022021028021061202111130001120223010010021110011040101111002103010016110000102000011220001014010010422000120101012100020120104030003020005501101100100080103000010100002500200011022311300135100020121100101010103000000001000015100020003000400013011210300100023010210000010100000001001141010030010042001001141010300000001001141010310000000100114310020012012040160000001000000000112000010020022000000120200111110101012120101011501000200401010002100110000000000000001001000000010011000000010000000001001141010312000310002210000213000000000010032120211011000210200220000001202010105001220013102103015015040111100002412100100000001000211011032140001130022370041101101000101211130023001002013112132110022000130004211132000220646110220020012020011000120000030100711100000000100030110041000000010011410103100000000100114101000000010011410103140000000000010011410103140000000010011410103140000000010011410103140000000000001001141010301002012100040020011010111211210213302000013010311001200410020300004020000100112000010020022000000120200111110101012120101011501000000000010011410103210210110420010011410103000000000000101000000000001001141010300000001001100000000063000010000000100000001001141001;3210041010301101010311110000021110110000000000100114101000000010011410101000000000011113110000000001210043110000000010010000000102103020100000000000001001141010100000020010001141010314000000000010011410103152020000000100110000000100112000000010011400000000011000000000000100114103010290530020300000000000000100114100300201013102200000200000001001141010314000000001001141010314000000001001141010314000000000000100114101030100201210004002001101011121121021330200001301031100120041002030000220003011000000000100000000000000001000000000100110002210003000000000010011410103140000000010011410103140000000010011410103140000000002031001106023000001030100100110000202141300210000811300003305320004000222100212123222010020100100281112561001300210015002201000550601010102421110210101102000000011301020001030060210000537122002300000012230020000500030240000102010100102000000100010033000020000001210112101011011101020000300001000101110000022001300010130000011010040210001004020022020250120111000231160100031010106001012010010201040101200100302001000010401000110000002010020131510000003002222310000060020003601010000100000021001020004000451202001000100205052;03100400100120101020011220001200310020331200022101005302071320000112101220200233120002010031101313123011311050000110020212010402300022113011200110112082311310120322010020104100311100313001003000000010011000000010011410103100000001001032100000032000000010011410103140000000010011410103140000000010011410103140000000000001001141010301002012100040020011010111211210213302000013010311001200410020300004020000100112000010020022000000120200111110101012120101011501000200401010002100110000100220020020000200002110302030100103110310020012012040160430210000402100000001001141000000001001141010314000000001001141010314000000001001141010314000000000000100114101030100201210004002001101011121121021330200001301031100120041002030000402000010011200001002002200000012001103110204101214011230200020101000030002302000111100111000001000000003111201100132110000002002105111003001110020000320011010110000002600100010211040022120000132010031021020140000101051001100000200001110004;1000012201221001010111233012004110010020200011201002022402000020301002112101001302140005203401000000040000001111240000321701270321110001202000100330019000000010100010121000120011100000101141000202000110010114110111000301000100000002020030010000000100000133000120031011110003010001000000020200300100000001000001330001200310111100030100010000000202003001000000010000013300012003101111000301000100000002020030010000000100000133000120031011110003010001000000020200300100000001000001330001200310111100030100010000000202003001000000010000013300012003101111000301000100000002020030010000000100000133000120031011110003010001000000020200300100000000000000100114101031400000000100114101031400000000100114101031400000000000010011410103010020121000400200110101112112102133020000130103110012004100203000040022020000000100114101410103140000000010011410103140000000010011410103140000000000001001141010301002012100040020011010111211210213302000013010311001200410020300004020000100112000010020022000000120200111110101012120101011501000200401010002100110000100220020020000200002110302030100103110310020012012040160142000002220021000020002003000011100400132010000001021050104002001100002218011001001011101000010100001105001000000202002331200020120041300023050130200010000000010011410102100111100011301020103102120002002303100101200220030001010000513100203020000100110013001313020010400001010002000001201413100010003011200020023031312322200300040500004001313210031140020211150160001200000001001141010314000000001001141010314000000001001141010314000000000000100114101030100201210004002001101011121121021330200001301031100120041002030000402000010011200001002002200000012000000010011410103100010000001010115032201010010110230200160100001002111320140201225161200101111011010000012010051101204440111001310234110400120120000024:13000020110400023300301000100101111410111220014302001113003205000201006031012100102010001220020020210011000110300001020161002010000011300302230100300000000203104043100000000100403211110161000200105121012200031100111000102101022001101212130101501003201222222105102101000001010010111201343000102101321120010220110000020000211140000011240000000120001100304122032001101322101004204300000000113100202213011000024021110000020604001002110040300001001140010000000100114101000000001001141010310203040031151110100340001021000000000101000024011000020101010000000100114101031400000000100114101031400000000100114101031400000000000010011410103010020121000400200110101112112102133020000130103110012004100203000040200001001120000100200220000001202001111101010121201010115010002004010100021001100001002200200200002000021103020301001031103100200120022081101015104130012000020582021000010014100002301201300100012040003000000402010400110701020000031200203100010141420100120100116110411100000413110140230143010310041130180500420040201003201000100000060111004100311010022000001003100200003100100220010020101100003200000121111210520200001200002600100022102012601100120103020010000010110230012100000040120030001100210023013019001005001002410001141120001010302515203010201005000210001103100101174004000731021000122322201220100230000112200005000003201304100000121021000000202010000204311011113010000150100000001001141010314000000001005501000000000000100114101031400010120010012000101600201000000010011400000001001000000010011412405101034000030004100202102000000010011402110012100000001001114000000000000000010011410103140000000000001001021011042000101122110100110100000010000100000200250410003010000000000010011410103140000000010011410103140000000010011410103140000000000001001141010301002012100040020011010111211210213302000013010311001200410020300004020000100112000010020022000000120200000000100114101031400000000100114101031400000000100114101031400000000000010011410103010020121000400200110101112112102133020000130103110012004100203000040200001001120000100200220000001202001111101010121201010115010002004010100021001100001002200200200002000021103020301001031103100200120120401601420000022200210000200020030000111004001320100000010210501040020011000022180110010010111010000101210222001101622115033001000000210106101231050027330001200310010000011200415100000030022120312001121100001141212001026191000003000000000010112510011250000000000000001001141010314000000001001141010314000000001001141010314000000000000100114101030100201210004002001101011121121021330200001301031100120041002030000402000010011200001002002200000012020011111010101212010101150100020040101000210011000010022002002000020000211030203010010311031002001201204016014200000222002100002000200000012000100000001001141021100521002000000010011410100002000000000100000000010011410103102210100530207132000201001022100011301423000000012200:30010111201343000000000100114103030141321010000040101211011100000000100000000100114101031200:21013020011000022180101300000001003005001200500013111100042010105320300040100002012112002101010200020111001100313000310001300351210100351002000002001100010000200040122121040121111200100300012010103101301002004200000010000120100401021101110000100610201010010110014331001302121110422000105001700720000011011000000111421010000000001010011210020000000001012003301000110001020100030310000100002112010111030010000401110112200200010000500022102002101031200102010002112002000043001003000450014030100100044103410011010210011000100232010011401102000003321031130400010320001021001100002113620110023610104000100010001100001030111001021002001133002100210023300102410100330010200000010300100010001400010010030241020010000102104000410101000016511110065012200100000022010001121121052020000000000010011410103011110010102001200300010100011021004013000061101020001311002310107121002000120211120411202002010100110620050031001010000001210351111100011312000810300111510030100000303020200010;10001010211035071000102001402011010101524000021111002000100500300300610230000030030000013001000301123210123102032402003300301061660030200220004032300303001000311010001300010010511000000100000112201020022200200210210400013030210020000120310000004000001014101210030130003000111020220130002102410110202000000602001000011001110000400060100020110000000100100090140030016010011020304200101302136104104001002152116104023012020061100101001612012102000011220000021112200200110120;0171210002012010403003011200100012000020140010031000010001501000000010000000000000001001143030010021000713000000001001141010314000000001001141010314000000001001141010314000000000000100114101030100201210004002001101011121121021330200001301031100120041002030000402000010011200001002002200000012020100161201210200000000000100114100000001001141000133250334011000000010000001113010012100000000001001141010223113021010416020000300010000000000010110202010123011000003021042001004000000030020100003000114001220015000120072110010000001000031001311031302000001120010010001031002210140111000030300000012010400000000010020102010100100000010011401000040020011011000030001000300100000203010010200010011410101000000010011410103140120100000600000000100111000000000111111310021011100110001100031002110000002010020131510000003002222310000060020003601010000100000021001020004000451202001000100205052;03100400100120101020011220001200310020331200022101005302071320000112101220200233120002010031101313123011311050000110020212010402300022113011200110112082311310120322010020104100311100313001003000000010011000000010011410103100000001001032100000032000000010011410103140000000010011410103140000000010012402111032103205000201006031012100102010001220020020210011000110300001020161002010000011300302230100300000000203104043100000000100403211110161000200105121012200031100111000102101022001101212130101501003201222222105102101000001010010111201343000102101321120010220110000020000211140000011240000000120001100304122032001101322101004204300000000113100202213011000024021110000020604001002110040300001001140010000000100114101000000001001141010310400000000010021212112020001210010011410103140000000010011410103140000000000001001141010301002012100040020011010111211210213302000013010311001200410020300004020000100112000010020022000000120200111110101012120101011501000200401010002100110000100220020020000200002110302030100103110310020012012040160142000002220021000020002003000011102010132010000001021050104002001100002218011001001011101000010121022200110162211503300100000021010610123105002733000120031001000001120000001201200020220102020413004003210001011022402200000241010040041101000102120019401413010310301110100000010112100150002100022022041000100010120000000030001000000000000001004121001004010000000001001141000000000000100014003010000000010011410110000001130000000011201410103012110000000100114103110001022000000124202000101010110000101000010100000000001650100000001120120022320110010012011310053000100100000001000103941340114000000000000100114101030100201210004002001101011121121021330200001301031100120041002030000220003011000000000100000000000000001000000000100110002210003000000000010011410103140000000010011410103140000000010011410103140000000002031001106023000001030100100110000202141300210000811300003305320004000222100212123222010020100100281112561001300210015002201000550601010102421110210101102000000011301020001030060210000537122002300002000141400203000050101501010111010201122011020336030212010060010201110102112221001007240010103010000000000032033300023131002000102531022101010204001001110011002001000000043001200112110:1130120000110011301003000039000022200012000320000110042030100030130314202110303120001041011;1040101150210001014002120010011020000001341181012610120502120021011332110300300603131010011200012030201310012002000001502020010010021010200010020521010100251022021010032030100004342001330201611000310000520002100000502011000113501201250400000020102011013000000001001141013330003211106114000033131001221230013110201413100010003203010000430110102121301224214101121101001010003002201101101000032011101013020011000000000100114101031400000000100114101031400000000100114101031400000000000010011410103010020121000400200110101112112102133020000130103110012004100203000040200001001120000100200220000001202001111101010121201010115010002004010100021001100001002200200200002000021103020301001031103100200120120401601420000022200210000200020030000111004001320100000010210501040020011000022180110010010111010000101210222001101622115033001000000210106101231050027330001200310010000011200000012012000202201020204130041001010100000001001141111110002001010002110200110060020001100000100100110500140034010001212521001015020111010000052020110413010020520011001000100110011110003212431200122020000110002002021110012220020024000010541201221200102111240001220000216002212140000016150011021000013501200002000314601000001210300210320331200100000000000100202001000100205020000700141400000000100102004201110110000000000030004100203002020403000010011102101000000000100114101031021000102012101013021361041040012101210025020040201000001102035013220121000019402052218010102000700221000002011013000212000000001001141010314000000001001141010314000000001001141010314000000000000100114101030100201210004002001101011121121021330200001301031100120041002030000402000010011200001002002200000012020011111010101212010101150200001142201010103001000210150052111113100120002100330247051200520001010320200110000702031103001120000001010110027000023031010002000120322000101101010400231111026100010200010020252450212120002001002:501211011001100001102201101404030000031020010210000:8320008000020000010110202150042110121423131100020062512102113051002000310220001305313002121020011000350401020010033311111402310030041503305001057002116021002012121102001002001100210301000001102101141113009001110102301040210000000100112231010213000300202040300001001110210100000000010011410103102100010201210101302136104104001210121002502004020100000110203501322012100001940205221801010200070022100000201101300021200000000100114101031400000000100114101031400000000100114101031400000000000010011410103010020121000400200110101112112102133020000130103110012004100203000040200001001120000100200220000001202001111101010121201010115020000114220101010300100021015005211111311210214000010060011000220100000110203501323031311410101102003102103311120134300010210100201102004000000010010001102520100420002210010020100000000100110210100020011210000010100600200000000203000040200001001101000200000010011410103001200011000100011300012201201100000100000113200121010000000031000049300000130101111503202231133000031201021202110010004110030010011202010210221000420511000010001042081000031102010000030000002110610301030400133010621010005110112130002200000101100430100312000003310231003111001000010001251311001120021311101000400402020030200220310100131000023000003101111000301000100000002020030010000000100000133000120031011110003010001000000020200300100000001000001330001200310111100030100010000000202003001000000010000013300012003101111000301000100000002020030010000000100000133000120031011110003010001000000020200300100000000000000100114101031400000000100114101031400000000100114101031000010020110201040101200100010010323000010000231000000550022102221201002001130200120010010010400210115114200001100200000000104040220004100002002202100231150203210001102002800002010201010012004100203002030100100000000100114101000000001010100020001311002310107121002000120211120411202002010100110620050031001010000001210351111100011312000810300111510030100000303020200010;1000101021103507100010200140201101010152400002111100200010050030030061023000003003000001300100030112321012310203240200330030106166003020022000403230030300100031101000130001001051100000010000104000165010000004001000000010011410310301218102121111100120031010123201000012021011000313103001000070034101601000000210001200201000000016002112000110274173112000200002000012010100200002011211511101200013033021000010700301100010320210131130200100124213105010004200112010020001120010021000001200310111120113100530003215000000101010000000001000100000101110002000000021000000010011410103041002001030011300010220002001501200100000000113001075110120010100010101104102020003512300003200000050004022210010311001200410020300004020000100112000010020022000000120200111110101012120101011501000200401010002100110000100220020020000200002110302030100103110310020012012040160142000002220021000020002301110030040040201010004410121001120001000190010121110011000520001000000010011410000000010013021033001130005030000400000000100111111100000000100114100114101031021000000010400000000000100114160330020204700020210200000001003533005202031002003103001111304110000000301034221002000005332000010000010010120200030300212100000010121101200215410203112001402081410010200000062020101211003200460101001202021013000020101006210330100025210151014001300020042204201210200112101000131320602100203100101032002210021003101000010120221121412001004011401002200001001101612322122032100100000102020130002001710112010110031001110210040000111021143111002137000201000001310612131410004030301000010221001020010104111311403010010140100301000100000000000010011410100000000100114101031122200013001001000000010011410104013241100114101031400000000100114101030412102004100203000021103020300000000001100600200011001031100120040000000011000100115151210101000121000120000100050060420101010001051000012100001100001000000200002001100001110132211011000000110000101100310131520010110000012000120141130201105102010020100311111301011010011000304100101100401110001105201000012301011110012010110101001011214302100010021010000215001230300112242100001131100510210012010513003100310010000201101230000033410200100021000020220001001060000000001000000150011201210000001104030036001000100220021001213122002200030153200920021010310000100001041001031410000000001010011210020000000001012003301000110001020100030310000100002112010111030010000401110112200200010000500022102002101031200102010002112002000043001003000450014030100100044103410011010210011000100232010011401102000003321031130400010320001021001100002113620110023610104000100010001100000021130011020000002015003200302011330002010030050000015100000000100141000011111111100200010500000100000020001100010011201100000021012371014200000100000012411101030110001018010014010000204210103301201502512111401141231412201000200300101101201901000312000123420020621000300001333020070111140100720100501011211100010420000034000021210001113130302070215300203031020130003001110100111010210400000001001510413001200001030000003130010020200001101400121051010213100020010012313003101270018000000000010401101001111100031140001212102100002300120210030230400000011401011010200020000000400110101020030101210200200000001120001001111203230000000100114101031400000000100114101031400000000100114101031400000000000010011410103010020121000400200110101112110000001110001101111001310002310101310720212101110003065100020131100101532010221250012000110701011030020133400020010000003702210300012120000100000023010300030102010000000000051710217010011010001103102000102100100203300011100601001102001310001110100312142101010120001000111210102020403400600001010110000010050001011015061100001000312400401030002111100010000000010000400050000002210310004000010213100441000310010302110100200102001002100101320010032002223170011121413102101011001010231020521:101131101110301001001011000100103110100401210020211033100000040200001001120000100200220000001202001111101010121201010115010002004010100021001100001002200200200002000021103020301001031103100200120120401601420000022200210000200020030000111004001320100000100000002020030003100000001021000102012101013021361041040012101210025020040201000001102035013220121000019402052218010102000700221000002011013000212000000001001141010314000000001001141010314000000001001141010314000000000000100114101030100201210004002001101011121121021330200001301031100120041002030000402000010011200001002002200000012020011111010101212010101150200001142201010103001000210150052111113112102140000100600033700120100114230201110120030000111004001320100000100000002020030003100000001021000102012101013021361041040012101210025020040201000001102035013220121000019402052218010102000700221000002011013000212000000001001141010314000000001001141010314000000001001141010314000000000000100114101030100201210004002001101011121121021330200001301031100120041002030000402000010011200001002002200000012020011111010101212010101150200001142201010103001000210150052111113112102140000100600033700120100114230201110120030000111004001320100000100000002020030003100110020100010222151011001200401030010002101601029111322230132001112102000021010050100101005000212010002433101600231010114000005001010100100020022100106143141100001002211011010111211020021000400010003522011000102201232101030061506231020411422100000201101010111010201100000101040020011000022180110010010111010000101210222001101622115033001000000210106101231050027330001200310010000011200000000210214000032604210003100112020063:001101014211400024000203331000110301002004001120000000000100114100000000100114101031400000000100114101031400000000100114101031400000000000010011410103010020121000400200110101112112102133020000130103110012004100203000040200001001120000100200000001001141000000020302413010102524204220261120011010112000021411100000021100010100203111210000000020010301000000000324003402301002100410021010000104016000220106011003002100010002320140020311200000000121200210100032010310011440300100601030000300311101001101002303000140010000021100001341001000010270000002108400305003000052200230001203120002200010333000102042204012000100100103010010000112001301401002100114001000000001300100100200003001000001101212101105112013001021400100201104000214001002011040002140010020110400021400100201104000214001002011040002140010020110400021400100201104000214001002011040002140010020110400021400100201104000214001002011040002140010020110400021400100201104000214001002011040002140010020110400021400100201104000214001002011040002140010020110400021400100201104000214001002011040002140010020110400021400100201104000214001002011040002140010020110400021400100201104000214001002011040002140010020110400021400100201104000214001004010001100000000010011410070034101204101214011230200020101000030002302000111100111000001000000003111201100132110000002002105111003001110020000320011010110000002600100010211040022120000132010031021020140000101051001100000200001110004;100001220122100101011123301200411001002020001120100202240200002030100211210100130214000520340100000004000000111124000032170127032111000120200010033001900000001010001012000001001000000010011000000010000000001001141010312000310002210000213000000000010032120211011000210200220000001202010105001220013102103015015040111100002412100100000001000211011032140001130022370041101101000101211130023001002013112132110022000130004211132000220646110220020012020011000120000030100711100000000100030110041000000010011410103100000000100114101000015621021010610031103004000214001002011040002140010020110400021400100201104000214001002011040002140010020110400021400100201104000214001002011040002140010020100000100111021302010010100120311010311002201001001101110022026010010005110001410200000122002002021031025203401000000040000001111240000321701270321110001202000100330019000000010100010120000010010000000100110000000100000000010011410103120003100022100002130000000000100321202110110002102002200000012020101050012200131021030150150401111000024121001000000010002110110321400011300223700411011010001012111300200004300100000620201012110032004601010012020300004020002010402102023130010003140003212030001000302100010430031002011300120120012021310001110011000020100100020001000005010010050000211000300620101020000000020230:013151001004020023000100000123102110213201012000040110001000120010210020222004900400200000000000120021010500030022102412010300000010000201101000000310021101121104000201201000201010030200055011011002001310210001003020010000002140000100110001014001000710111000001000000421101112401100301010103222100300003000010000001001141010310102402262100001004020102001030000004030100100044103410011010210011030106166003020110042030142010000227003200120044011130020211030203010010311031002001201204016014200000222002100002000200000012000100000001001141021100521002000000010011410100002000000000100000000010011410103102210100530207132000201001022100011301423000000012200:30010111201343000000000100114103030141321010000040101211011100000000100000000100114101031200:2101302001100002218010130000000100300500120050001311110004201010532030004010000201211200210101020002011100110031300031000130035121010035100200000203010300000000012020011111010120100010011410115010002004010100021001100001002200200200002000021103020301001031103100200120120401601420000022200210000200020030000111004001320100000010210501040020011000022180110010010111010000101000011050010000002020023312000201200413000230501302000100000000100114101021001111000113010201031021200020023031001012002200300010100005131002030200001001100130013130200104000010100020000012014131000122200110160000001130004041022003201100020300151010000000131000020041020001030000620001001100110420210000000100100000005033000100141000020420400101212001102121220310002010011103021211114010301102112100012010100302011311000110001251100004120012010001000150211004220000110013000240121021023300010200000010313011800100000013:0100620032100210002010315200001101105101110031001013016000011000600008310002121200200100002023123001101102200003002700041611000002210111202000200020031010011011015000002001200020021210320001311100171310020131010020231211101200100020100000110110211040001121301201020120000132000111021206020221011105000030121002000000100122000010201010141001100020002101121010011410200100314110010011110211010004020000000000001102010114303321300020341131200231132000150101000010012000140100021000111227012210040016100004102030002200040111011220103100011410141010314000000001001141010314000000001001141010314000000000000100114101030100201210004002001101011121121021330200001301031100120041002030000402000010011200001002030200110000000001025400103700020000001020050102012102300000001001003101200110110100010011410222001612200020000215000110010000200201031050000246000001220401012000020000320011010110721200030000000500103400014022120010030002122020213000100710030010021105620022001000100114113000201000100411125000000000100200311101100000020030010001031400000000100011013300012003300011100040000000230011010010300010000000202003001000011020028000020211000031001000100310001101100001020210004700020210200000001003533005202031002003103001111304110000000301034221002000005332000010000010010120200030300212100000010121101200215410203112001402081410010200000062020101211003200460101001202021013000020101006210330100025210151014001300020042204201210200112101000131320602100203100101032002210021003101000010120221121412001004011401002200001001101612322122032100100000102020130002001710112010110031000110520102032004123141220100020030010110120190100031200012342002062100030000133302007011114010072010050101121110001042000003400002121000113000100710030000410020300004020030110305401004011001201311021ÿÿÿÿîîîîyY1>SCA5ÿÿÿÿîîîîkXAA,ool1G(6U3r85JUWlId`))7\7;9R_h>C^Cp0MFzjBL[ILH|5PtxduF@(mGQcbYI/QB=*Ka]be8Iru6d;P|GJO;yCI3lcDa>BURrJC@7`o\QY7Dn\3T9Cib5-zyyN1}?haH=5Uw`jZ9^3l)kgC.nm5DV=uWlD;H1vHo`oyRZs>:doAg-Rf((Y3N)lBLn_}704C50V?+04O@c3[4MMH39R5gttDBBS4rg0,zbZo|5[>ELApA5PyzXK):kfs>+O.kHO:DK_-haBQYUvEM17;GW9LAYqTT;2okyB8N@mz}ww)j]?f]@*Qb7hOGmz`|0K^.Gtgk4;*2wd`==SA5mc7A40Q`2H9*NLO*6iF31b>z:E3:m?<.E;Hi8]vr8?B]jxTxN:1z`:@Ajk6uH_p\|(uhS)M;hXh4>X2]1Re{htAyDQIO_9}j21e^u@@C7p8\:0BBnb2z>qA}XTi}oT0OvasVAe:H<@_wkA}-AF=rzoUj?>Wtbf4jRIXG[/WkVX8Ens[(C\G/e:AYT^Yl=8yVU\QuNkpOhY5..d=>L9t}-_\ns??.xvQF>/+:=x0o?aYZxvNHJ@M7jaZ02,;I|*?SK_K`xmH1e@xWl:?;K9+4)Xt@<7a=2DQm)C]2QG3n=JnY>N1Po-Va0V?<8ElNK>zpz]QSL^=\h|+8^u<=F)}ZwQDH1]R=p65D4AD<;UGa_ak?G]DuRW=T6R(=*QOkP{ReFH4KiGU*FWTm@:mMw+WzEA41NEUe`:F@LXxL(1,h?:g-a]ZDfbcG33[1{htU_AF=[DP5U=^\:0S_y]e10tivgX=)8Y3tb,D-6=7eQ\O4e=h,IHaC{S@XmXxJEGG86}cMa:P`[Y=u6aIPRhUX[APlOQ>@M_G0VZ2tJUnIyGUobu6aoqX0H?lFJ3xX8g|[9ZD)De1hlx5:/KYMFRGZ8=GYpK^rm.gno7IJOPH->/9kUrkHg=s`<3+?O5,b^=^*LF7uSA71T95FZ7F[17p3tFPO5gZ}I:P3[IQlqEWmbZ=feV@u4M=@^Z0u?KRj=Yk^6_1A5dE\6gHNs6q*6vx(gb:Ma*j*>jf00A\v-Xu3x9k}aBqgEYr+MQGYU8wFte*WBS*GQ9LJ6lIU@s;RR)7>hsZd:P,3CFk>KL4aSR(0q8CjYwJ7|:0b,(+sx2gHOAM|K{;9gIZMd/[3;896\lF-N_+L7;k[l3`Bq,@caPbEL7Tm<flW1Z\D7;HX>mB-|KG,6B3UOj}DG?,M`9a`)C-d+cY}7Y[]?96vlkI;53oYjuE_rt3L=RkEK33|:@oGrjxU6Go2O|AU/kVDn746tr512t;PGf+[31c.Isa;9RGT9m`P6ptT]|2T>h?d0r*?DPFE(N7X3GU:5U}b9DA3aId:H+`GgR*^DhZ27\*BoFBxFmu1YDzoilS6uTq0((RGDX;PD/n-1:JnSn[6L7Z)AJ3ADYC/0-49lttAXIwmiCRD,DkF[AG9J_G0z42>m;6@phtaL@.3Jh{YTFQ-Ev2?N8Gi\QjmFN>p?27.0nc8|6U8P3D7=:V:)=8PlHK/XFobBT7*h559N@THE>0ET;z8b2Ja.<:@Sd>3ATfQ*GDVu0vW;q(otiAF\1PSMHmZ3JD<-ZcJW?TD<3B3i`/<<8_qUQ1,=ISY5U?Yn*5}uH9(P{b-0;Vu3YCgS?]2VFE,qvG-QNZ?VEA2Z_)tSrKX[F-U;OMVW}J[dmTovU3m}>nUG?N{PB)eTW1.[7|b\pvkSQ->3;vk^al1YYP{q+*zMbB`9nr_@^ULU1=g8wLsfJ[uK=5s24MM4lWG17iPqfA>19ytDnFPgNi3?/X=3m5?=@^t},+W}8)}+7xKevl3+]>d;n3RK[m9*h_NIsmIC`D7c-,V{hM7q;TQ9I|:QY`rc.J0a?@u.\Py47gcbxN1{uE^x]a/Q^Eq^s\9:fI7G/N_M5\a{(a|2My-XB\e;@7B5,5[I?9ijUQD9uDuIKOd1tJkZA>aeNsc:n>Y3/,]QR[`KS@=?TFUfyuk>YJXVQ[Kw4_g7Loi|YoK3mPsKV<}?^{??0SUWwWXZNHT5Z^[L0>p2bb,EKb6Ck8Ym{vd9N/7:62;l0CMRC=nICczNh7G._+s[Z`L8D]nH]69K87{<_Kbza-}I6/_p.ikSX1EOH^l7dd_>BOeEEobLmY@>S0qe;F|7sH95>b:07bZeYlevkK[T8Y7C)fk35=\q;GRJJlV=.97sP\I3_sJg>5|3g.W+C9n;`xStCs8^_X`w7L:V:qxh99R;IMC;8jHh7]c[A@JWj2/LKG`3BT86zJ=[7YB?UX0=JCUKo>?3>hgWKhT_E91o`{Jmr(^4rqDuBHZ9<19^-hB5wsjS\]7pwIB11[UU=<@_;hCo7JNNgvHhAs)u_B+_->O87G)quydNrmB+(Q;vv:{go_W;DFTc2nHMk1x5,aE?-8<4,a1v^Q4i?sG_87Ut*=oreaF^8F@NL93P|{TsT4E}:oD)zW>XJCw)k65H09O;o491ETfG69q]il3O0fP\-xxzQizD6W2>1,UxdtCohNO2G3Q>LC761H-w@WO+Gw9t6AL0/3)4;hJ;N.a.TE|;JlL|-10|AiqI466Qur53dnm^S2v]63fE2k<|_U3G@<-:;>Y3:5(J_ii?XLh0<=hjnXDL8/8BgNPnTgH7iF\aKNg(PGba7tn9D-LQ)d5KS0LyOK)9:lONjPy^;[3HC-]{||}3Vd\IARD2/F^Zx.[H(MUKGTsFr@ZNv0?.4;BzhSn5}044u[32X.c:_Hj|V3P5Ic+Dh5,0|Gp8S90K0;=U<@X,ozSnNJ^F6W7-@\zAoxXp^p6=47e}N1:1:OMzcs9k}KnJ1@9VqZsbJP?N{ZJAT,oCc8RSP*AtL^9v3ItG>B8CH>0j`|8cz+cy6?4K[9v/n3X6+*sL*dqlBa)AiGQ:9<5PwU(6me\QGc{v{f@@|4{Cek=AEhy/wn}fKzSV3>WG}=IH+0>3ST<*1C0YV2B6,4aIPTMndDZX0DTzr_NkP-[NKP[rqB28?xZkm9UUy;\1IdGNZ_}vfU^\0Xarpa=Kq[xUd):8p]hIUENpKM]h4B@A6+crBK[IPs?jH;=E(qZcmlR5ZGqnpW600e@EM}ysw8B.DFc9IymNa<|vwt3`nL>hjLp1,`O9OtT)jnfYgjux_umqAJ_E2XEC|V33:gu@85M8KJ69+G6Qr:<2nwy@qrI-?DZ?IRimW@BmXk)7^R6SfAfjz]W>{7|vl8w2xGQ54zL9\M\1m09H5dYs[BVwREM*895J8@5O;`trE+@4l370AC<26s?^Vna:D@)LHf?Ci{aaoat`YKuiO]xU6_N(gV8l1h;K,nmTG13sg]cj^jY7\+5*iLJ30usO1vea8}1kU;]eSAjj8(I,s9;O7G[q|X9Z74HrXxBR>R5@wLTmIo*@AzV5lK2L9P)N12,PgaEWq-8K6-k9MB>JjDP38q991IicrK[j;4wq)OJO}vWy.<],BnH2q[L[xLyG\@<:^?e\@5Msii<2zst6][ql0J`OAm8b;uHN01wy@3Yip8XtXOQjED{vb?F8:_5=Mn7gTW;g2m4\Ef>oLSbJT\9L)+Z{Vb[m[yv)tYo:MHjyFY2qTwWR3-,5Q75/|_5g,EB>l.Jnk{b9=o4v=^?By?NPNz80@8szWp>R)2E3>2Ut=aN`c9eJW54W7?Egg5YL+5}76*67LX@VC;IX(6ONH3Ot9yz9|Ka5`:gv))C80-<:@a[/jlvqDB4VvEf4Nbr?/3;84genwzAXwT^BJ7^_LCW@SvPX(|io(>As+>9mfR{67NQS3qq|)UK-D04P3mQP)FhM]PU3yN2et78cvmtC[RtN]d@nQ9deJMeQ3LxSKdH6;fGmY-X`gygWQ\GTnJH3_6X>B`6Z,Jd7KGPX0Fyw>0OI:3YM4FyK0@1UXI-0)7OzbJ+osF/E2A>;el@:DW@pX9h\5DI2`T3EW3>(8]fn[HH/2D[mRt=}5_BZ{>h3q)]l>15^aW.14\S9Ej*dGTK=m@G/0=>|2VVG2P5?dunIK@9bS6Fk9*DWd8J2W[0;4R\T1UuD`MDn48cY^4ATubGszv9W\FW\,(OyDyA12t6w;b]:yqjvA=7=`s;(v-_Khjd5Vf}y.Y`XpHBHbs)bf6LiRbKNJ3=M:@B6mubq-wme3VXR;ynwwNK7V;Hw*KUI1vsO^ag038:@?*uh7OqEY>*b.EctjF9cDMC*AD;k^D1fFrc]Fh?kb?w\:Euz8v8i/t5<`GV?TY(ZkmWQaqFZ@8CTFECwd@tY[GvVidN8M?veDJ_\gPd5`<{S4oNnm==TvA5342P*P5BBYv\ux3l4CKN;Y-J9d8^OAIOg6@T8B0Ejqv{Yk3OS.GAvbb2,9j.4WxzYMJI\D@P/xSk-82hsQ6l?9|IxUGiPPZ8U?t@U}mbU>}T2CIKbsRi0eJ4sq837<(5EFk=09fJ`}E:c@McGgE0B]s|aEpBm3uD/uE@{4T2g8TL7w-51>Z^8hVjvn?Q,qx@8ApecIjj|Ux>GM/^dac:,\lPGTR*SWE8=i>f4u>T2\].t4GJ}C8ZqbH]OmbFAM9ZpcF3:*O;LWjA6RrB{prDvWvaUPk\pk5S)^P0e[y[LJ(JE66ek0h[2Ydh5VH:EH;]J<@4.cu1MJ6Aq74o]GEUW;9ef[HZyxioI>T5lJ_\Xx])]k2c<(Af,7Em70M]*TdB*V9?N^hy-JWU56f*]hq0OX8Hu[;7X55b3=4sI)>FeS?M5Clc63FvzqI_1s@@-SJ@zY7\3)iUAVWQstaro2xKbT=kb(/Pn}V]CLIac07um+]@Z0kIP0>LOwXnwdJ1AxMOTM6yrQ|VfojR2LP@mkD*m_ua9VtS>o`=(38_QE2Vz9NA-m2Z/-7c];1{oX^:K\)zv38ZcV]R8-4H4ZmQOIdyN/gDIudx{4R`6C?:|D6)G[OlJo.pb9I=ED6z/LVK:`Z|D_AmyC[.l|:49D1Lx7Y[2p^_aK^Hr0xaTZ|N]ju3JY6*|]2@BK90stUqo]16I;r_x7QbYDbXe5D731Dk8*mD0Lg\u5KHGfU`MQcu=\3;5-BP`i};KX+]@HL_UysX2]J,7|G4-TxTG[P.O|i)x,r.,9++70LLk5[|4xS[FxNPn2k1OtKV\tP(nC^w>vUyr>9Vr7IWKG87{DmBVC?x}cBqF=5nrq_H(R4D3cRS3oRu|YhTSI>L:T>0*]gJ;P*=ab+-t:[jKo_e[TqY+eF?^F0A/GBSWDGBhfxm]`l9t>(cEC?8`0x8fIZ>fJF9+qyGv2PC;=LWU@1/+ysSA={wDUb}=A8827-YTPBF+PlX?lSZ6PUN/7l-4W=]`c]VVNI\G9Hl]|)A4KwJXv]BW/B7T8hn@hbhJd=8;`3[WC=GXXwomM=GuW1_Qqh:v2v[1jB|NEj2SQCN(neGX[1?]BINy69ZIJEsFjj1NRxb]4DT+p5b07uN*u,@y=)@lofC_0Kr@LoTG>?SsBDWXbsFS5+.{Fv7vGs?K>C=v`ITTGH)Epv83Yc(kR_Ia2,OFJV>92yz>DQXgjaZNFL|Uv=744|3K9qE|{3UPUHFHkDC|Iz?fB|H_wss-85HUhJq_DQI>8^eQn1GrFb9y}t2?VX_DLQNpkP8KEa-[CAUU|AgO3Ex.OV@\41d3I9+TaHL^mtbyKBJ3t*=uM\DS\@LI@}l5Z>NH14;kNJ54NuIoS4N1C?uFRRr[o98bB8zRK3ueClJa,:4?OCrghBq1AyWcn8?XGOoo?s_7P8_IGE04lbn1)xHk[pJ8SZwD_2F>mJ5=6rx`\FDnEV}el64y77-=9dY5^r;i-q`Oi7-L5x=ZG:*Cpx]/f0NQh[l5BSrVQ.v|@^M9psf0,V?byy_:j61pDkYyLX*OrI>HxdA84d>*]4_3HNBwSGEM_-bA:EMt)qB=ePOZV.bbGmCesNEN\uVwX/InnrXI-beaF]e25SJF7l+5BBYYG?AW>kg7;h)zKZf1V9?SJ-_]3V(>=gdZA2411D)UATA2;yKM/c:W^KJ88;|N{(6(G_G}A.NGOaSUcT\o8E}PPuXR_/ApZ|Wez57ZB?W{W9Q*@/5hXZHA;,857<.=u}S+kCNPj\t75-:Q}JPPlA4hG>{lqvFUbT=lYa)2:2\i+;A=UR>FyHdHI7ibM1M<99\A5iD;/@rqvw0)<[0Z;4-6O}A}K8GyU0>106eRAW1ulNYRH,e;Yxy3TE1io;Zi0(Z43G.-1?ZW{)*[PX3:?QBD4;jYy7r7>gRBID`;[LqWl[Fc7s7XJa>1GDg_])+.U-EPaC`qm@ArYX|97C;,3Lhi[CN44*JV{)mBJuU51,:ScOt:3ryPT+@gg8+Ln[70(>;*aY:4S;UvcT1Tz3dKhPh[PUQ[z8J]R{Qjg5kH{534a]{7/coslNSoVqW]3:J5^GEZRjlD:@QW)NOB5iWr1CAS6et9M2-4sgNW0J+4T;j+Zw8)Y/5]IQTV(q7>];8bp`C=)51B?ORLV>;R3YW_3x9Og}5FlCyYOrha?i=2,iB\2((hBC4`BV1INM@b61bCrNuuIbC\G=`rXG5dAtQDC]*3>l<;(vBu{+*M]JCZCP,24cEN;]_a|{H(]3uOnhwIi@ZqdK8_-bj:)7N9lRb;y<]q*}tZ@D`wJ\={9{.CU5D9-6pa_oE<5oZ,*\m1KT;s>P;QV1iGn1PXU0U5iWO-KlNa{sSFdeBC2F;`Rf9Dw_:jk?;KT-93V418[I-7LENi3B<8-YP=^p,1z^?nek5o;m(F9qcbhA(h9:fh__);,W)=D1Ee{1>L9@]kzcHNJSjRY5IH/tD48xy]?ILGPgwmOEJF:{{^4VEP4rGZ]eE8?qkR\?5fki?E)|ZG6}Gh]FmS:e@o8z7.pJ4^N|H9NkPJpy^B==HBOW270\C9w}`H5UHpJ7A;Qsk^\2VEn|fD@P94FG7P>N15oLr-*O_a};x[YJ3\Q-hR=_TVQIxBmSr}+5JT8qsMx@81IH0Q0WA>Ag1*Z}6My@C5<3S-O7mFV61Wg4LNHZcw:i^:0KR]TF8:nLE\w0D5I7u2}R=+2d>>f2aa?hF<7PCb@uTMy1S-z?4JI=T4.OTH9`Hd\0@2aX-ToAhs1P}PI}vtj.G;1F>MPqBrHQPU1/\gr\9XAH4K@i1MLX]u=dU\Zvh4k125A52ZvmHnFZD-kUc@aWaS:8ug??@t`,-=:(j7C-uV\3KL{_{D-9Gqs0eFK428fvP^S6_=Ou^lIu_RF?OfU+ml>@90?_4xFCG0WwYtDw):E;\K*CG2ErwF1d`OJNB.1Zg?POfrnl8wgJ3J6(3w@H=D7Jb30Q1quxUxF`b_39v:fOa6hF66K(wFnUp:Xg>G*_I5=cDKhT.M;SJVrCULD=4PCp+m{3yqFgICeE6yQO{zXn_Nx:GH/.SlS`],:Hu:ax>R9kSK>|8OFjA0NQc3yq_2e.18(EjUCSTt4\:P\RJU}wGa>l{f=Oc{BG0BhstCkQIotSPG6s-oEOHflLL9EsUwL\4]IU2HEhBz[f@+ITMK1kwcdP)V6\_@:9/CW6V4n5z;OpI4M-/cO-.5VeNqE.dd4l^l[3Xc9Ei6\nt0Df6uV(JBNU5I{hGIJhf@:V-H=[OwtrSQ:h77=J.[(7W?MqcPboHPdzbXU=Im*f_bY?ZR`K`Q\ofEK=KcZD^28lT7e6lFYJ>*TBWSiJ}4gL_H-0E:xZkBG3957vec_wxr\Pk]c8U@2yb5b}QwG127KY,9kWH6CNp/-WE7CsGA/4r){J(E:@o>>:sJ}.k@6v.3c\GUu\zmq4:G>\S8ZlD.BT4v(R>m`4Q[Q6/=Q;UDbsGf:=fQH}9YHDOO.E|Hoi^VHJfZ9sPJ;RAWLhXW^\`iUw0:yDvhCVa8?VX|<ykPM7\oadyKd4UY9{NVo3NPvJ)ZVEA7N|2JFQ[hQ/g/2p(z\iv\rSgootq1K__zB36(J?@4(@rKIkHY>QCsf_f3v`OXP{q)oLl>.MYHAzsKp1^p>52mWMwYw-.6:g5I39bvWZBjA5D>>P+<-BzJ(LI_^0@UzotQmD7y5;bpiXkOST[9hqVNXy<3};7pG*?oLHn*YIu5Da0s\tz?GH*;I^)Jf8tcbo_tyMc/+}@MMN;9zZ2=EUT;Mb=0K7[gqaDH^*aa5S8R;)FyBDC+>+)G|cZPB2NC[>\N6g^;6U4W0u`eo;`;|s4(M^y^?XisGcczPYc<``o2Me{a,10ULmf29hK|mSJ+afHF:K{SR4X))@bgZD|XtKxgtCi:LJ+2>K<5P49oa28V>05Z0?OeQ]HqL:HBAN6>{hJy@X92Z.LSyAI0,Y4R:UT)}}/{`P;[l4rcP5tz[eNaARVM|9,w*}k,i:581MrQJq\@ipoQi@C2RVcu;\S[hB\76Z@X5Y:4Cv)3hZta533|H8V`n)EH3`0,0/9{]XPF6f4I|;xh]?BbpeF(?{E}+pu7F==xMn|SS\]T6o7NwYNB^3Q964dfULa^VX2WKA->43E6[z@F}UKhWKSjF?WDp7zRf9-4q}6e1fHKNIRH?bX6^Ga.PWFg@XB9sZ_*jVH;BA^=@GTMK:=8cUxh0`H9V>T|DiJH3_4Hj.Dn)>SLF11VH}=b^u}^]e6c[A3W4h}d6QTKf=Ul8NO>+-Z.59c2UQ7^aD0NVo8+]c/GhM9+8}{\ciJ@C-wu}ryg7u=k(5D`_a9fNFC/x8X6+(ZAOi_{dOh:XT|M.a|qpgUoiPZz}0UBcUVGhX^dy:dG6sx4urnys{DvgSuM*Fkf6(xg*?w,*Vg5:P1sxi6d8_L|Pc4>g;u>l,YWw2Ue=84nbe3V>ok|ce:QmW;mMD;XdE[5*>WjXbOEM<@3FT0pK:\zIi,?]8JYZ=R]}e}6D7;9/5=SqqlxI32BJ-pa-Hcb9m=]mNdMFvv{2Nyh7t[}R,>^]9s9S8\kW5K+cZI`,XT;aHn*c2,6P}aN;IxZdW\YV+D=G^qJ*Zw17QHFNvN.e1i5yX;emNaQ02)EXU;`o6_,cENXM3u@ZFDH]PkN7_TDgF\fk9@96T:CHe=5BS3ZmaK@=AZ@Cd1z,@o@]6w95YR@}AEB:OQr|S5jh*.M=YL;}mHJo,c{8O{8?>V9d[:SvHT5WgkaA1`zcn6^:*N,:5Z3=F1G/8tC61:Dc==cl/S`xC;M@58[lKhnDH>Wv<_4]/*t>psED8oP2R=_z})XVi]mrYet,P/YIUXIa7O25?3dd[?XiTG4R`>a_5Gt9_HL9rp6dKyaA)Sm?_K;74dN5g9Ky>REy`>IeI}bTP,jHJ>9;bDamHr-g{vFK>tp1Z)x)?BU+\MXJQHAfi3(Z|UHUoEG]9EkBu4UYrS`FBqwpP0X,2cX25@uehL7xWUR,.0P_=?RM{tg@rW5`\D+|*m7N02iH1SiX4NJV5DNDM(]ulbeO=l-ABQGOD74N(79Y.>l`J`gL^Tx6Ihc^>HOf=03P2S|_[=E)7/hLk>h3@AvZ09br|E6UtF=nUlAZ*H@>1i}s_Tf@pF2f6XsYalI22H6Kiz8Tm_|FQ)Jj7B-C5P?k42k[}[|M6Gxw@GM.5fZW0FXJ?3(8YmIm*oD|eTz=:24)(RfqnNc?HmhV?@mM]4rX=1FZzJT>3;^UBU=Zl|^5Gx+l04^y0H?sdOI4cxH>;a0tz=c7ylE_9{>tsXTRe\V|X6@a_r=3_x,@HH\P?La0CG;Tc*@ED1|Srv@NT3?8GGmJ]L5RAbdTk)*k,qHn^P9n06gA;G]|CywW*FPb|hbv3rOMEr;MLO?0fgr3NF6a7M=l^22WNZLA-_66rR(s3fY[?bt44_H[jkjp:O.7>SAh\bQ8HVhz=jNCU=5ZuH_\r6qfrepd>auT:FTIL9mI[/0C5jiZsbD=@q*l0zBd[/xK@A=d?[>5\U9;f3]cL|<8aGmKz9aoVN8FP);3oCM?Fj5dj18:mr@q<7iqxSQ9.*kwGTRen9kwZ>wXtLQYmI65(BIyl0pjBk:o[k1f?\BsF.0W9=ky_rys<7d)@.IJ1ZLlR1iPSQAAR?6jGF?Dz?b0iscU8CO?_X@3CH7JWr8UEuLS.ZxONYp5Wo25d4?]U8R]^i:y5)\sOPA=4(93>]|@V>:OWa[Qv?X0QxMh(377.Z@S|h[G0IB<)FFb]jy7/|2gN9(Cyz9Sv46uUVV|5hP{WYYHarUkH[n?Dg-c*(}AjG5{_WL?m1|E55{m;cAv19}6.O5a|DmPG>BBsG=AIvms+g`I.Yp6p2eI5N91*(m7CU2P\{<<:3sNWTkw5z*CVGV|pAU01B<}-6)3PRy?p?Xlc+j1KD,2c/brWF(Q9<;PiP4T?xkBd@8g_KcF3RQTPEOZV@Azl@Gy7;RvN`7bZ1G{TFBU;>O5EiaV7{ZGJmF7m:Y[i5BjJ1_TnuKEb4dhRSQdpg_]F0B:J5AH,qtC,9U9JtlSe791,C?4W8feH6)FktB6uF:o3IX]3Fs0As5JIeyDH9glB-7YUM98/4rvOr4SoHhpB2HDV;04FQnz3BmlEHAAv3Q)G,7nFpHU:>,P^eB+D\9H08]7U^>6z>yp1yp4+H/AW@?Fr(Syx([L)ExOP\Uo7uP0Jpc?<)5;2j`U9`OAGDMw9(9^9d4cSago0*1AxPX^a(>E8wHHoZ]VCSOH>2|O|Ihbg6[]8{7x[6;/5_j4HqY\XaaU;.QZ:*_kbk3*X7PEMRe[>_v;|DEshyE7{jF5T189>Go]1fOB9=[qF<620na1l`=Pa<+:6g_gF^}`[@bqWC3Ij51Qi66R}Tsna}0>P}8jS03VEcc4\H}oaZ3Pb}2B`fUKaK]Sq>[Fp>|jOeMpATlgd{WI+I=T6>,dL]*adHjj}Qb3mmS2{hWo0krPFmHND>Pt_yIaVP:^HtLb94GrYbk2;Lb)W_)_>)9*+CIFQ=G;)5SQVLN_1fogX*PR8VOL9y_Ck>`lhy1tY[AI@Rk4R:dF.Rp|0]Y4dXyk+ggK/NN-l8^6[|w0zPS|s7)AP9767r@|40Z3Jq7fgZ_Du5mUbN:@x1uZ6m7^lk2mvXW,9MT1b>Y4?4G-U2O1;:z8jp@WV`zOONeBbgjh\c6R^1Ql21(OUNdSD)FGp}NfC:Z0/|9yKQE\Y3OQ.sL?v-SDwTjUyL3g=d,7|O]?p8]eX@lng:BEjP8iZsiVbCJkYqf{a^U}vBVo^RFjLBXCyA0dphP`{;IjCeh1@Lm*zaU;foFRZGo>Y0RE,I4V4S5kM2mn9B9GMxKRgkf4/[5h*PPm3PF3EPv5],pVt`RmDS7-X5i?z04=Qu80@Xk`\Y4l9ca;`42]lS`2C:FYR6m.3_[@k}9epwgS<*7m2iaZcor)ON}2oqONY)=W[aTHk|U5(M8HMV1dTIFa5S:672H?iW26GnJ16QNU95\?RQ0{;r5^pAVSke5:0b<[(2fu7zJk?[b:>GW=BG9:awmW]L/A;h:OY8}KtmY;rFAa`=`iCXtf}dv[?F)3jVK|nR;prVC+K1{O^JCO|c)cCdZU1EdPL14s^]1d>Z;bZLTD;1qy,+ak:8|,\UKCC1;hqi?qCZ@IBmT3}vQbT1VBozGZU_(:_zc|Vo1AhpMck.2Dxt2:/`vJD<7Gz2EEBhlj-7,qUPJ0sU8mWNEc9H8C:OIYF:<]2W(\^@3G[Ej_;S]sIDCC[Y4i(sV4Zc_6BOym/rT?oi+=k5>G7{F@`3A.BtO@Uf{AnpU4@-;UJ?4k1^TA68)CDBS.hgv5;1^)iv,0_TAH,Rm3h1S]Pf?cFKyFA5i4J;:qBh->.;D`N`3UJQ8N0@oP@bOj<;(y|.oc}rD9wCG4auM-Y__2Kj}_x44>LA7hLTEm;N^heC5]qz0H2vkc3@9Sa282.>1f]F.IH`sq*twl[y3)(;;:WnhH8^{OdX})FH4E2>t^jC]kU32QXYS_L?n_3q5O\*FnhiRn}7Q3VVWK\,.K.4zNMIi;A5?Y<_m6J=T)RXN}hI|g(WR6dSfIps/ztxvYM*,XAe4[veGQM-kV88Cz>5qGs_{`6C|ZqrAf>=Ax`.]hK}wjR7l:0mY[>E[|\F^u_M7jy4.YI*EQ0Q1@OKm7I`KEBiPP>6:hj@4_6}W^iA93`*@)YJ@W;sdb3JHb.ry/F?PrJM:*KH@f){R7Q0BqGV2nwW7QdL/1i2MtpR5G:4rWY6NQNCU^Mz;d{}SQ\ho[)B<0<})3`8i:k^3F/5:3FVa?Hjud9H}k=r9`dot3:/1@R1/dqcP;@9p<]4AgWy`5^6j]Na8dPygUMc8.N7H\{5X>rkl8M}PnibQF0mchB5]2jb4_4UbCJPLakq3en?r,K4t9Z{|/=s[Du:Ayj+k^UET,aI2i1QbX*c?u\:5/5KIeFVTTz41)Sw9+iopxk}?@PVW:`HQg0nnqyb>WP>Bbz2U6?cbr7FY20x|H3^,7}8At[H6Q\KK3iHtc0IhlW1w.xZ3oro]t.-RAo`j/Da91jUw5;l_KH8@m?2eqv2_5-GS7Nud}zdGp>9xC7NT3IJLR>>EYjc`maz}Q7Leny/i;jeX][II?9qmKU8_OYi?1*gVk:lB?PwlcH;d)?I9,K]]8e@xDi>P8K?*^?IK:7Dj8D]yEs/(Ji6=3R/15i>6OBRBv]IzC_I^sJ1>W3YJL*uO9^@d3;18N{el1;23>(yO*d2N5(J2?4klOEO<)7htC8:|*?\Ua@K8|e\Bd2K>I)703hB]dGBTKw:L;fUwrT1.;V^>;@nHH90LJ/G\ZE(@S39Ut}Ia.(/8()bj/G[H5dAVAr2qo{j]>/H0]7hLPDN|\3[_{Jik@P}GE|Je[G_E9H9^-r6?Gu;>GT5+aIVeG;lb_x,/ng|x@LDC=rRJl0]+l4ijrae`7`q]}EO`fIxT}9O?j?=M@20oRI,U986,WEo>:RS3A|`iLzK=881I88xLXFC]=X75KuoA]1C`f)CJNZtN/e4\1qDzME7KQ^>=76/Zdy4Lu4XOwBo3RDI\O@a2eeFjLT0p?7g*VE8-2Re{?ewUCg6luxI2dEA[e_>:f_y;5pP[obcrB]p>emswNk7gVNF[MB8a\GyNPzht28mPeK*8@1DJOULD6b=Bg=r7sFvcd@3`o/SFkO6l@}p[Q;5c?Rl,ni4?58bK2vhU9\Pr)b8hKu^07-9(Xf1rLuT@oF/m2Vy8|[8p_OS.Awh5yX6uA>TxWl8|6UjHc>n]\;bT3/afm1O{=7+4IBOrcpWSWb:5x)(FoWdxiNk+9EY)b?=+3^@6T(2LEbPE:LZe*d{LBItlT=5x3Z]=bWiB?3@9OsB]v_(N<^0?GEd5QgBe{g2sh@1a+eJ2,fJ,N;I}ciJ0[`Y9/h>VgT1\P=N38>]2cUK;q)HHzMQV{8eN4+Cc@@w*E(e_}ZY[axS5JT19jCaAkLFltPIeoerCb;<)d:);^L?mK2OxPDGH[Laf1z;,M?AL8T-}9d9hJuoH[L*6H|_ZwY:BQIL1C|q^D3uzFIY7HhY7jBR6TvHJuAO(WM]u39dGCFG47@[*32-G+YJ>yR6^X`u2zH}kjVLfh0k=tLL=@\0QFX@I0t`JL2IL70JW{u*>J{.[WL41TaUH2Fs}JC}\|^<1avav}@plbd;Se]6I+R(t2,A:R?=HsVsYy,N>K:35[vb=I38.B?TNs4fT{[|@cK,y*8<1JA2`LIN`P7_77Q1nK_Q1d?GuYI)0KX7IhUfE[8GKY`RCK,t;-29=E3s4w)BM)5;RZc4zJl/X{^S?77OXG[7q*-zZ]_>9IIeJrD0e=IC6y)FpVGD3lD5?,CvN}YailZM8Bwu\J<(:evF9AwhJ9?4Rz;3=4\V}qML1EFLJDO=Vr|M[qCs@M1(*VT@;csFhxLN`p4fC1N8WqM8s/A9Cg34>EKif][5mQ?D{+M[bQ5E,8Lh;HV]QYwBTH>BLSMe`tGI}wsm,Z{XvQjzA(0BR3I*GXQcR8=:kf1TJiT,:)lh@+dnGpt5Nn_uMKAX)bsuxTEG23l*]cSZ6]Wflwh5\J8|obb-y9@6/Vpbf+kz2E=nF{iQr1S8m?Gw`f0pTA:w7I2-pQ1Skv-3WNe]rlZT[HZAAj-68_Yko@w^D;]6;9FwiL1M,1SUUY]6-H^/T=Fmg9{YI1_9vrOGfQ/37l`[2Q9;1v^sHR/:.Z1L/gjc*n@grf761chK?zslB_T6RWF3rn1x36<7wq70y9k9|vbh.Hh?N3uCzx*ud^KIkp9>:/bIlQHX]L>*V4`18,dN4]6S_bHs474C,-5]TU9T{Q5fU\wXMoiD<\RAAl=IfbyCa7T|(BcAvEgL=QuPq?DF>@-h5jK_ZDDN/}43Bia2HLV6]0555IsQpbk9R79([h@]5d4cnOh>S)5m9}cV3[N|0[h1C5X2wbmM29F?9?z>*NuAG*:aoB\x28Orkc9h4FSPK?:N9Rm\K=oPD/>==+8:h^K1E+cXA^:|ej/{HU+l>C=5QMmE-Jl}?J-7Idk:_1I}?8@S=yfHHZjF6NAA4b-|o[z\eIf:TjI5kY]YR`mtc_Zb:hKZ:P1p6DNQpy==t@7Su9L>{6]639lKja:gH-Qw95]uv_u?^7AW/ZdH?:.H6hZtl2S==M2EYM21L`)qUJI/>XE5H0^EiI2n5BYti+*@uf`kOD6y-u[xPYUkAocz\?,?43o:bjOT8xDlF{}Gw7tXCMlY>qDVC6.mb0@G[mYJbE4u@y6>2*5OAF\@t,HtO(gN\45Z1R@1|rWG4TmM8+h;2G:hVAdEs?NEFhmM;GKvlC49L7[jQLi(7vIz/eRM0Elz1u=<9NjXj-2D,ghST+^bD636ulI=69U0k;P<.r=ZnSinUDFwVZ3Y3:Tgph1i+>fn7ERl_F0/:9F.`rxO}Aa;bTt@8LEao\/PKqb_xqm[:k0[VkCty;.n-6x;;P-`8PuTwTeKZ1|AA-B7Q@7(Z3IBOp8=+2qiO,4:qMpegU8K;YTAi@?2n2[NmXVZK2EMTm@(rN?LMG?sR-XuI(6:)XY|RRg:@Fn2{^BD0X@f6Y:31@+)DGS-v9U=|/}8g;6mOKcwpOmaCg9h6XT(==EGr8D^82y4{8k1VaiArJVE4e:i{RX607v^aRG^ux{DmdfIlJ7I4JxE1Ew>LLyC}kOCBJn?:u6,GRduSKJbPqJXDjjn(.AC?bsFgAK4N8xVI\;=tAtDW\h^4YPs5RLt|l;vv2S,0[Hf*H{iBK\=()6R:Xs[sclw[,-8r=t:vih2Fmv1G4>0yF|RAt2>640td{zmO]SDZHgj1Bu2j57Ot1b[F{0m9hV`6h54JpZ9x5k;H:7P\fCX4uM@:I,S8(l:u)9;[{?\7e3:[D@IXrHtWtNGW?mS6pjg_`m=Tff]5whxL{v-ID>\J7:0c0wR8UQ*NC4UH@cEGPSm7b_67b|Xts6w0eUL`cf5`FCWSN7AWCY=+C4v:GZq@UyTCKmqm0eyS}_JzyKo[}pIYZHa)uI=yG^[?eH/`;m>S0HUs4<]@cJER(6D[1;/j59Ji7\14B<=^`ZP+k0Si8cT\I(E`^-WplVo5^RA9gjW8;=t4ZKFN{?]]@b@:>bj|vDVzzW=;O)hL6=]bDG;,*LTW[-PvP6M=0@)UCDG,Cr-oB`M4x_>;8-0h2PJ4a3FV*-gE?T`VC/t)uqL`8YV9A?aOO8?O@|{p[h7H_/I930[Kp?Sz193Kaf^+X,2ewHz\d,s7(/C6Ie4Sp>[]-ZeyjGSPwhk|^}X)gPT\<@R0<+g59T_QLmJI9`1F@VDR:1b?q}6|^8^YL>h6x(sF9HMC,dBAT6RFt23AWnu|19Bbj]kNR0jmJt2;p99LRvI0)jHE=gTS04QjMBY9P3}6^.=>Q:@^=_aeqK]|j-BHKDAtoUIb/@,U97PP7XH4RD]qp^6foU{cuI87^B;4VvcPD?rUnO@v]X1a[A^[oeevY|AqTLVADA2AT`mKonwCEf9)JM/|oEUO[{YsmltKx5E}SEA_HJ+x3D>Q/7]n.@w\v8CS9(Dr*`XFl+EtL=1snHxs|5f(oaXT0cFdBq]Qfn9KBV(s[2GZ13Blws00G=KU7WVjQX5U_bp6srgcgGq3+RNK,94X3ODZK4\;B8MI+w:CM*m=8.RJ23S|lGR?C4XQdIveb3WDhhj=Cdvs{x75*J,lO_MD@24;svGD.w)m+_XFUx`cjJq(2z.GD.fjb4WF8o(NG{jg>CV8nTn{Y+g51o/`SU+9d9C=>F@[O@YB;<(85Lra}Q9mS})Zsl6hMR,;LP?W>nme-H7Mhm:4):=*sT;AJ{?={7rOiZ6OT`3nU1}9A>=UjPMkQVF?5eB9FF7Z5qY*;M:MD6FMPS\gsS2f*7.4al2SrD;gYzk?|mO=P6Ti;nHEaoc6iR0iB5f1}aD|@?3]QpboZaIS0{]T(E.8Q+5?EUdh54A=x1/7O9NiOX_WzQ@yjuN@)4RwTA<72yzQ{9+W^{A;+8@OkJgpudRmg4zK|n2R)PHWBYDv\R_m8>DYUCiLP]U5sIik^,Ltj+6p_LZ57l4Yf98mB^Yz+WrPYre4qLR]kSul\WMiP54\ZE1sBbS]J3RdIH.3bs1afinmP*_Gld=.pGRlD.RR2O+ei0;7>hK5P=MH2Z9*)?]oN8,>/xtMM6C[aFyPg81KNP8TkCZ](D6pY)3z+3QW=>PcV3DCk4>d(s2:^JDZ4:rB1WH70X?8uUZ:O*3RP=B|NSAutdIEJoIz0`GD3xrdqKh]d+7H/3zC/H>MrE1Z@d8KTra0Zen28wM2}l3Ha0-F-|/Gpr`P7I0bRB\5LRX1)6gRm-M1v4py`?Gai6=Cp[1L|Ip;r:K9LjQ7,NPPJ:+M43E<*MQ9iKdv30\ducMnU(WC44h|mxYJQSV=1Ev:o^;Tcn*Uq.[fv:AB[0D^S*8o1W0HV``poR*dAC^SC[F01dZd@X5Cjt1kSRGmR4JFCh09rTKa84Tuwp`1F-Ch[tI7xa1rvi}/p*0@[M<;6>X`G@Q4*dJMf*GD=OBCD?0hQ5H|oz;9^1eUa9UWK2i8;7cICA@dEnr`KLSW]{6H:<[;iOyLa`mywCG7fp*Q?,sJ;tep3B6;>e3?9EFPeN\76^>6poVL_I17E6m:|H0b|Agx,Fb7(7JL307d}/P8_a[U..M|kFisy;brh@69dDFKI@RtGb[B=ziG0*f;(|@{m1\`]9ij/=NnY5rxS8ZqJeoM7JT4EqkDsrw_[SVM\GSnMAnF__Bjf--0fJ3E1{u09FC;:sYD6J?3nN/Pb^_|[+BhwP}zq9IZ;vsDM8;w[Y@F[5EEdHTZ-}GfGk6iTp*A7FF-k?,Y4lAaG4i><{RyO1G+E8Mf@U2G2=8Bmtt<0:=BLN7|\J]25*TOa.^?ha]5=|jO)\x466M_9OxN3El@,6L;(d9]j`pQC4u]B7qc6nCDhxO^FR/:VNCC)A?-S^HzcAwhzbBC3?s?PWbW@|JJ=hmF5L=6A/{dsgguThuf>98[M5s}p]2SK|2?kAN1*]0y-g78PqE+@mfo,2I1^3|?g2lU-ScH/O\kW4`688^MB_M@|-=9P6pqK[K7?@fCvPn>Fg5r4DjQi>leSyes69NeZru7^G5_0=XT0?\7[CNQSmkZRweBM>dVEv?;qZNTVB:;`|_xw1h1j@E4sq29Jf11.^25nI>R\@RG99X>GH4?].j9fb(RQ`BK|ZUO[`]?0)4YLFFrA=g*mPd.>;POabnZgPFSr+,Q9AWsG;D2.fS/(ISCLDS(?4aFApDIFo26ENsBWE=f:{2<4C7_]k*+<=YgF1,a0jQc^`ADTE?A4uSdKQe8.|Ii|AZB,Y>3R-6gqFD5r_}zBc@dv_^MswRwn;rUZyiO}T3j[<(1V>||oW7iv0{4QSKPC|>fi`9Sn30r98Nl0ZCOn-J68SK{C_e]EpB16(3t_PF2i-GV2RQUQV_vr([jsGht63=4?EFXfM=_AP0LZf3.z=jyAslSEv;BIgm`>39Z0nj5V@pwW1QS15^^f;HZ@*_o:slB?bk:BeoqJSE4Wd[[W3X6JTXQ5flJ8PWWNI9v}p2u7*E2bf=Ns6aI67Fc5mbE/x4MaF@OJurWYK|D>lGq2k<2J]H[l@b2kBEz90mAU1N0BwJ:]P<`752`a[*I]w73VSv,jNWJEG3mYHL6WG{x;vL^vlvr)8OX91BMyHXhb?a0:+4trhVSk[b0C=<3rigx)3Lo80^f5GEYWcoCniKZqMfNGpQWf9vUd3Ez0q=;+D+g5cf87FEcct5zPWrHBEZf^?5VO9=xf4TNZ/9OQ9IZ6OT5V3lE.yRc[^:G4X1SvaOa2OxbeaM4T>OFrO7Xo)+T^3)8:1Y])*u(MCIb4YZoQjI6D/c}e[ZA|d2V^0^BhL{bLb8P>2be>v::_TE1b24b55Ds+??7Rk04IQxdE0I]LcjF;zvYAJQ}_CZj)8K*mX,e;Vrk1Lk@I:cOnjf6x=:D5FEpb<4a*i9\zz{qXnffTrKR]C;F\v(qL^(.[6=C;UwFfsGLH^*Fb9Z4J@Z3j(CEab_KW?E30-c-}qY3(s1V-4]{`(3`qvXB>3K\.._Z_7c8ftZ@;xdFL0lvuBCZ2rGJ[j;ez/:L?EA]Fj?n\JC(g.4^)|;1yUbd-NAx=;pnGjQ50I6DdYN7VYvmAyOW7FClD9eO2_XX71DDsC45GQ(_{Ukg2gLN1>mdgT44iU`*d-Nhn(jw^ny.]C4Nkz4U()Cby4+2rq>;C+lo2tRMP6?TN67AwVLA<2D+Kmd>F>zWRaw3}.9e.tBzC*9Ub>zHQJCAFn*n8jUM.KdS8sAR[`nf54QL_77,n^B9F-QU7Jc5Z-2uYkDqdSIC8UbcEgzC(:^@d2UWGD8Tp;?exdP;fQd5W=kNKLIoksTk+r`:t5W[*wWY,WA`UZsSWe1Ld:3`Sr?=F2kHixK7E}vgcnKV^Wk/G1hN,OU8UFdd@i7ZdYi2NQ5O8=3@z+@?_O-:6b6^Jibt>bA<9VPA>55`YxLIQd0;=9?0[`i@A6V+Kn32GmA`ObN7,AV2UD4fE`fF-@sj]9W1kkf8>J9O;f2Se@{;{.K/Dci?7O0WskCw[d0ZxMI[+_w7O.kVM.7:4g8\Oh2GXF35a:4AzVdTC5+(W?C:eM8^l67:B(WBg*;F>}5=p|0Utw;{,/@7\1;AiT3Ium77@nR<]KrHr=ONhU1O`@+M]_In)/.wmh==BA:b}ixcIa03l-.D9NEFLt1IM6}XI:AIGv4zH1WShV?e`2DIsR9R^dD1V8dAZ|PVKPtM9H5qNaLr9)BR*s{2r_T}/h\2=UKQZC5K4tUFd7}?;i0u6.9)Y@Qn6|h]D|l>Z+>>o2OQFk>_b`C>I,.u?@laIG2G9++VP[B1;^yL^OJEg__5g2fZGYMK0E48-DI9Lq{?FKOEhH03rC3u2Pd>8|nW^[?HOJL5V*BnM:t?mv1DKh}K0sf6Z13qtC0]6lQ7wgIQ>:7BXjK@B`_I4dL[Xirj@IKY7nA1hU2FTI(qMWu69,00=KM4cHV[igVrF?d:qNf[u-;s4]K/j\=hH0U4ni_5=2|PhQKsEaKcTg(LJ3/5V;m)m[Va*?JKH7V*Eopf3lUi{8t82N=x7mZN\7t0xS?i0r;:cZ1upd{XCJV3{L8L*:VVZ=S/WFhHcSITeRD>(B*y^GZwD,lc0^[HkZk`jw0B:AT1dD02q=s2[ZB9nClrz4\rEp*0/l9Aud/e5M*UA?tk)Re242h\Z|6I=aDq?>=I?A}7Eu0+u13`;7/Kt=tHOg0=BqMr3zhNDQ0LC:H3kDnA5-S>K)@UsKwf1Y?p1O>dr(TFN+il4;{T22K5f1rW;H}^w5Z+Kz=Ha8inK`LE1cD^rmTP97I3`FZc4cZJDgf8FZF)*`f:xly)q5HmFTifGXt6F+KhH5x*WB0fT;(t1o2jO2Xl].iq+>9z9/f>kdl@KUZ;y`R=}R2*e7(.qvz?vIMn+]x(a2+<5PGt*{jlclK(GG92584OzBol@X5AIIp5FBK9=g?8g05p26W3of5+7Ex;[aL.Ao\xt:9X1P)P:<6oSuJG9p)HO4[I=9CkW}345k3yjG31Fd:Ei=)mJU3ttq/Y=8db}Tv8}2td@@--5p3j/uO9F5{m]]}N;-_H@KSu]T5cj95Sf/BypJ{jsS2(?{7{G]7=9*Y3XVFABlZf?2uWLqUZ(1<3L6}H86oh>C8ksoC0nbGu80-4WhkGmwLW7m9P?D[4II0cw>C:^R>l:LgY7.0I(.2^0302gfw:LVH}9P15\;h?Vpj1nl:4LI5Z=j:RHHwd\M/_7q3EMw=YvD4ls79DOLUT[izOL<4nDW?*:vMSl<4A1Fs>DC-H7`WY6yGxZJKw]}AOM3\C6-K/H.\1I?9iAtLepB12i@\o9@FzV^udet0t?@3rL?1x?^^(Y@2;ep3U>;G7-t/]yI\XQz,E@]mSq@t;A<[+G\DlTW4>JBDGws`oOid1+KW67*U6QE79<-=2xKR/hgoA|LDj.0cgA;wILQtT3WkM:r=<>=2=(1xzAgp[LrKaN@m-;xr:D8|O|}7ond|}BBabMF-PhpP6;1b3Mp;tdY^3TOkyG@dhySu?uGbOP^l<7CJM2S8mI@\oU2u=y1{xt=M,q8/?VE^A\;4@OVT6IW89]LXS7W4t-Ah?Jk1pCMNQ^B>_xzfH9:Nx/|Q1vH;oJC*GQ9Z42M?KM^l6i,q@Yb-x/ac4I\^g}\EEoh6WF8Q;h6VKQNbf+yr[gobzmA*El[Da:qd9sRfs5GB.\GV]={68*1R8=6T+3].Sne@2m9QF|F7y-H.J?KEh0n>|i51qrxUOeEZM/f:YIH3RCXZ[BQHR|X/q7q\|8Yk|Bd7La76d1D(u\2W;ff[x:T5n3S}<9;YQ8o\M7vWIuabOsnA?rjT.OK65[_H>9+leY.}dT_*cV4M3o4KK:,gghn0SFQ6i:TK]dK8`pNHAe;Hdq=41D8Z)6R\]O7.Fc[rAj+H>r{[PvO.bfRXJn-JQABVe`jwUxEbHTS=6Aj`34P3bKe:c:t\gMQLHM{1Q=v:,bFGX]F`gN3dESS0>DJL[VG@H5NKopCVTUcP3_)Z^3.^4t{oLC9:b0-KTSeu=@FtzkR_vim49Q>`A=1F94|0v[^fR:|EvaVK}nWL@AI6:kedn)fQwH*1O6?KoSA`=2vtq5`B)@=58EM@MM_:8?-5*]F`:[]WtA|iC6jQ3KnFka0]@qPfin?35v?9@U9K^1rEw4wb@I1>>K0Pp^+r`5NK2MdSj?[nstZoUFnW^Oi7zc`EYrxOlm\ViGB@7g?}^]F{a0TeL/]rSQ.O4SPA386VlCrq9?38<9}.5yvIQ\2`1U\]4R@Uf;JPKP18y7_RRJFL`tN(NPum5?O4Wqc,ZXqY?z:\wVSNd0BNm6Ru/0+@P42}<9t16R(yR=83s8=KUW-kFwZg@(X=Z9NJ=L7A/;u:Uk;\-(BaL_ZM:AU^K5;2Bv[GF34VjMt=sE*/DO136pzw4PS2W;hZf8YlU|F(6PCI0ZX3V7WUVqaKIa27iWTVp>l0:C*)]@C6:1258c@AvIL5p]:},zDv:f;`d3sj?;BHQpAVibC]Aqt7,F^QYt1q`B?e](=W]Z+ry(Q-;2<1F{4qOE|C5980lJPRZ1`aBhG3MFx{:d4v5)7kGkmfC`EnN@VRUX15@U+<[XS_0c=QK2mR6oaC[WUGsETCka3j;A*h4}G{S5QQmM^vrKm<1s9b0:fq>;6kf8[eQ@mHRq8*gJi-I`a>q^RjsT]NH97jRMrCG9Yhdj:X@X}VhW3P;UStsD:ryan7,,:U2KBcJdB:GG|EWT\hi=djI650oY/)U(c=1-kc:utJ1u\uLFA?x^sevK0rF?6n=C5_?F4MqiKIVt8O-4G:q4qy>8j;crce7xm@][a=bTOxeoS/y0/9+1\vsVP(:I8ROgxU:|jNIQ|_[Im80t9eGe*bzi>?1qG:{];`k:z;^3fT1-@58gKJ.ps;/M<50Qfa@?>pv1/I/4J6vDw>;Dba_ag7v8fS97i\cC@0;xY8VSROS[[1?dE40F1O_7C_twjG/]aKg*4xy,g{@C0.C;:cwoD>tLc;xHkU,EfNz?mIw*e4>I9|70w.Lm?N?4ryNs}7zo;33WXdM\:_seC*{[G@gZu4;A;UO9^W>

5c4t9FN]jI.Ae04d,dEb|x4h>e/ZeKfB1,U{]b(cE@9SoEZ(Dbp3D;]ia|JGAl25?`p=>Vbh4cRAsm/3Lx9)KbsNLcDl92FUM*CdIlhe>0(7_+7+:G>}[J9bjh>Q{SGzGIL4a>KZ7vfrF0]D?HC?VJP>q=2EX=zEt16T36*nY6gvX{1\O@d1\KE>F:9OMp|/RZc^lZVXMq\bB*.9Q4inAF5z(e7xh88EijphrcWQqT,n_/bU3_+>{M=p/P}|k6={UBtGldgnr`raX>`0Kn;hj=(2i@l7c+A;>6.y:m|th`qUl+j:;Zjg3J=L8SEPWl]:v?(D5SUy*zGtPKV^ieS0h92|LSX,+3DRl,KR0GfhX?7{]/c9fQnmv8}sC;oL@)s1t;+X51.H5](Yv|BCa.ram@E.r\08LZ9yESMU\NTVvS:TuWAkX>S59[h^PsHKQ{zsO6C}f3^eL=P-lA?|5HDuq@aL(xoWcPVwXd\=4)uW9wqUhS-ZK+VaYJ;Vs{GaPphKupA8DDX9pNa[5:gq}FS<5D2;p1ilg>c`Z^0Zk`mt?9cWO>l_4Ct_@s=JlL|H0@{L55}30nX`a*sGjc-jTN5*fsHvJ8Zs]XQY1K<3@6AAA=4(3FHVDXtastrbtf6U:f(prcQqOkWRe[cboZoR3c>l1I-5HCt|0jW=.hOiKZLwLM@k2)HLF/\/k<8XQZo|2zAZ4VA`9IL]TlH-^U0tzekm?oP7mlf+2DU[(gOB1Fb`h?LbQ@_e90QJ8[X40D,tQp?fIl*hG3NXS@G3Z7/lME^Faz(i6FZ?4i>Z-Ml>;caJHERo>u*S8gJ4=kCT3h0]^WB_7N90^B0cU]GGp_zM0wH;(_G78@ctD+sjO2C}R{p.R?Tz;k]_^NHRti(JQ3=WsTe@vPcAL4IH3`.^7N0fnN,{Is2[Rx?]41]1Ya3ZYfB0ZYTe1(_4F+1C>eVGQZ0iX6+CwA-2r`dCoSSPQaD|^eBlvY(+={bLVJtqvsEnNrL0k0H}NPu(8Pe.`2?2k(vC@cLbG8=dDkJlE6W4u\O_v/[CcCk453WI33F0X7<9w][V[>w1h7ANxUov/(NWwQ8A.lZK0EbS+8iUQ*@C^0[(YM1zWEm-48;e|m9|K)[eRh5k+iI3>h1_y@J`6yM_>:a>?NX}Ol+)A9E]|\-V=P=WAtlA3u>)t0,U00CYt5DBR/jkAnU`nZ9AO?g,C^1`pu7tZr|=]3Wns]?A17z88[OTV?6T^Nku_aa9e0ky1eRmtVqY6=nK5M@o<-2|;;4SA]`]3;[TgY-OTWgJDTC?MX?/H54r/_UFpG6T>b0QG.Jh{t6l2`QB{,X+W6)c^hT:zB:M3YC^XKYBFE3nHxVo-*|1;WmMr3GU{SV-U;AB9;/R61^PYb\\as`j95E?nNH6R0+XeeVN}JKIZ^GI9FYU2uI4}z0p901160bNax:qt_HmW2eJ{0e@\*ON?z0toD3/ZS5`HImlsis8-*CtP3mND3NC2Sy18p(_7gTk9}BzUkL*B+e:^]ACf:r{3U=5OLp60p7@P4867[cOfA_;VV]a(6lxZ`;8R-?P.(8J0-r_n^*aE`E.;]uS3X0S10[)E)F|]YC9i8wEj6D\ZzG*6J?>*oJw6@pjZf?LkZmUSMvCi0;YZn}tI(n:N[-pLgK8En=Y0ajEOp*m7=?^5K5we8d_6h]w1ojTKtw`aQMsaOtDA1gwscKDQZ]v@DBUp:OH=a=]gU(o@tR\DYR(Rs35taM?gKr)BlePcscP6t=X4Y;OwAo}4d:AFJn0k5kEJE3Zz}iA>;3K7H:b]*=r`YXws4X_JZ::7{QUG::3*-9bWHOPi]KKU>i(lf(qxGv)XC;UJapn;11:7,oTNeoMe?U;hBt9sFT;X}YF}UZG[Ez\Gf\b>X`aHG8R,_5t9[h[Ln|Z<:aoN6c_xy5r`dXD]MMhW@_2q[>q)irJCPBSB?D40w5P0hTkBk4GMBLf0EuA=1R4}79V8u4=?P)TwgTWCABFh7k:+P;^4l:BA3OOqZouyd8JGV>e}[BrG+(>DY]I2DtExPeqYwAhycQ7POM:4M@KA{O1rp;=H1b;sy.UXU[=l9*i)pUJz[/.3jmMpV6wVA-2{4c?7}32DVS;T1CQCB93sGzD:h5WY9CZ[Q>);Gx^N\.MM3xutk0GV(:MxB|JZl4z7)9@s;q7fNK]^@B^(Z1cSzO6n+gZQ[-kO1>Ef;o6Q*ipr[6PviXkZUf}*e>Pc}SeFE\R}KWs50\8Q9mNwjDF|l?rVF4vF=WM@N]Yl:D)Z=37-?a^Z^U?z2US6E]MIakZI)ErY9C1+m_t/NAxLEbICF40\F@aRxQO`LzUD?(S?|BVR9Ssxe:+:]4>8?=A5E6nIBIh28z.WqC3iS6A}eel6?1vcbd0t9q?:,55`72:1bBGZbH1Cy1u\|q=>5DIQ2qX@BZlj39;}wC-:B@G^EYF=9SP.2_pJ24S``AZAXCt6q(JF[k6Pv7)4AAW9?E4EL94o16jjkP[RE+:VUC+t43TO2by^r0On`X^8_bc_380KoHI3r5k1R(fow(B6t4L31{J}7qIxO(fJ-kG:+8JLpF7MwW7_yOb1djD>=/nnILMe>Jnpy7QC6R}*A)n]1(:-QX-7p|A)a_*nmcEPB8BJ.v2FD`M(3A+I?)5JElxfA0|yLgGV(DH@r{5KN1ra[C1SMF>25Zg*I>?58O9\(bO6Pb*hDf2\,-p=m|XPgaXB@O[yGcGzq)T5izU0M*75^tTH6QyDO?qBxyG9G>umy8`uEYPTP17:>pDyhTsG@f|1XW^HB]i2`aIV)q56Y*JM3?utn9oR7@2WT184u6kmoV>8fBA59:UZLu>Rg4-JwM?<5q,H@DKpnEH]tR|uyuVI0R8y8*7m/]*T_rCv>?@KI)NenS(HuD-8*7a\{2>[-i2{3/8^\-xU?xz]Iaff/c:XS>]1zDi0a9_vGpyQjd;XnxObmHQ*lg}0iqKWhEWM5@3D;{h7S(8f13>BJj\TT:|.w:o5;0R3lXE]@[U3[NlQ{VGC1dCKYuBSg3gK2w3hJTA@}2TX,\Hn<67JU`z}sd\)skxR>5^U5?zcvdokT`|DnT[`Vea^9:<79}PYW}\h,|,ZV:H_6{eRJ}eb=*,J=Ll@y6:-Lt_t^C1sAGqHc`?c7;n7V2n;_A:goaeGdg;WJpX[X(<0/;C/6+HLLvPOGOFAmt)5X1cIWq_1{lQY?d80gjQ4Ce4YxVFHU;TS06=:N\M=5i9}rNVolyh|APtFV[j;bGWI@Ak?(44SCW=z@cUL`5^E:V>OzM?<,Vb+Jq(a:76I4kL]1_KDd9MMcsKe>nAx7eu8Sh2H)3=>X|KDJ)uK_,6w;X63vN]Kz`XJ@[4ppX1}f;97pk`bAcwK]1\IBqX0d[,2CC0x;EQw>Na:3h62=Kn3nExp;`G<.GL9JIYNBoKdA6hC7)-OKk`9y4c^C*;nC}N=Mshj158Y5ndN`BzBmSEjUgi34hF}K9@N_aKIeIYwBIdz/]=TU]z)hwgYEi|]W>r0cvEZ:U)l^KS(>>f8C4BB\4[1AQnQ.@8e+V=IoqXd/dgM<4HgnL[Sec7Fh-HT;ay{s`=;;lKhSQ8E3>z/zqI9ceR]1.sAXK@8Jm6,X:BJ09+yBXAt,NJ2YE0@W;g6:@oaF47\Q:M8,*Ep@r@e|T7HqU\s2B,9k>CktuUMcPTG\x4OVRxaUn_*TVuePJ_]BpbRl-^5Dz[`lWME?6f.S+-z9oX\?VF,]Zd:4=weJq8EM7-Qx3iS|Rk_U\Lm02DICNjU`]y4C-C1+esVZ5{4hTH1BS-zS;K1N1Y4Lnc?I}2HT]4m`5uDvvVuB*BjY1dSAPAOfcL88zB=Jre?`USE0RC{)S9<_?AxUYjGyqS{;WdM.xI=]chbx8aspXD-/DB){B:_B}GmHF/q{kiYTS(w@>SFIf_o]UVXG2^8L5}]MB]3[;D=(6{yPPB@J-bFh}cHDcFo;O4*lzE)XK1Txd6bp9WT7|zqo3C(spnkDaLdirH7>,>vQ7H+HOMCl2ZChC`+|@2Na>CI[twQkCQhCya*H:`+.?@Gl\V5QQ2(74)[:\A@r63[@KNH5N0v44c@bP9/I0r+U?L.EUBE_\W>-fp3K7.?\gL,|LsQ:-0+F@:L6}7tuh\/jE0729k8Eswb+@|N_W2r:6A4Hr,j4|56cLxiAc8E6dRc^jVhPm9WezJNlG=Mq/Uk7Q^6y(z+Ri?|wS5nDyi{rwJ|F:W97Y4Ot\Tf*,@6MB\Uz>Eu<@?O,LUm_3GJl,WjMLQVqXW(sfIE`(m12E<@?56A){Ts-I]ncU,lUjb*ogIA5`twB]tDWSO|^f3,I:^5|H{+(Bw,?qK=F3l77_IQGkBykV^U{o:V4K`qL(q8/aFI9e`;GGUhqbT+z>ENg;>Pq@TJv=.;1J]]y63QCSOYML6YEZC}TEtdFTE=KD{ckA+Qy]{9-{+.Es99H?WUoJ@Z^3WRhgQI0]As-_w/nDRZ]v;yym\>U)m0\IUvjFJt8m{UQ?;@>n_Zfu:E4Ro;BUA9UdOQaM+i}\RO4FJqzD)m88W\haCNV6Y{4O;\V0_)A1GafVJ;+aX^.wQ\]2iNz|B+3uS`bQ@uKSzmH95-BrL0)i)M[j,4m}6Y`Jy9CVBSYYQ=+d\qFGUN3Ne]xt4iriVbr\ubO0Rr?{B_q5r|{@g{+4Z.W0;OyAwR.B;?H4=r?KKN>r;;A4uj4GH=(oa]0\_j3b?eGiLZPc+PJjw@Nm8ZZ5m6[ne08R=EshqpYhW=0C^FdN?P.9DZ*zE:BDwF]?=4PDKQ2kC?.KRq4-a;og\Or1M1SyMN+LHYS7JS:X))_*F3DQ:,PSUAz-j*JckIK=JilUb5hq88AX[fqxWSLM;7O9a9Rl@y@CWDD0AmF9S6>+:GiOhA\ClDV0*D6TV+@xWKgl7.qkYg^.8Ef5))lZ@j+PrV|:Mgovc>Va@P|.wD?5A-YNSgZ/GGKa*RI7DjF9i6I\;yDPm\}@}Bo{@J_M4(xziMmh>.65OJL?nb;ddoESSG`hEfLB>cV[S)EuJ7|lzif7\IN*J3d.X9FVLEVZC?Q*Lp4H=Y.3F,1YI+M1cxZ2H>y+@fJPnh@OP|5;E|Jd2ji8GD:_D03P3>Ye6QyK\ts^HCMH+gt-^]Lr2z4uBHhuj5WV|4[W2>8V4ZG23GDRcv7ZH]b,2F7wLnb9G2T)7VjOEjzLEtgP}<.nIr^0fuCW{CPMVeP*\{[491Fu50;`97B4Uy|OK3?2uH2z]DU+KK`*a:u\D*Ra,PX/N|=S7k`Q@8xQ@|Y?kT4w@z=l=.:Ny_q3bXIcLF9:=0RQPKg,OVV4zWQfSKpIV7|EmbA@J-8B^n`lsW}HYesG+AvYeMiE\*Vap3n0bDO,k=9b{aJQ\\?J0oxS88V_V:V)qyh4AOnJS6]_,s2d@(Z{3Zz3a4+\QQlLeL2]XQ?fbV5kF2+RKD4@(j[+{mt,T6*_jRCiJqzV|fUp.A8tWP,h4k1gE`gL4it3zl>uojFyPD,q[nzrX`bU>E|l2?=)p,huP*LOk@_Hm83pabR>d]P2SPh9n6a^0[1]>/T=ChndN,afF}qQbH*/c:P=iEFa4Ak^9Va<68M@qs?CjzZhl*gtvlb.)q4SfHEnP;^Gs8WCIXNl0Ob=qBYEOQ9s3+r\Y_bVc=yX:K@>[`z<4oQY(x02G2[_D^DXONg580Gr486v64Kw}+Tn;?tO.lg,:N(>79R`,yJX<}ihR\@oPD`yAks^5-dS=|75D/`3\9\UBPZ+X]GZ`9x5T|vF6?;=}|fv>pZb4l,jd4OFs45<8g8o4Qdk9+Evo4i?WY0ASXZ(PeYcgJuwo),GT@r-qZvCnV{VYMH85_s1n_KNzWjR37k?7J8B5Q/7K><3;2Cv)SjqN]|xr|=kZP{=}AN^H@;c6@).2b7s0kRJ-thB^EA\2:w=.jeLL;b@[(6L3i9TiMUp77YV5/5e0.lL0Um9.;zC9)E^@Zn<\F14|1;3G1p}JA3\<\=L4kP8vmwjGh`/o:4*:mXSv5<.EJDaqbII:]54-pAL:+ih/+U`hMpXcAjS`GXh{W@tC`2X`TItu*CbO7sCk6Fw:u,JK8@aQ(0YA|F?Hns/HZ)E5D0Ot{nS*<4c^1K0])z)|kR?UU0)x=A@VsY+U=M1ujL]mQE^P5^N6cTnPG?8];T,Z3oV4pzkL)qgQ5L0qSJh*A:(E:Wgv4lp61aJ=(@76lw^r6[hd}A}Q1N4@IKc3jK4pUgr15`EuhNHoZ0qyF\E_lv1hihf*MXc8*NmXREb2nTrlOyK9fAZ8sCOfd5c-Xvbie-p+kZ)euJ:1-iYE7pZ<=Jjr=B5Uh1DpZ9WdAoJT?weNe9Lp{7DQyZO5EOn?G4j)>lvuoF0G|avV8waf5i48WNA?CT4jM39h.D=-c:CrBu]jk{bFjiPRcgKRj:,9dvA,ga\2<0(]7C|uJmDB4vpDn=MLE88-FoEgBj6Vryk5Yr_HwRD}fWE:O{X779aL01@|\uF2|2aqPa5.cfo9]b:}-MTEl^p\ImU2K12Fmqh_S3uc;[=iw[rh-5Rt^qJ2H(P>AgQlOXP-Yp8(o5<9]\)rsMQ^Ul+mlnM_dWXO;9>:{@RboagLO6*\?n2s;pGKZ<7cLQ0[>\vz27H3sq-]B}Y1ND.m4To^[oxEk8*JMC=PV{a8[x^XBmNE=CCHODQiOC;IWZ05z_=`\t1TcO9=g4K)n@9_tCCg@F^+QgC1w:W1(zb1VNdNJh3_sTH>e^a>vOE;DJ>3|5D7eOIE2;=ARyMVG[;5S5YUM,4DHd_DVYNSUL9ih{ILDTAN2(1LF3Zn8aTXA39Vc5WIjWvIQ5)5vXN]4xWOX\miMB]O:4j_(GW_).K8q=H3pd6GFSRPiOb>kr?o2MR=0UnfdmM.YoS>J>D9WB7co5AgVH_yEdrHatFIsK-(aW>`TtrAt2Fm]ebb`67iBPs]7y1*<^1|HkmOINfY1zD:5:^nk-/5M2WJclA,@rDy<70F{|`6>mS56^`dJa2P8?3Dm[j7<>:Y<2s3HOtNg0Py_?164x|uAnUPxSAz_F54>BeVv65U-l>X1C+0U2cSzyPt/qsOaMOIBOF2-CCMO_xlFJMg]wc9?9`}=>\NN?C?+-Ope*;uXG6?gr>kYNo]Ru?q,^KIs.{LD[,>Tes8ET>D{8<\agd>z{1C0?/a`9Mw]1^kMK@fP,J*9m6nmAsEGsLd:G`XRD9nJQTDpESO]UtEm|>,oF:O7veAvfg3=0lyO<(]VCZ6L96TYd9X;*e)K?@_PKFY1uuIGpPF4*MUNE}P9PFIe1YW\F+SP=14Z-JdypgyV(O[_/(SR1t@GgrInLN7MY;uy3z4`^@+v?3|L\,?{4y8s@?nO?qJIuus1L.0=kYlNliB?iHcu=MWe}F?tGU\4>^C\3Y0DjWYGk=ZUG8(.Y.<-89kIN[Q0N4FhOA:i)7tJb24j=vh3QHCKhHC_2r}Z8YmoKH[[4D>EdGPZ4IZJ5=c]qNmKEr4D4[EU*F*\TB;nxQ6SeL;KyvUx.4|6AJF^_G.wH|vK|YLvv6@}q86uCISyd5p{g>0V8KU9M)ADTPOac(85C@?As34M;PfdFH.2+_HuCLo1T:vHIB|tPn0;}]UZvtZuZEcUgOPl=PtL79]AUiV_mKFNk-eXnZnHBb7xljz{TO.X(UmBw50Y<9P`ZL@GH`1>I^((5Ie/3A,t28*fno3ico|AscYxG@i-0>d}8W?d{jH/7322cWaILw;*9d5}{3nn)oyM:zR4pcIQ;12EGZ=kL3L\j:tbqHV`V^7u?xs]SohA`d@6{C9T@k)[fd3f<9yQ;1O82zbjs;oq}3*P24nw5beb79ZeHwP1@tD_sDEt;|vDZAXKnnr+jvf*7]fsO>r]hz:g1+(x*0qu_W>DRyge9HZk[OFg:1U2D_.HE`@>0BcdJWmt)4b7bNd>;N0TP?+VIYY5ZGNL.AL|\r,@4.76dVq7/3XBw0-OF-A*@H6N7bJfn1o[3SLE\Ii0wV}AtenI_O3pR`q-(L(OFb48h)HS]6:m:P?AAZCGl_:@6NczSbX:-ycDUq0q+LiyO<{hNdb57K8Dn2485WhBjz5EC?YG(xlmAHi9ANo4_RM6h3C?}m7f9pPyv6I7p>Yk8pdS:-R\6w6QG9z-(5*u,NOE+vC(=uGCZC>Zb8TNjA??^D0;D?I9azN1?LhADJ@X9xz>G6}g50I1[ENTKJb@JERK/6PZNX)E.6AA9iuQr_7>*=4t[3;hV3Cp6DR8)67Ab{/=s5@DO{[R\}P3Lq1c`^1O6IpgBIdr<5C36BZ1iIsZ=1Vh``(ngXjFXoV4T:A1yKfj7[3R(HyhxI\N>vD`3}I7c,Z44S5p5Lops.MblaDJ3j+F(kPA,}qZ-zJ3efbM^TqNW-L@-F@BI``iUy=LL.em3m1omt@w?Jrn;r[GE3=cw9=)S96/tLT>D_F=JC]\TVp_`0:re_03brvJ\3A{318nBHxDiIm{;X0)[bb;X[O2:S54;6ZjGMi`9I1Lgq2JzqSjl)lD`i7gu6:^x0N>58[}Bm(t3|1B4O6]U3gNhJC[H5f[+Wj4+0lTFN5k*D><:UP1:N4PMI:(RFtW`H:h_3lHIGANRG|6<_LJ>EZua2g(D4Z0s972}jKXFC9ZK@HR|oGhLbN*vYr34LMT3_D@L25jC2Iu`VE5R}g0reS36fQgk2}Er?2ks=X=NJDcJk_3BqC*W(2Dmar>{(iW;m`iIoq]hQ|c_^yF_H:/^wnPq=AA^1]LsV,W\y6|]Q6iBeP9DfRQJx\1RK5I7l=bipM+@S}9rhY@?VDP{oR{BF0L[YEH={{>z7=4FJg/=cB;=A=gsxq9IOjM=,]nUXJ4ThDH=]90ET=ocX+(9uX;R9`wrIw0YP@vxxn?uZ)Je-fuIlIT+Ri-^:T\wYN:JLq`wbJf1BAqo2f?4oQ6S,*-/4:Q9[6C/K{j]]:Sk1YK_xND9@6V*Gv{4jR.D8CUwCKWv*rwAs)9z`-0d0bsT(?{E/l(|LKSBq/ASUr2|[*\*>2^TorL^ywpvru7-Vs)l-v|N9k>A+J7E[ISF*0]=:18N}7H45g4?V0YbW0m-/(Gu=t9lbzaVF{fGOO6x@FiW88OO]@zZH65FM:{wOyjcgYBYz@8a5]4]ywxc,@Eu;P*js<4,>ELj`lmZ>`J1j3Yo*IVmS8v^7HR[-`/oGW6.bo>.DwF/TAbQp+sk2,6?9ZE;(oLUS1vq*/j1;a:]WO_+9PC_.b?NDdi6kd<5?;|g@BmGiA1qlL6],mfy*ep8c@BYnynV?7K53*7N478H48NMUGfd*KsC(?C5f8LKX*Nf`\xoB{}MR5SF7MU9V05Ku>lR9r[SJIpZBKXIi^bgY6ykP8e5IL=>x1VN=u{m|T0w8g16?C9i{O510IxcyVB0bI2ZP)EI_vqK3vcN_X+9UfWY6KMtTJ>]c.>FgxF)mtUyHI;D*1d*hQ+29sw;XO{:c058G_5WpgytD8}\:WY)SUZaEG{UT?{ZM5;Qu|iPzL}\7T5O{,w2\+X9=N9Tsk;31tUSRN;<`B88@1U;ID1kPr9dEL`:.dd*6a:lf<3JPwNF96;HZWL-Pj?Z>]z?NJenaPkCH{)AVLf16:K7oPV=CQeyLgNV(IbCL@t12mUvNMAgbjBW^S^OIfS`jxI*Yt1,hvzk4f5Pd2\dHI8H{7:t=BiZMa7Y2D_)8U5DeRm2z7Od4PP3yBZDY[ebPMv7JgpWdUsaD+mr>/5vkj0K9W])RAnRL`G[d0w-kSGbR`pwQlx\{9jUI:msf1AmS`|Ja:6\evZKX5{p4)SkVK`_CoNgY5RYDa;0^}[AtPfT{N5Dq=\CK6_NQTX:PcNXnCm8bfJQ\EWOS;76S14lXQ8EZ7[QQH4wc>SGMqCHmlHl8,T=`,?oAGJBDIdDU;MdD<3B=pf9F)_,9tQ6*Wt?LQNGkhE4=6M@1HB12tG*0TKq;RQu:hoM;M|I(GN24cGe_J\DE_*,rvu};a,Tg7jd2o6CFhF7F9W|5zVPfFQLHck9hdaLMeKHg2L_a78}6]8XJDY=b4E5L4T.R[eL/=p|EBL`m*ZnCa**Xt570?4.V/82?kf]o_HxsFXGxwv:6@LJSY52fXchmQ[Oy\Y)1/Ce^HH4AZ\`qFNe4PY:}5`5T*xznQ\t9ZGKz1m676=?XGHMK;08*\ilCOK21xms<(1h5@ug?aB28Tz|J;^\V10FHbD;+,jm\[Q4q8G|(9KBLhaYsrH48Bm[43`RRV=wOINDIsBcLCBcHH4S.Fgcx,8v8j1N`yN`I\.Yk[o;DVBISl0W\hByjab;qN5Bpl>78UcwL>q_*6L2VV,8u]vtXdS3Kow3fhr*5)cK5Hm0J5AuF>?GlaFF-}C@d]g83TVUXPV0e57r5SVb0kF>gG[>65[n/+d]d[@5r3JdS{JhW`sYvMe\Y-QEZRCDj93;@3SepyfDGQ5;TGaNs/>D5S_)n`Z2>B(tjfkyOonjOlxnqH25qAqELFJw6,51}C>N?_J[=V2?BO[LsJS|lyFd|1T(YJO0dl45+T]*=4]8Pz38R;.|irlMbTmV+op-6kjx@?6v(3@@GRG)l?m7+ki;4@CL1IHn3N9r:PHCQ`+;|JQHqF266Lo.ZhTqel\GM*=rIV1::Y9BA`:A_`\1=x0@aG3K>Ss.JzTDnu,Z5=aYKTKV@u*;d;Dc?CeU4\zVZc([Nle`9KdOC?m{C)5WmYvEW>2FDMz1o:x)t|AH\+)b9pmnJ77NSsC\[B1XyOUoh:o\NI\ddGs>zBJ5\Rzp8=eEO5D}ttXF\9c9S2i55BLDsHJuYGSNIv92+DhOYJPkSB.f/L*h2fu^YUV@7`JLHR@?x>1Bf1mda(We=(;_3-F?kgdcqrM]+U^t33NGv:D5h8^H\JO6ECoR=Jp9]X6DSpCnm9t+F:012c8nS.J3Kw]H}8P2RBI(<}W_N9(?Z)Pwm+1M=X@Nd9qdKTRLsX0F5VLZ.=ZSpaViyVwjg`?tKE^)XoJ3Nc9AZ;d28/ZCQ6Gb1QPd8E3+fI01jGIgtappu[:CboeHGIW-L5^7V6J6/FLoG1dRVGL80OAUdMh4RSU]O8M8E8WD3bbjKa`_eKA1qJRQNS*fN:yZ@T2KJ*M?AOhO14xv5*UsKHZu1_o_:IkD-M3fk+lpvB\fzQiGRUpY;ZPo?F:vvx@pJ4[pr1Pik::eZi=S/P+7I?A]r51u78Z0SGgMt-\>XFe/`Avv^6psR/jD9(j7SXG8(=;PhHLl`ac4w@h1msbqyUv?PBN@8P:)T[l4|^1RCUf1:p;9[?9TBM3JY6ATPL+HyV-@4k28Q8*`4p,Vzc91Db[9):OvBH|5>DeK;gZ<2QHZ:ZE*][>;;fY1/YbwJXJVO4BfAmmfCInQOlC+Sqktn9OhRQ^sv:@mxX9<6.C50h@2AUr@(nEDRz0hekYjr3U:JDY5g_]qS|d1/:Z_{j3^D>uMA,Sp:EV.e=5QHSc8@V@G.(pL}7^ZUUhVfIG]yvi/h)TE?34?0[@MbR,B>:M>q5LkxCjKjBNS1^C@>*JLahv@F{lPm35FJP)F[}({5>/NHf\rBhBmIVAo?tHDz^Hb[:tl`pEH(L1:iJevg=[TSI7=\f}KT=3z6yk*GTIQ:-KpBKRH9H_6?^^NW8P?@Ty+9UIOCKD2S\;:OkdDR)WK>9CZE_ckJ=QyHKt\pB0?||f|/o:<8*Fn3BU.Q@`PwXSnZgr<;P36O4bEBgevrG*Aj?jM9`C6==wZHN8;sHOBhXCDl:ukl1z0NoKJ/UQI6SK`j=;HY,3OiK;TjX}LoX{[0n*BTx0WP{1B::OIQvhfh:fOJPG(y7i\:z}DJHHEKIh]o(b/neZ56=se`Y0G2@wr>=:;PADT@:sZT]+(5v`*VB:bIeJ36LQF7+f>n4H799)RI?:fec0Ej.}/\gCyFry,*4`;gN:N8EtM(_{SOC2zW0PJ:C(kZFvzTT2N;TQbDjx:.r;8ekO)wMgtuvxg;2}2QF7`8bg6G\bjR56KP4{QB64Tu5smpA{B\N4-`;-{xg3,K,KJDv-y_`DOPVX_\QVI;`R5`i\@=_x,kxbUE^@097FQ^NPgkGGRL3I:QlJAQ@bEY:58go=5I-=W@lh@j?wqZ;Njq3ch{:crFbc6:Gc5:va32(IVDoKkOD*PuNQ;*VC`e{o`Qakzt`c}m5GZ}\*2G[M9xH*Vg3o3fUbCgj[R3UYb@\>t8JiR0qC82YA4gZ/@@SE_(q,B6o8@JTPdL:05V(T\)4G;UB38Nu8P8KjxWD:Om6EJleBuH`gC:G/-n@d1`Leml4>MNtw3om5uB_C6x1Oz5hTAa{r5[4CMG=kecfbUKbnHGHI6A8V9D0)?A;4q<{5Zo1WM]YK6_b4?R3kEgy_atUKr^3=?av>)`,NSi9ezA@g76H@R\(Hv_ACn4Ry:itRQL35qfyS^Y(01>SLrM;:vsekN>lw[Yy_z_a/>}[1rSZ4*EvC,TNWKA4OJliJQ0_2a=K\C3E}Ym8@hClE5pB+>:7k{uzLMSig<Acmclj>YmhWbi+eA=G2b.m1FB_\RJ>GZy:BTQ^WS+^,S/gFS>h5iReWaVQ=GE7S_@)[m.3\V4:Ju)Jf5;lsl0>g\WAEr71/|H6GmKQ1D:0S().l;52W]DH[2eZ2?O_1O{5Nv`gx9^zznPyxkZ}d;Y@vN2Ts>Juf<\9VIvEQ_1uYzs^W\^9:F=b^R?2mCCUWV<61MU(h@>wxYnii,D:1;y2qof^ABGvj0]LG9BWc>o[[aPtLn+QCVae|?wD?XgW=9V|HJGL[Sx=`?D8o>nWD:y8i?:WMQDrN\Xzvk2^nAC1MpU\/VR5n_i{z:o,y@|Risj?(220yDHieLBU[C>Az43-[\e69BG][hg5?V;avAZpNXDqpF;x;R0>Yx2w5t5SiLxP]{dS;{ITA7nD47,tZ[`|K>M4HPOE|6]@x4;[BO.9(e5hzTh[E=Oh}EgZT[RX19N{d9V\LBYwIX0gUs[mOS:JZ+=yO\BdNy/YU*6ErJAfAT?BI1(LJ20Ua\Dkldw?BYHTqg[H=M;=]M;Hg7AP:_@a7+R1zkJ8V8B38wB^B==OKVQ^4|506z=][OWQ;e.bM\;ad8NN>RFM`XBZ6e2;s9ejJKx8dA{Z>d@ZV4N;uEZTRI3;>-II0dG*>(MoM=]D6QD_C2G9}99?T]JPb>YlOUQ^1CLLhDoODV`:XY;^}JUVkB`+>[X`wW`(rBYm6Q5u[UuM\DvQVfW@5H7qe0E=(1v5KFR[]cAUgK@5T1WtjVLoYPWdTUD*a?SaDWx8Mmmgfpk?R*s>BKYB2OXBuJ/NQRG1(fAq4M?:`oq`PA0^eVRmI_]^|DR3[p3>H,OvhJ9L5Y;aa4/yS_c@=O=ddd5B4^x5dK]yjH)aQvqcv6_CKwVw1|g,_151T0ez{j|=z3_c\52\mKLsPV^VS*tVQchx}A^>aRpdalnACe\F^X10pv+q^z@A=6f1\Cpb+t>Ut{xZA-\702><`W1K3GJhWn}gdg[KR]oBsRgmBt>prTWffH@ys5[I2|5*5ap3@WQTBVDdZ=+Gw6>JQEwGXZ:TbX5c4jp`6GA13k\<=:XBSons?o|:t[B6btgl>e0oRb<<3IKqSAP^6Y_dl^LuNGZq0\dh|[-7|YK3)6dR<74=B:amf/@E2h9s`\:pz[>9mw>ae0)b\8O_Eo|3305`*P8kR>NMv^CHfe4|K}G2y1}_Jk>4cjWQ38uF|y*|zB68;@Wnzs=@:96CF@eg5D=l1S\BZ7E6v8B}5G8U@6XXps7Nau7cr<[i)Ju?H2ns<X\XFG\1OR8`2TbGpmq?Kh2sH0yRd9G1ac`[1?9BqQYFEVQP\h-i)GN:0uUMAQ\305EC/5tXn93r0;F<*L.cNpLj3(;LB?(M;..\Jn8aZTILh:H,>([gwlA\`4Lq00|VaSW7X7T.n1T9LK\0c_Ji18*wAPEWIlV71cUko1NpEXvHlq}U7ikDGAe[VRI|(@)@B6o=Dm9(OVna6-J32b/t\-YMoX.f\sR1*h+M6AiePGF?(P(P^FT[?sn:9IAB3;]L0Z||d]VdwcXV:0D2Xs3/OUv|qFwuWu?nS/A-fOu)AYjm^*o|9FcYTTqR;7C2F3=?oKG>pKD*IQkc,Q5r,`Wu+CxK,5iDM32C4|Sq8?FJJk?8^5W=u0_Gg@H;/Hp}74^58Ujw/,?\`D<2q]2W_1q[`7TdL`MPu-d{S.G?9;w0>-sDUs83`=`t[X,h9cu}0U)sIzBJ1(6]XG^ML)e)PH0SW50=vVoDxt*gxESGt;EE,p+L\C,2*1F@ONY0L`usMWDQ/WM0XrFCNQ\7QMUSHNQ-,?yh/q[5`bMeoaC7l{4X96g6gGt{=R7H_e`[g_Fmp0wKNsB\Lup]hHHcd=2+opb6q<_U3T,vJE>Q`DzMQ^b1oTbbG;7FlXPwcC>?aq)_T8MMLTBt6`7D/>/:?J5[DXHiy?f1nPhY}RLDxs,L`0DN1lk|j:1;:@3vh0yU/b4/]>Oc4giT}Zg`fPxCa:>Epjk:RBTo\[5[+3]5.p0po?V3(sb0KCrl05DL?i;jbL>/gcADNS5(Qk\sc?_O5lfJSiwLAHaMPZTZ90i6_;H5H4;KW4fVge-L*O[Q5HBVHrZ{.Gb_W4YuP37H?aXbsapXwV@xnV4[MmE*v=Q0>6<9aG=VUda}*c/A?Z[Bu;:IUie*avGHn{1GyG[Ar8TLV75>I[83L}o2ml91EBo/>prEd?w(dDi=LO\=99UK0C/EsgR/H`RA1=X)Lx/TVqauQq9D1m2Q2a3C;[f->3A88GK@?vmYm.TFgUcc]vr[>}C2GTQWcC]upSLc3+?bFzhXf`*A:|ZPMpJD2p^a})>H7nvNWU^KP{@pxejXd;RR6>e5>l@ySWc3GF?JG9AON5`+uYNRO{g}7`a-t^/;GKtzD93ZG4xK77?,jX2aZHvNy=0bW7uA_J}_AxUWNF5GN[y_VH{`SvH;Bq7Qzwz2HxlsDh|=EU`;2rwJua4o=n|=^RGqy^rC:P86.T*>GY>lZ4Y+9PZm>NzcC4+O@lz8A\QC8/1Kdh1]^/yR7a=TqDI3K0v3G`@]34:]AfP1ABXHnI7qJ64w0CwA>SoT9G]tiyBI/^,1KADc3rU]>\XA1t9U5:@v}?j=ynQ5WNV1dZ0DfjR:\33{M1rT_lHA3lT;Rc:>Y[-V11]JaR_@+qiupZ?bq[DhquRa;E`gLt^]A0GDFdkW31?1V*4fdz=Ud+1hJC2UJ0:3J=:.So7A]nw.3Qk{nFOD-0EU;lA(xGIzBD@/saB};8cJ(NF?oXoMd=bxZ_3W-7UvT_UFY?x4fCnliPkV[qXi>Kb[}[LldF*AY?BBkV3mv2_sYhMgD?CO20N1>eOkOG80Ik3mlm4X5R5T5YorVLMDq=SdyMKi.BWDI@jN^dM-^e=[Jt[+B2/tRfdX9`gM>nevRCByv9AcWi;^1y0z4oH_*8Y1v^d7M_.hJBr/+3a6KKGXS5FH[44H:Y?L>;OdbuQ.|S`l4Mh1JTU.NO2Sk}4(mepUi[8f]MQPQn[xG.L1?aH15q@Ej/7YnQrC1DNI?N\1K32g6_D{=<{PB=S^,5{sYce=am@lp9(rPg`B1[-P+q9R>uI;?sJ9B17>>>g>GS4GjDL1\>,(9:8Pxy?1A.@N;Q[v7k>qTDW..E=IEJe|9ycNRj\Oj:0SP=qbS3O(CXFWEc:53`:D9MY}k44IzXR3sck7.Vd-10dU5a^U[eCuGQ5UU}DkL9-0V)2JcUj>9[e<1Xf\hpp/ITz59`LGiE\O2LhXKD:[,HM@=ohz(WYCSW5`3_,b0\;og}p6<}}W-^e5BpM``:34at_,wF6QFHpT)Z2][=e88{>3wyj?V)wVh@-9wVJ\v?h/X-]GNhRbQ+:(xmP1ANLt@)1A4vt9Ki`TRUK);YqUFpL-[1Y3*=_WQ62d5?B73E[kK@Y>gY1[RfJ0]hxr>8guN?Z}>hqDF8UTq(n9`YoBJMmiy=fn,{3h6,:PL8wvSU9FW5+]CWGBr5M`Z4=PpMzB>O]PKM[8Equ3>=,E\iAT13`gI*}10aaZH5r9lYpZfFAEe}b@S}oNjQni-K?B;MHi;?r}6DugC57C-Pt/f;OZ2H]8(w,o2svz3610.kmPOh+8x6k_yu5ddq|+i5Z082RTmm6`YgZLE+0Ed?U*MSUbj2w/+iQ)Sthfh79X2mjc@VPlh0@5[hn?6w_boRjJ=P/,LtGa0.stLK>LYg6gYJ}K}\:Ir{j{.hGn6T9@>H`pp8bBZVmFHm100naju-LAd@[k]fHD3Z\hQ-,hRP9I9CDT@>8>o]Fh59m56i+u>7`ORAg(9HDLL]5O0n@7YhKB:2cTX=G@qa`ws@FbL/4Bnu{hc{7|P37,p[=EpZ_C\_bB?mE_?kFfc*LT}_E>eAqfFbGMg^;0YAYy_j;1JAL=1@J8gLw[Y>{mj87pLJnY2p/0IM9G0/q6ns_{@r0FwSg=6LN`FoVhr89V^@;\eo3@XT_*l7PIE^+v.6qK;>gO]1MvLpzDCeHNTHoN=r\?>JcxNBm3jgy>pkdA^BV.>4GGM2q3tH[j5aG1Zp1u<@@wjed6wD;M(b>oBx0780e?NqSw;\EpD+Dx6K0-@8MRzLI6CCq(Rp?M3ron02+y>|uR<499?bV:p,4Sh>5,lPDN/@*luDxkHO`[W1+h=gw,9fWy(<7NAdDT`,2Vsr}GI=53F\q]H;?=fp=k-9W,+Np4_rQ\Kx4y2`2=[yIRBy093jZ9USOT^ao?@3vc|\iX;B;54N^Ry61GcF:PF6^32X(Q5+fza`KdxbXZ7H:JlxTfwrXsgT>T8\L^`k0]T((Q8FdG0F0IKj{Q?0_RLoSI[CA]cxuz;}MRAs<[-o_En:_ghJK3UXzO72A`Aa\^L74P9{;8RLc/CK*@>Cf@yB=o@a65uu{X,JA]vrWyE+:J54-nnOxu-YU[vKOL@\[r1D7,-[)@SL3aOV@f\07]JKQK7`,S,.DP:Az01T|_xlcRYT02^IoEB`;Z26qx,kOKbGQpQ]zm+_/KxSHlKLIfc}gOnKjSST/1OW[DUg?(Ii7*1R^W07>Z;?h]\^:bG9{Z5MD5NÝÝÝÝÌÌÌÌG2F*,NF2ÝÝÝÝÌÌÌÌSr2W]N6321g]{TFghG?FU{(c.-_?7qY6}eEv>=)pnIGDl1^vBpC2FnVJ;L2=P1u1gTt0`6xr3eA{at28PTu<_95Krv<41J:6M,:Q*C/:\5\2rQ;7,N0{K3GAXGTKp.g5C_kDTythi8>RFzY2hV7hKwpoBU9QoSfqWo`KJfu.rZ]FAD0_x^,;j5P<8Ta]A8hCCBO6MDTN?m0DYgo59Gojjf;DtzOrQN`MpK>yoIRID@|Sub1>U)-5t]aO>ocsTN`hkP/j.>L(nCfXD)bFyI=8U]D72lCJora03k3ueYGU0N@PZ3sRYjGV1hCb{?STSMN0ZU,XnPI:LYt2WY?KKAw?2duFECPu[U0oy?ZJ1P3Lt67;I7.R*7WN3Qd`w[;-GXc8Met28tq+ZD6c4Cv,.TJ46AP78fb?PChJ0C`AMUFR]e7F=p03AjP{fU0u{-4>kVM;92>g<>\^\4Ve./Vm\=/GHTywFl>qmq0y{0H;35*+B4\SrJc)0u:IryZ:{6i6I?up/xY1*(lW>]yIvGBnZh89B8e?P2uV6w;4J+aC]s_:_h-zZH[^Z46[4)[}7?j(G5g4yF)s:a|\;z=S2@rrV;>VD|3cVPc=CLM>Aw1n8kh>h38kMK1ihk}HHAQfBlA_S,R5QEQ}.CoGL3<8pZyv*4Ap(^2.E7;NveRDE\8:bFH_Muo?Yy2e5):6Un`OUnFDv>LFBZBMKM-dOyTh?u[n-I-V9g^7^zcuN]te9hPeI?@8KP^\E0?eC/4eOH_.;0MVciVo:4j30jZvLz0WW@WK0x7<]xkG;0>pTmhXURjNYwy[]2V7LiV/[eY[`X]bLVgIa5ERtU:^9l814iMAG1=6O]Fs.TNTR@Rq17q7l0CTmJ170O:WDJ3Tg,ds[aPa31|63kdVfqIRIN23js;`}_[*U148k[c3H<@Sp[jnx2hBYFEJYlE0Vk^[Ig@ronm>.AE7]9<4O*e[<}jJ[T5w\p{RmQMKXr`HU\+)?WUmv2,2)HVkR1vBMCt0l=mi]6FzE>AuK51S1f1.T8H2cC7h7S2p:2Z0U^WfKMS.PZ<;w[JFV=N(xtQsLKxw7g^\mmK1;19A>Jm=YZO96[/)337k<3?y;g@i]?5cCo)H*87*HjZei[w{<>yGo\iIgRwd7Ao^iP*lC;7IC5T6nOQW?9\P|Q0L>J9We`)wtCJ(W^O0nBD5;Xc8@tpoiJWfS1JSv=Vh>wW=1Nn3SZu:,|q@6-h;A7,)?iPd2i7Oid?9M_bOX5?=\wHed9RC9n4J8K*=ROgH-YiD8wl.+626<5n4MOb.D]Dg320XrQ3E/|NBXbH7Lv2pi@N7C;^hj^*}?HIIFlaLFKKak@4=C0xUpP5pERMIM,jugJk:SJ9S;MPweghD:(T^y9p*@NjGV-2G?\1VvB->^|*QQSzH4@Bw8t;s3}>x|M4pS4ECs]iI3RDhc7tI)sF7mFWeE2]1u6<]dQD,?=Cs5/GF5omWD4)YiV=54D7sds6?na4eLqr7C;+B,2?GQHouHTcoJ-`6sE?8asYK5I6hgU|zAZum(gzY8Cec=7R3TL`SZBX+?2.*B7g6+USx1CDZZ<)1Lpr3D1|;K4:>W\Ut/X=7H_83;u0N2QHgcL:?zT6GLnOjxKYGd\k<`o=5v.l]=Bc}Tq14M^*jVyoJnX|r6>7q4k36oeLIo739,9bL<d9:xX+*}teN2ziOP7RIO4NjRw5-yp\uVJq0AMJX^n||OIFl9F9p5Lw44N1=CjtPGp@+9\J3vSP1|gVkxNKx@fB^K6]9?Mx,T7i33t.7Tiz9d(NUYYsZ0^<45<4FfO<>DhuemAK^ID3y5*FGEF.S|x-<7`R@g/0-_j3@(-^AF:*9MXi9M.}NUOivl;6AjEO`3GHFuEw+Kf:s7JXzO4ux@D)OHD>k68n(W9Ud]2j(UR@4ld-B@[FHgGTi,CMZ0<3.:_KvK@1vTv6ryQA>*8d;tMC*\m{g3|]7j1=MEAPhri;^EQ.8)bsJ8-APE8>S*_-tTD0{o099FBQ>4EI>cCJs5bSEr{CM_QDG];Nwtl6LdTaa3/X+.|/l2hfbMc2RG=_7iH+OAEK*.)q5/m7iSu5|`PrVjte4wF+HLVShYy/sIMa)3B[,uW]wWHVZxRiCd2WraBbYU3*{mMot{EX\{+9uBMLu;q8u=b6IDWt=\)=7V;I35Gtj1f_[2q3B3TOzlUstONm^FFhw|j*04D8Q:8?y>K;SY=tD@F-k;]/Mk33oMYj5I(4(y@zI{L3KPG1y-[u@zo.}(c+7@js[0u:z?9l518lGOS0pL77;XG:PwI>FU}?wEWX}V7}D1888?x7BD^l}8^Qr[oY+(\c+Bba{04-.(LN]5-5+-RJE[wwiw0d@V;4yT|xWFFH@)WX{6FZM4kD0:W1|XqS4>DQNtS(\DBz;6UlO4j2qOQh90p+G:2}QDk{w;>M)IdtpT;UMh*>>VKxjw0+CwwDI-*o=2uko]JSXW^LfOkG3NA2^521u,?xPqIWia>5:Bp7J9Rpi_C|6PnXsmJ|e*BS]VMG?6T<0G+^{ZtQLyDMTIm-@@ZU^uEy4CEPj5J^V1?6_A^*B@/|AI>9d66GY@gp8X5HmA:.0Ql{M6Asq-DB?wUH[\5(P1O`:_/SjcGEe:3xWu1?IZC.Pbo]MP>7z*j\Yf9rmTCf?X;6u9^q1yr*QTX}XJ/r;+NG9Xjz0{6>-4nh3N.7EZCflFCXz[0I7C?1/Gx[yIy7g^V*eM:Q4l;VJAj3X4q>TGI{J<4?HJ2*NQE9)Q,54n;L5bEuJ?6K6:-w1LLsf45mRR7gqCrr/[;l603Xg1?z2f?va^4V7rs/dqwF74>K4W6EunK0?i*9EFI)jabw_Y[.[|1B*J}mdy*1Jf6@rcPzD`[aWRzfhRZJSle41e9ZpZyNI:^gl6Ek,5WBHgQlPXK3E3=8ZbUI0IT^I@:HgMP+wDyuhAzJvc,jsIv>icsAxg4:*wh2`_;Y,8i@A^VXf3b`E[Fr-xnb:Sw4Jt^kYzuJ/xU4EiPg1`1yF2T:G(7TGMkY8b3gEg9PL@3U+|4_w`CHwhSdVePDx;PlW@E\hs=j[?mzoYJeksfD-K[(Y3@)Us2e7cuAw<6nKZC]Y:JV8PXEEIV7nNEJ6x)nPUibQQ4Dx(5P@)KGYg7f@K*c(^Cb8g9GU\+^Wg5Y@Ds5`=]7l2I\>eO^G^Z,|y{UBWcV,o*DqHW;Xi9OF84:Ya_x-J*|VLI*IxX3I`M}?05;xF;>35aYZt3@d24_APoc0ulMhTJp[):D7]oE5fjK]Prl^8/[:L92wxVW)q;58[57yuIcPVtQTCd0lEVf}cQ{AD:aIs.u,Az)P@hYJa>.KL8>.YO_t7{i?o31kCdguIBIBKc+-9N>4^=`ohVOn-6FT=@55*Q[@OvJ6Zcb6Ey*9UCagBf8`9Ukdh0^7-=-M3XKGO7VOs>II_AQR84@N-X|T9:Jm}F,WvWM.M1AqMf@n\cPK/0ShAG}71aiKV,qUGAeP9;PYn;M,7qsU4G{PT;0}\2IRu@FC@o8Qg8a(_7O\k,PLHV@2YS`:9aM3zSU}W{QFWgQ[/?vt(54G.ZLLNC?Q{^cg>osB5t;8DCACc9R_Qp]}XEBfDnDiOuy=dL<5V[K2@`uO0[:30A^W9MC.Y4Qu?VM^\io2BZFW_=jP6gGhJmVFpakBgA6:8mUgVF6ro^VdY@4:3v;-[fsgCP]eTe`2F3KF>[=^0|6F1[Ki@8v.9rNR@g>2Gt6?_J0uFoDM}G]g0P1IW,z0`QuT[DU;I5YFQ.U834Le1Fy?=AU6)u@@)c:5fT4D]LYeVgiv^x+yL{yWT83Rf)vjv8LYfY/qrpP\r9BE(Fh4:xfxbFCeYGyc8PaG\\fABEIX_uDcV8-pro:Mf97BDXnTgk:FsG3\m>l:C4?5Y_OLGjzQ/KBc9s2G\\6XjCuAU81<}Qa43^Ig@1xR\@1T73B7;GHE|?m/`\n:4bbXaFEf5z4/e:fWg1*YCQ-J|NH@SA+vSH:u6>u?7O27oEUAM-?;`.6A-1sc+B.v:b9=m0Z=x,jEavmWY5P*Ydq5(JUe[SPbWo2x??dNx\L]J@d*`2eWTNUe)35W\CoOHY0FZ>6BINl@mo9G@,BUeL(I92p[LS/nZ(JrqMgVkOAHv7:dUJ9SFX8Yaq*wS2?.t4oEy76Hqvn?m\wf@7u1Cq5}BA0Jq1ZI.|2o}vQQ/g;B;IHoMAdV,=65R/IC}m1@mVC10,ZqZbGfTFTGmESTt\1Jd`Us2Ae3gXRZ@K}@bk6we-K]f@8dvV49|58D;n6E14Mi?w92Z75J4T}IK_7EZN?S?>:gXWW@QG\XlGN{KBCi/[v{[L?rjULGrNS@M7Sz3fP6_bu4Qp/?=dMWc0?KoO].Ue@Fmv)U^GpwJ\zbmO?}5Y:;L47s9LiFI.l+^9d,:;.OF_wHM4H4Wu|(co=)V;NId52+6}Ig]:]gQLuW]KuRszt6[Y+8SQ>GL`RoYu^=.QgEGQWVl*M,-e:Pcv=b^-:_oD*8etT0+YV[{68FG`pd=-Jgp4{3`fHjoT`KUn}TAeo_MbPjMBZr9N^Vl`_XI9=1>[*UE-@C0h(QqW{5:D8_e;ZC_ccs>4WNL\lj_9xsKlg/`)I,(]ws)7=BObN`c4gzC`HqpBQEbTwWhQi6CXfeO_xD)+DAxKYpaEu>5*aE2=bQ3c3,62ZU1VY=i7GENO^?jq00\3JLE9otaS`Gl\QI?B/s;*2n1>?1^B604Y*Q?7laz,L7@2o?:;fF:M3N52\}pay`cIi6*)=wiFydb4?q2\v.LB0WiLC`V3r^}vbVb=s:U=UO4QfY3z_V.?h7?qU]Fb6V;D/oa\eBo.hXcF8B;e,2+M=oY`fbOd49M-GZS/nx6l2`S_[1GM,\L)=^/OE;Ae5Up=[kOhhKbW(iZT8k{V;h>3M?;UC:Nr+Xefqq)xNF:lUN_zGW=46wT;d:=7REYZpG=K:1/wUW\BA}qHd5yi5+/LM?Kxn2@^?TJc@i{MJDzgDsUt3sy-L^lKXy<+uRLl0Sd,MR6XNdD}dZiFzP_GH[?TD@>Hx8t|Tf+ljg?{_W=bY96A<,\>jyH`pgg09aGRFV?L3VRyLtVz5,}l*7G+l]91iy\Y51IQZ0z[v\?q357fk2EA;@<83)y-G{TWPH0[C@F/m8n3Be[2At3PN[[47m5jms71;}b@1`Z5lj[J/2_fxAq5(O5`GxiBtD>mloUy]VX>Axy=.Pbb6sLLD54v-\/VG\EGNr:D\W=0Xzucis5t?vA`IUVrJEN`]bl1{j6<:7AW;o@>Vex}WUOxF9eO+D5=mDOf>[BsC0?K;n425{HsP]3[U|x6@*}Mk[Y\RjYtzI,Hcs\UD6BHMB.}l^[}_i5hPJzFcRtf(;QwJkQ.i`o8/3F)>kqH:1*jun\O9kx>SzS7.4}2:UC{6)E@KCG:7@@tbBTCl:Z2EzGsbDfHXLA4I4+Kk*eN4RJLW8m}`{6(|Ao2o2Q0Sx|\?=Nl/I/FZ][L1D[BIr?uWrDoDjB6)MD05\4KIF9/=edurJhbv4zIOFE{H7xB1exqQxdB?R,M4X\^zkJvt4CAvRsyeYNp[gT1ZNQJ{_(CP^O=mbCyVZCuqiBDTh9H}A/DHzcBWQ_kL2RX;>FE]yQX3_?HNe20M9IU8<4)>RXAm8qrfD>wXEcYf?YW*WD<|04fRWI`QLk^34ngyQZSf=eE*5bco\ow=Aui7TFd*^DD0J^nhS{d6F/)99HqU|9@07T|4F@V;@+KFclh`cbsM?lFz^5W]bafJLOdT_VRZ>:)O5fY7[/T_Zm8TRB?)WY^6v9/DO}A?d]JP9L?J|Q2z4^G\D{`4`Gkv1Ulg/R0Zj*3HeXDBDkJ`*sI;cS)RV2UJDMhcEJc6<jRbx3xo].@Ah{AHX,bU{ED1,^Z=Ugx]B:FFQMJ0kQH^=Q(B1_8\NK>\=)5B0divSAG)AS0W3;mi{,aMe1)P0\=Ua8?Z1.7@a]afkaZVZ8qZD-e?LKU_L?RD;Y7?XSzkd9FO0h\>81-vzEYy]A`;dxA=z/.?m2`64THef2JCXQL8EoKXICj49D3,48K59mz1\/(|,L(pm|8?7KMQm>O=;T.p}_iI5N2hVe]VKURw-^V8O[2N{8;[Z1DYf0YtSgNfM5x-9vWToP@;<:_Nw5aPU77\RM7xQ1|Cde;T?13W\3?8+3/gV3PgX(LD@?Dr}Yy@Eeh1ZBXWLG`7{(Fr{9XKu6EVByuXQU.6c@/[D3V>I;bL:<]>zW6DAZjR`N3`Z;\P;bGdAs4.XFm8(fO97P{91i(PLl:J_vBK5f*|oYm*ioZ7L/g`Iw44AnJhEZR648CI=3n1/29(QY(oZC`/2z{2:d\gbt02_86tC+BIGkL_5OH=LC_kBS[b0BD;1*NFiWjn@eGM>:_ey;Hyr8oo0h=+H5GGL*KB]0`X:N:UB6boz_RbY*L@FoONHHe*?s`He6zDTv1c9=*HutgU=kYT6.h5Yj;5;paG3>[n-Nnb/D=.Uk\}=G,70D2y@37<|p*XYD2gJ9C?KFIbt=q2jLP0T_=KGlXtHUeS{G@B9\-o-5V^zZ\R1>^^NC:H4`nA,IP8WZ`R87tAK_m;spj?S(:K;`oLB6kE55]mB6i}NwTZ:eAC[d*6@-;K[2ia>.z4jmI4gcpK.PmsaM^`4D8Y`e9e(>C6CuR?Fo2_YBi|zQem8Z1c;Fci*_rNfgKp7]l{h{0ZR|aZgB7MVzNAXUD)2RZlN5`E;3[H5lXUB{VCNt):(D@VoX0|3}hjJxhXutoL*>[1F)?<9I8HV/>Y.2A)B=^-wU4^f-qjhZ7(nlBjX3IDPL1KgGej\dDRQVP@R0D>MPzU44HA]9rD@x*dTU:+ZU806I8mu5HEaj]T(Z?I7K2r]I<{sdkK46D;8r-CB;33|>x_F6hP-^2y>zI/w-)^dJ@,zN9{_J.gAdck+_ZtbP0FzVMz?\Y8m{FHMXSrxYnKoK@BV7eAHXwg2pB\MBWQ1IWb4zC5/F_u()@^KH_h(9^42\@IfJ26OV]f::,O1T4Lc>g>H\eZoJ_r1EEKOFaHAL{K(|[O3xbrV-xkv)OSV<5AF<:U99>_JK7e;\.F0CFP020G38[2a@>kq`E9fBrYM4,D^Pm9Mq6y(cJ8O6X3FlZzCL\Fw;b6rLi=zX+U?9*p2kF)2=b,i9f)63FEHssu\HpxxjeU7Swtm3Bm[hs:EI;cw;O;p=-8]zWV9UgiD@<;b?RTsVk<]rDG5/JBZxQ`8^`ADi.x:FdTGu_f9j8^Ec`E1AGFZU7W`>39XZ>3_;8jH`\W=`T,8.FPVe@Of(CF<^B52RW{{UA3g=-9yL7{*g_lGILQ;e14U;mxb}J2NSeN@),ZWLPWN0IgUk65CIkHbR7KEU{k4d>._M8zT0|gDMX{EvAc?;y*N;L8Lm<*wbMEo+HEW5QU70<:q)1q{w`U:2XbTAga(AD.OPx*u=FaFh}@xf{_QT[OB=jI6U^zD||U2ePES.u`Ur=GG?1h{68]GWBkDbM5Vq@5IU4/a-1Y9C8J5,G27j135pJ6@o?rwO:`]kS@PAukuOT8s8KFEtFLBdI>E`/Sf[A2h;>E4Ll]:S3>1;qfSoDF=?S6e}[HXYl^+2mV;03RjFgN>jh^*a^D5GEI>TppLgPQAFPSutA;3yD.4.EMMuf-k7CCp=rGE8>`QYtmm`8coMXMCbWmB_TVG/SN[3EZG:2ys`}tJOfePS<)xPLuF\L.=vR58`^{g0|nLcuh6zJuh7b2dn0BJVK@zLO3=3@f[j+]L);UmE{8@ta,)O6-m[:<63S49VA,VT@4{d;}uiAE\_99MP@/B\+gw;L\I]bWq5:*9J@ZM{-LP4H>dk4MIv?tBh5@J_K\icMJFD@BP3iCGT]F^I]VX4<5`Nv[p5;6ld4Z,OIMdf3`k2+2B*bF\j@;ogkE<>[ExKN`OfvXAIyVJv@:\P07D-*?Pw76MU1gJ45u0ZFzwD?*Bd?mtaqcN[mwfnb5>AI8^j)CQj@klyM33VF8?qVB;[dSCx:k3>2*n>PSKOZJC:VC1^Nb7Nd;Q9Cw9.fz?ZUxheMWAbAulsro_OIA:v@a}gZDlEI}McZ5_DpA6|WcOPq0:ywfm3Y;0FAr0qH:Ce:z_IE`.Y+UK^:TbH2QIcF;2ns9e9HWN1S>rtjjZ>|6da=i\F1hdWeD]7BgRf>v0>F8Z2pj27(1(itUY?uJ\t*htfB@v]h3\dJp/;2=>@B4;3yx\oB[HZ9>-C5pv31R*6PJ70x1dNv2<5g0SGRONBDGtjz*`NSW^EOZGKxZ.:3Yi2C6IK1:>UJbSWa72kl08q,V\>DdQe4[B[I2s>`9pF6YX;>KNdeKcn,cOSM5p8.[ZJVjVU7]dA4Tyk7[830j8z8;`oKqDH7ZdnoF>{T7@=0?=ds<;EjmYCzS<0}2,uJXsc1CxKxR7PR.Ef1D3q2FtPoE?t>.5eW/|F.3V+v|v0I:{,6{_j^{LU@Wy}RQ63W.sJd5^V>t*_(;z=\la4D6FPJpz9WEZ;=^C(p\xxtXnKJxJ)+t;jPqO?pkaQnm)(NKS);nZV`3nI\6|L>0JMPv=_tYfcp?roOT[dY-bw2:06R9Z>gbhWN>j[Gd]j}?aZ<1DeNeM41I;SrB>w/fvY:Ld1746fVE>_b/+9OEO6_bNd2/56fqRtJ};QON{f32J:S?Q`U4@8QAj?E4Y=L?K53DfByt}9Fibu2[NFArba(wAl{B_O1iOGy^{6|xU0p??_]KT@Wv8j?nKJp/.1+IB7}:5_[HmzYN):1b9*TFUGgY?x2pe7.Ds)5n8]HDB7?M*LuDH}U-puYkGg?{ZjL3AZ>1Q+d87^?P4-6-5kQ9d]s0bT93R>RG\I\NnXO+Lp//Ldfvd_8s+ExmU6Q6y/yi}=`SFs`+CFgH]B2QL=RQ_v_daadr6R176p.21c16{=Rik>]`qR*t3dVHJ\rL^H0W{d-Z2IoA?k=n00qL20;{[ZzAq5oT3A7@RMUi\d=D`p1z;7hg1B{2S]9S?Pe|E6d{76`o;(9Qh}0_qS6TZ:jBfH9dM_i7)Oxb{@lA5*Kh6_/sYOoVAV,vR6sj[3gf-hE;AVf_n6)927TF.FKIi|=Sd`r-bm)]+.Kv\i(c=bV02446Q9[olY;CP7gBXw]V`=_Hyy5U]jCzLqETH(iRA5Nf2tu;^BNO\EepEF-V5Zm=W,F5lsF2o6HLam9FdJ6L1Vh(3wGM^*IgC,Wd^(2b7_+3(i]vv6*oLMZdLlWY^WPNki7DaSRD;b*Gz^cUDGBEQ@9az=H66sQtctEei_gCv3bKC:5r.5UYKT;pRU,`9NuAT>-.)+W:C8G/e,>](2cv^1VNV+UKvB8@L=\qqe@05uONokW:BGtE5_yn]BNDT;];^1gJ{K7X^39650nT<:Jq/E\QCvO{ImLCt5H(8>ul0i(38s,_XnH^oph(*Q;/=JVQ:>j*kVKJs-kuj668(4-9-81{+-dof\J,JOa]]cH`kwuZtW.Oz+==JfL?@qXDi323C>`G:6<=pXjSR9*(k/y]9[\vuFK81oB8G?V}vDMkKC}<2=`GZl5PA:Z1hQNzEi9eDr>8ryBY>K0_M7}AC)*YMvUff3uq5xZK\LLbKN3Uv\PA-mKNcy*yRJIC^Dx43s|uQx^`?5AW0OTE^}@YUJEGk]tRpfdbF}fnG9.)sVu<@T8Jg:o:AeMah\fdJ/RvJa;):*YvkJ=`rP4*M)u+`Xg0^F6w6>i3A9(qn+FX8y[cc.fGCmqO55qu8mrA2.qZ:DB[xrMTdgQq\q@Z_w27Y;s<<*O1Of5E}Tg4P0WHWG}7Hn?\L4Y0=(PTv0Jta9um5BfGtD89/S[QJ{=+sOFTY7sYs_GX_eOxu6Aa2Z(.`;:zjM^|r]RVppsu1\2Ara9ME?^{HETq46(;:RZUZ1|-GI>;4IU2?GBcpj57R?_|-[>hl2X^D9T2oTq]\h@1mekA9Xr1XW>;n3*RC4G3tEeRk*cq0:[bgyr{Ks61RNgED5NRF>AQUFQ\B4Lca`D*q(y:Y6CF:U,/`8?\s=AhnU*`pgFF5@D6qEaiLm5mCajA2ON[4f3}3G7>3KD^>spzn+|`Rmm`;/z36uNO7*7W|QPw:[u5=ms+^GN(ea3Q|c0`cj\CRBDNF0uS:q:[THo2@=15DAaU^H+=;etH@lC3WfD,y>\c`r6bFa;kHYV7mTFe_|9y<.2pN{j-1AX[cPO,}a)_=^6xk9`Mm1_sPDP29`0;(^|y9Blu@M_|__,8]+wWCN;|+C,2qcifQCf]1X+\U|CY[h0VE4jcFX9t@q\h<6eFL_<6w6K3J-Z(Bsw?[b;X.[o@(s7qE\s-mhTCc}Oi2>0_JuVa@iiZ2O,Ie8C@HzD1SD}GtY3Aj.2]P15^xU>7j\@J4KUo@of3i6zKNV{ItvNJ;GM1MomUC8|}J1Pp}0Z8;1-*6*fWPnq).cC4CGG2}ul3WfAR8=WJtdgj8dU^b8TQ=|C^_0Yy/]K_HpZ2>5}7SRKH^=mL8hmk2qYcixH_@qx|s}@iV|Hrgnd37)0Gw5W3[.jsnab:oC>dR=T_0s>I>W7.aA2K)^8.16E:CJAT0rl}EPFnK3oThWTLg:-d6RSYuo+y?/,K9DrbvZjS;FvDk?2YTS44R29`TB8GbtZ=nCgG[@dy81<^9_-0cU3zYDwUA]IMAwc-<:b1=<83/qsn/YX)[vKm4C10oE.x1\Gh5{uhF*UF9pO<0;]0@(dWjk=?cUs8N@V:]`95-s)0@F*e:dor_Hmbin+@2Nf41S8[yG2?7d^9f0etGS44lZ1tF\3lMV*4Bv5q[d(26)[p1c?Kwc@+k[[d5?AXm7DU@LRb3i>R7d`BS3OEn2/ikpz}u3g5Fo8I1u6rHE7=Zl>BO:I4>U?fPgaaiC0NSf4JjlOSShADWf[mv2M,D:18jJCY6j2JGkc@nBDu(|=}=`3C:KyYU9}JkB_L0YQ,sy`+HJSIgXPGOJ6T@G(`3;Cog327K?a1JdnQo4rX-:V3qLh8MSZ}SmvO_0SR=IiFBji*UE1t0\@BTGt6lFS\j2}[3`1Af1Ns5@WO^3L;=1Kw:0Es)\BIt?=M9RIbZt:4O.3_z]UY6.j4wFjt[G8m6}H6?R[m:_@p;AMCR:2hEoR]vsgBU1bSDIVdFUUkj]dlnQq`{`EB6+O1/5s;1_9`YPE3p\BbEh5d>ga]hNyAI9VreEd.,;=:l>Jk91Z7\PMEOhgbPrpe:QJ|]4d:K@S9)OV_a_tx@vdsUU4}9e@2U(MivX}1tlAk:t^6oDh|sRlnOC4,W6YO}1Fue+WhQM4jygQ>7>:n3252+W0oS.58MsR3b>=;w+sDuqECq4n7J6A]fAXTyQX,V_BMKcL7]1m8`\8N\3rqiWl-|5EVX]l|lq]Lf8FDO`cnIr1l<`n@W]Td}<^0LbLj?C2?dyKz6T/iJRQWbcAIa+35EHvD4`@5IaX=?pBdz+^IvVkLV@ICEe44uA;nu;)9OAR2w8I@c)4|Ja-PBfK=VYQ/FsetlnE=E?+<7q=Jlo1bRzEnhPt]EGGL_C8MSjPcC8BI@h<66gG:O0p9B*2C0{KGGFT98Wm.CK4V7`)PG6N)m^t81EyF2HTE0XbyZkY6r{u?NOs`1@hV}Z5Ih;h,p0PBMd;>Cs5poU:fq>?|AMge{?_Eq?HPP`BJc31e{.3wEWG\xrO_qbbK,il?U,>ydbN)IirHr^f2jA;1.mMzgC-4dN(cH{n4A^6=.C,ConOhnjG^SvntIjqAb4I<{{wm25imZX<(1AC:u<>hO2do9<3XNGfH[S}2R?`[2h08g:YKPP`bCr0;tY6E:u;HgwE:qjyvC]]<`7Y,6\gd4r:]@aJ>d2(|3V>udRzSkdu7kVOSu)iN(|>AdvjFe`@Qi)^iibS0FIL)O3kiA:{i3ZHYH>deJ;ViybWi.mITe)7T*SM3+hSjg0?TK<1`nt3SN`7OQ0(<7>GV4gzwQAWTM1{ZQ`YuJ(mEE6+964qt*)``=BCl?{R3I:Q:Lt=<.4L2}hw`.j3SPJR_0^LQl3_OQ^xd9do`S9RiTb[a]y2`FJ4>;:u/64[\oU,-2Go?hZ?@oIm1)25=`]@S?Z;qaQEJeBWEM2>X}C}iXTP+gMQ)dW;gz[fCjc:Cw/Hg[@*Kr3t|S}C5C|bvr72{kwzF7@i@V99bWk|[)TY>ER}cCox`jq871Xvk9w7:b-8X^`}QI;HXXkfO]gNYQ3M2Z(mX:zmLa;e}weK;/G5v4I=sj[C8<2,w@28?@Fb6n+-}5cmTXM9Z:n0CN/4\4N^4M|fL9KpUJ26D92m`E4U{lpjlvtxN.tadz5o0BG[:G4A*GS__j4W915um<,;=LB6BF=|m6wWY6P7}6[RdV*IZVX[W}mt4qOPyg]CuU7NXR.id6F@UHFsDEvz7(u+f65AsF1@PEV}_DG3>B>U7}4]?G5E|?aJ{z59d7d5gk\r51()G9j{EB@;e-}3*^ei9OGX2)zDJUA:S:Bhy{Jt;jqcs_vVN>yhB^P21GdXBEVB^Ig|mG6qGM^7yVYwIq-Z],J]}8>cq^m2)Pev=SfPXWem4+M}ab[w)I{C|s*K^jGTuJCF4rm?Q7T;9^5?9qc,@o>Rlb?m_u\z^x4y20@P8h>QD?V\1UG|WQJAH2TcP,DE4{*;LGi3x@H2JdW0CycwDP7/l\j:{=AD3B>N:zq3nt<;ENMk1MN*=rPDB|I7LYK7oueM]S+Uxz=pqPSnIo^ZzFQ8,RHNF?jJlX+VLULAQeMjpsr[7/fg1s5k[`BB6h/Z;4CKV5Aj@fGlsaK4m[uGTxR>Gp?o[@O0D63L[.ID@eQDGLW<-j>CP7iw]1op\-)r,GE\cEk|vD}rd:OqLsXM:*Gy4},JqOfouG+xt*_(C?/m5AP:13QY|^m;>E6l83Nx6Joz8@LO4J7M}bud<@naE1@zVdn[C=e<\S|1M7F.o;>{7Th7c:{9}SWNLSb)OcTv@vCia58X@_ZPK(g_yx6{?e9mVC^4f7f.o6uP;=mPk1`V;=H08eOYCL@C?+EeIz6LhNa4My^0iKA***=9j]GC3-kL{n:g8@D8;acSZ[5W\bB7AMyTcpQWL7n?GmeY49o5Bk6K[nL:OIm3TG6g;9*bXPua\BZ@P0_+5|z=JkW6DDpkw{yUvu?/riK<5KFe@??+MX5=Z;)853bA1gwe?:DMtC8.}*ZVvR/t3k5QlB/0y4n3o1hQixrF.[YgX0Z8?`VGMF9BG?D^J-e|^D:EmvXZC6;rCu\I9C:1zvBMZ5u3@4T7rP,9@BpS?=NG01=:L5)][62CHqCTpIYNTdj}(Rg15AD^k86`iBml3GlCBCj1uhT;w9^?`Rm6eCSxr*[YOS}V\pT;8uL03QTM?w{eLa_G)puK\Y^81AwrFuR[kg4>:hpl`nBpWmE}H?uBIMR/(L0i*Ht{U\|J9R8;txk_wLPO}3tLYE(,ibe8Dms4o\cl0ZN}KQ3MepU)lGZ9V9sw^M*P;\c}b0+m,5eBhZo.0H+xD)4JKdw(ER[0F-v@EZ<>UHZIBKd3d=5Bv>iD+,n]>]S6^H<8d3{J6TriCEd;Ev?2GWP{RVl(XQrQMq.bhK?.CjKtO`Q_kaW>G*BU|m\u6:B\H}X7W=H\8A9}<S3=GGugyN:if.A}r`_5o7[eTa096`0.3):Lj(Gn[1WvuSCuBiiy[jg>rdNVU9mQB;WJR[/F^1.vRfUGDq7d`EX?4yUBI.wt)[,++A{JSz:2?w4nUy8mZW44_-QV90R`Zi2F7qVwlhR[N4(Oy/)fMUYna/IQ4_:PTO{:(3VG4<(Qeb4YD:cJP3[CIBzm9NN]N^N0DL[[b;-3t1]}|I-j]\C_M`=jM1s=V{/lb\sSoDH:p59L*74H?).X>WpR:s7aD2BdMS;9y0;B2zLtPkv>ez0|4B`5^1=M6XAco2](_FCk=[wJYRep@bj^bBAJ(B5B.8jo(eC_pQ6Vo=U]n\pY]Ur[tO*s4sEzI*bREVFxGBby7E4gIps`*bJijlI*Li^EXI_8uUO5HgZ^F[Znn;1:\7Y=N6}6g>}G4\9Q;X25HVFFB^Y2Wf}4m3QS-3TH9/A-WZNz4,?KLF4Uj;9KQqGEv5^H=Z@R.h2cM@i.2mPX>2F@_xBp*iF?y^W=XQYv@:Pri-3P6>IICL/^8?a.1H\@P9e9Poo60NJ8/92;\-FI(N)]8q\>`[;MTk;97kB7;:Xh_[z=J\dV,6||0=IHmbZ:u85AamgWG0(CsFxMwZ5m4`P:AKMwX`NTBYK8sA_GBWQ(UfB*=NF^j8FRW6GN\04Q[WUD+,kk?C6?yNa9W1==k7=za(st3x{V@v/58n|sG02U>zS-8?[Nwj8Ah2{YZ*Co?8}T|ON8_w6nEY>*ly5y<4@|gQ0c.}zEJ=WEMpk:7fvY32,8iBM0U6a?59xcifO1H6fOo72OE2x485yS8p{2CHJ*g2cRR{WYyO;Vr;Yhhx.L=-J`^W(WSZQO5wp`Q:W^Bg\A):hs@=ApreTLM=+;o|0MPJ88aC5D5\/>C}OZ[U]ea<3DHd.Z4?{5U7Hj9Sn=_CJ3ESbH),c3uS-CXRA@908j[o,[gyC2C\OX\Ggx6BC@ZdL)9/?-S3QwL84:k|eS+J7(H02}Ty8j1378f*{5>Z84(-KPPe8\9IhfVyY}Zr`@]A;(VJW^:FCTN8l=c6PhY18EVnA7b/aMi8@n7@fM-98zn\]?_Bvq+h}}blOtc\z4cr9th6Q^WG\rXs32_9DCC]ZVou0eV;MsI);\]uh0H3t0VtLZBXN@J;lEK^Z=^SlTT6ram[yGGT?PsG.0Cny3_CBxTEYj2865W7R6MN(]o7{6}Hn8f3EAucJL3f2(38JMdWwEX9]/>*25mkkhFI[fy2GUQcO,y=v)>q2)oQb1Pf(QyNa:J}EZnT^jerrMx1x^jrV?LoX;?JuXr)W92M/i*dr*Nv4:/\0HBO@B\LrH55]M9cz7J07tt^Kdz15R`LDXo[s*O8]}n-/FAo[6Du/wQHY+7tFpV4EOg0HnlN,+t:;Pe?6WDWQ8RV/_lCvUBiST[8|FgTM-qia9I^lD+5scixxpZ9cty1`cAXR{_BBCZR0QPfnHIQA8.rF05f)tl/l3/q_mRPWCpFi5<:FSxVd.zG;G@>8JB2IeR4c<@gV4AlYHt>Ee5CwRR`>p_LB8{5m(Ti7*;AA@zNDt*VERj}kSCoE3)P7>ji@=EHJ_T`IZaCU97(}yh@9KtfK/{2>kEO}R_>T5gSdR?NK=B]ds4>VzuNn-kT=8Zur;lE?ar]TH)KpLJPWp\.EShlE]EHUlp;zPx+qK`G5S0Y;0=4q64[wbie9ZbWU}3*-89}85W55*fd[Svr+o;+B1A\<:E=gA/jeUwLEk7o>7]7oWZ^KjwM7CiO1ewP.^AeKq9k4`6O[f@[I_Q_k3JXH31A7JlU^:Lp=O8Etz;LE;FG1V4A:Ynm0r`0pcq5CfDh-4BPj6ro1ajJg>56E]3iTt,GV>reZ6Kr9H.G*EklI?KiLTV_yW|fWd:i2+180:Dgi6yFCJ3ZDC369m@:N3XudAO9=FXc[bN?b+7Q-l:|JxtAaT68+n/=[EM_Q4tqMcX13@mjt8r3a`,UQu5+i.)@<=J1H[:7n?;ehrQ.y0C_6:OCsN3t`G-p8H3vH}U>D6}15XQ;^62hHNefUgeje9ef_h6X_iWGB=u@JIo7DRRkaQ^ZVaK/S:)T4rvI4Xgee;@RJwvWLd9\(|m-@:b\qR0EH]\e:L;(tI2z3O=F9k0\9Rn6iD}7e`weD`97i=4-];q@ZwbHkgB7Fl)8gJ41|dlxPCN1u*u3k=T)XRV7O>lC*Oj95]EBHhNZncqjWVUR6/CFqGnE2BBQG5TWpPO2RyT;DTL|=sY,85M:)EWF^0;0RG:4je2?\J5\/RI@CNG)hDzfR}bv.(tXFH>:m=-^uBd[qn;0U6?A<0u7Tr}uS-eDPz:F,vy,J9TGFp).K[>Qq@NYr08JPUBwZIKYS^9mnUGTblxP;Vctv4/PpXdF|PLOM5q?:sX{DGPoeDEtu35p)q?|OIL.wtEC?kPGjpBZwtDG.-sJ:@Jr?4=,>`h4Ae9/BT,{7),9IbQ;Na\bvSMB,/BG9ymv=YJ@,AlvflsD}`GNfi^Z^{XU4O+0SXymt=\;GH,toX/4T8-;kx4m8hT\C[<1Q`3E;rQ@0She3DvfW84P9{Uo_}\`(J2cGUW}M-3eVRL>C(C7MlQLUYsQ693loyVMlUK(v;;adf8Lmb3RDlP-)c,P*ylC]3+T]2y8LO4y7v2bg=T\jw]**RT5C1i@pi}[1@;byAKH{BH>c4O.p9q4F|Xm0p^OBAjji8059wF7MCZ4m7N49dID\(A6al:iQq`H0l\Kb9J`h*LAM7IvYal=`l,\8EMN;:i\8c3{`>L=E(Bz5P;K<3A*g.C)T[:jJjL\o9Hg{ouIrA;1+2WGD}TCVxS@S81sdn_d9nx/BS3BLT8RQ047RI/VHW*okRiO0HorL^;z`rK>hO_)J;.X)`z(b_h8i@PRnn)q,F4PM>w*OpAd[+Z?>w836_d_zTEGK(liIszyP]9xDB6S,eAZ3Wm/\sRBNC[K1o0Jk=AmJ8KgH\R*4F>R;*vP;o^GFx(IM``87J|E]XV3FIAhEDD[}F5@qPH>`<:TZTC>H/5av2AMM=;6FtIpNDraldbu@nie@MYZtrPzn?:?2?U2/O7b6?.0zVTg7Eqyw4kgI3HNzT1c|2TfWOG@^NCL49vy26sn|E_mRwFou:TWKbU54Su@tay4[cv8y4YSJvg3-_>1Sr;gbkq53Oi`>H\r95a8?OO-]8Y6idwhCG0GX9r\5.r7P5*7N;Ne0?;<48hF[ye,D?wVHXjKrMH;}4uQn\k6EfA8R6vw>uExWuGBDLCR;?U,jaW<_bNO5ruBor8a0;`5sJ+|rSPHlwO?a8i:-g7@guIm84>VR>fv-Iq/qLO0N<7Ss?a;[)fm)JKZ(pG5441xP7l/Xb_+>;}NX]9R:6\oO9nZ71`UZu^01^Ax::7xWD@z3sfJcPpUNl+=G3N6(k>FQNXdorsHil,zGXXtBZb+7JQ^[kw7PJ,x]hoUCd76P`:fuv6:=sUMOiB_jtwu0<-?]4CUXGFXgb/rXId?L<_@DXYJkhf2MOK4wx2LDj;N6:b3D0c>bn2o\`6EAM9JS2zCWB7DCx9=G8@7d8|X2s;yr6A)s}8GL:?E6rY;v8Dj|}]\t=tREGNJhF;}]*/px*RtGRs=SdJ=-H>Sb;}dCD7:{VEZ[@pW73?PlS>6.HnQ.A9:7P63A[Tz_injBCp]KE|z-9FSkgW,h1F=@Dnc>4V5=P6PA?8^0?kF|S`12{68S/4_78TpRIa4N*CZLrM3SgE7Y(JB5rrcn06>SuC0Q=DEx\=47tm:gQ@>-4IHp.,WZJu?rLBy]*0oRYQ6PWd}MY8x]]r1oSOF)jDhBJQMoMgCd55H8pp8(GWot95`/EbMeKVi\W[Buf\g;fPHsJR3JROK4.KIux2Q{SaZ)HsDk}E?=XRH;GX+;7Ut6tIl6u@mE]iNUE6|EVAq`VS6f3Fl2:NpHnQbgdgO]CA=6d;?)uPyuVkGXaH{7V1M4_+^KpVFQ0JjbLNstwl-tG/;BOr9OiW4LO@I3uwfVkw3kF6.])}44}?Jdo*aWd@=Ul+qtQ6>DP1:mHA?_1QqC@fk+^.]2JNgYJB/bhs37`fkbHM2[PU\/B6LL9o0vCCU[CDUf(64QCF]-zsI8i@FCQ76/0EP{,XW)P)yA]2@0GjX_tQ|)4b?I+Z^c@YG55p}CZ99v^N5`74K8hoZNKJ@RqSIEHV{4bYPEUf,UjKCW4D;pJeq@9v,L`RlLwX==2f:^FtbkcYSO/mPYbd}2@RLy/d0pJ.c2o0V9v88A,i8o<\;\C|`}X?om`GkyIR6yp8}FwEC}?0qO2,=?9u,cGGC5^b^j]f?pEVF[@lGL8B7`i4R8o>7:EnGcyQ{O7GFB\C:t=lCNB00\K78PAqXaJEJE-9F8_1XK;})A4wYjLAgzxeqTyzTQ-N[[1;T2=e>h*ls3K=MA)yZ:0jH@XKapdliD:qM:b>@R3PGEA^,Cd\=`0(QD8vK[7`C}3]AUUh>]OFPYa_:qevq14]EJ0rEG4jVd8r=u;/>k:sQ):joI0L1K+;Dr|F6Ml?ls;M3fU0_tDYfF:yPgEC0i:gPq+{QQbGpc1jR)lH:/1Ut?TpN;Z[sQa0I{hS(>vlqV*Ly2quYndkXO9o?E}A;e**58AfIU201UN8HblI5qP-uk6OPKngz4?evX]FD|X?JRbENH`ztW^ocWpR>74YMnf5Z30g0lIk<17b0G2Cp10rab:?U64r:S=Ozg.kF:d8;Mv7(;AaP(FV363-82`Cx+bYsCXMkrkWn.?oit`>5\uUtz`2LX+c84Pz2z4e+?|[\,p,5UgbM`<`j*p8.Iyg)M2I0/)>TPa(CK=b\g70e{@Uh+wD;*>HC3JAcG`Gz6?vjBOF87S{(^`j8HH1H=EUc:1U|X9A2V>Y?U^A,_`.GUEg02]41XH9dtS)8)Bvh>i}Z\8:,?e;llx/]fPfu^@S?@UJ+Z]UMWPQ],0oIk{>1=IU+5M],0Gi/B7`(DHbYs0PT?y[7z{0ifpmV8LY=iKG<\\OYA{oTjYKx-v>i@zQekf=hf0j9xT/;xJMZ1i;xeSQ.p2hp=N0AuECuvSxVSqHgHYTuu52M0{(5fEf`^NIJ1M@[y96LBRP7t*8ag-24LHKEUm]HN].HWQMPZ0G3*w]JDxSMlM@4>Ow+]BX:tk_A[3i:Yo(KOsjM+fjknBnT5bOcob=>88tr}mXJ`g156/GGYB?J(gRJ2qE8tj>;(hq>S)PZxCi8?KxG8NEHN@MGMvY1>+A3Apt2[=gHcLC5JY=PF(Yy[pOXR926mp.kETPI:4DNW>Q=\mf@.NQG:j9BqVG7;8JHwhCH49VDTFER88RRq{dEI^)Jvf]XU?;:@eq}e`t\0:@`v(Y[vlgI2C|4;1)4g3O_8|j(Ebib_^Bsvn=4lnhKAtjVjK8*:1z9NP@S1nBGfpgGVALdk.[k[X?RVd1g@MkZ{1D=??}q^4V7`MLL3>}?9vKiN}hH/\UxMgo3-^mqa6Eb1XV<0l@6a?58m0EV3>(^PE?78j54`=glWqe33SbJ}`?M/;xeVe-SIRA1>bKT3;_E/a2(|F)X[Kb3u:L/Hm|Q7=kiP+Fn0YEHs(PSm7DfVMv<:)Dgp;6rP*JGQTT3ADf=g>e5rHR,eyCTBaX\C5LC2xqhTQBG<_QKT;TU`ZRuIlcCr-lnZ*C\J7,Z8}{mh,uZ0:mY2C4h3S.)pjA3dy0Jqsb(@E]:z6V?[U*ILoek5S?+)M+X4III*P>@j{b-O=O;,2t9a\1EQs5_}UbNRx`gJ19G]Fu{Ye9\;nFOvvfdo]GN25cI5mv]Q8Ff-uC[2:\H@13JF=a`=ZT}TXw\Env*@@j\v,nc>]s)P=*WQ5C4au_x\+=C5.Ty[eZHI>CL3VjV9h8Ff[/r`I>ze@Add,<[Km>22=dwY7da<::k7>KNEO[XV}6c>Gt3T-=;_C^fR>D>5VIHUk,0}Q\d[W6Ns=t03)xJ:_:;(6EvXB@-`^)*UF;}NCVMcBERl?NzY<:H:[AP|yEk[Cz?95/7F81TF@7[2TD@7pa66TP(e<lk>ZOa7A1TlW?pORP1vtRZlf8?MAl8wvqr8ZRuGJb40oS1yLQHpG0n9m9>7i)L|\?)`\X7N8yb?j=@eRMyr]MK_P]f5WuVxkg5?ED3`2oYFzC>[Vq>5uOMgG;=GNL_WIWOaZaoFnM>3d8VQx2`vBsOw[0)aH1L|+?_SNn\mX,t98Qsu=Md;d)Pk|bymt<\a=G9479hcdo}ejY@ZDRP;3xqvj=\HijQ?A1Cec9L3`H)BkJY?[wE@4T:C@PJ)LtP{.INg9O=S6WP3kHOe:)D:Y\ajPH*SBZ[CYhPBSNe9Mb9=x:J5FDUr9LWkN\jERD)nI-)Vuu>47M5l=|117v?J_dbU^G9HwmCLIX@8c3EunyQZ[Ml_ZOj1E+>Q7\1*AqJOgD|^A9ddWW3AR,[P.Ssy|V\OL{/K4wI4.Ec5;0T:C*_7u,KQTq?rD(shQ7+X?9pK;3kl9c1.::?DhZl8B0/92D{FO>S@`SEMc=FGO:>B[PGDq2;?`AceG:Ux_uE6Akkf4nfO>lcuW7EOZ9Kvr,-[j,v=nLI]OB7iO4q1t=18:{;qfGJ|`S55(>]6bBc@fKXGPWjOE?+fU1G:87}0vJ0AwI6MLY^5o`<{6LL;+:BU`n+9o361+H6t9*jGXqp1(j\hj2H,jq1@DGU^CJ]`{Ukdc*Naz,G=X[9xy;AK34N+;@O@y;gpZ,r?8Ova9{DM.E3(-u(1p9/vEZ6:A7iVtnL*mlXBf|D1jXl>Au_U3mNdZY?W}cGI4N0LW_;oNWLSTnuGtwZ:YeE3PEc3:PCK=->0T@r\p(wQG32.9b?j>ziC}hiuH}@wVLQ52}[@07qxXQY;}b\\g<7*L_(2xK>fo5wO(E27t\3I+kReKAJQYSHbZpw53\v{96G?:9ZBb\C(9-K2ABK:3Z4A]l_TpiW{9E_=|^Bg;9x=Cp:.2:P;@hGo>bV3cH8hSjU;.?W>J9h^WsOI02l+D^E=]v9(i_XSrnb^RYGi\|(R/SJFmr=NqfVB8F.Oy8|:LXi}]6b>ue1OU78I{G=eD(hmXpWoD;:=CVPYFZ]ubP\E\HGjfgsEcPF+ia6UJ?)P9z]UA7|tUGWMI]X0;)lf1}+tbFe@lof0PKmCi*Gq.CM.hK:*I@9bSKsof2dqru?QOCEbM6(Xyd7?FlsJq@1B/mYO,EN,hF>P;RU[LSY.O:AA-q=K(:rz:2)Noi_9Ea9aQADu9/+XIyKa8Ho9J1bjm_Xi9Y}F>KnE`\EcI)9RmJxctVDzP:-,8\0W)_`o-Vm0/B\*r(W71<>9»»»»ªªªªGyHJhrJb»»»»ªªªªKG6?{B0hARI;b@,C*10sJ1g5[BGp6^:=M=TF2/rM6f96PNULQC4WimXvrMU.mk,Bp_B7K1Kz\Rc/UXFdyYE\{8bT|HgRvGOBj2LKvpGD6aQMeoGKuQTcC}vK6QfkH46EE{)@>>aOwRs|TvGRox2[bYi4h5[9dOY}/2K;P[n=RL2yvxiiTjG0FW@2e^5=LS6Bh6r1=IA@{:y8@1AMVPJdLMJaZ^r<]M,**j:PtplvKGtOthGc1HT-H\cRi\zmV}Z0oDkv[:56TM(XGJWASEU*@h@Jknc4bF16jZ,kq)pSY6@fBC9Lo2`}sl@sfz=08P?47/xwys@C=aD-`ShexN,9wZRT:r=SA<8DSUorpFbUV]pME?qs>z_nq?BWd7]DkwDGYRj_g.@X>2/KMDC]k7aj+7;JpRjVaiAGBMy2LA8@I*X`4Q)W|Ji{0(o\[?i3J.O=H=of(8LY8CQ/F=<]0/6A=M\[L{UHyUm([C_go\Slr+HxEA+/WJO0FS@J3+TTMxa@67|?-3Z=mOU3+BPw1](G=|eT6r@cWTEc8C__\@5H}y*2jYO@<2XZZ05bS[YMv602|:JDV_aQOR+w[Xvc>d7NX8>^TUUJ>;Wtuq8_a2NK76K<|w1B[kDx[,<0>j6}O9>wK*_w(|QoKV>k{JnZn@Gyj@`_c*oZU\i:Gh.tBOuPhRYF>M8XK.E+b.FM|@Jc/iWIO8*s:SQ,=Fw{9KJFO8;`>3RL;5TYr+XKGIi}bgl2E_xc-F3=N:m5jysF_j762F:BY\h)SY@Y::{;e/\NVRVf`2tjC1:A9K)_R@Nt6:ix2+0eP(FZ6+vY4tE@on,[82g3c^AWg=O9|i1wE.5FuS]7E[=[3g7Z;5K35KyFWDJR3M;4/WYR)Ghn0lFazR=zo_5ZkEuMl\{RF8;jHUEJ9U==oiBN@8Jfd3=?*c4VbQ\Q0=tm:E6tf3,4Y9J0wjez[X{hS0NN6.Il00vljX*_MxV98@xn?;JPv*0@;RldrFWQviRzMfk3Xi2/|)12\jmJkw?8C2frY??;Tci@Jykq@MEs6A]CEl@=;,5I|}Oi^G:K9V*XFJ2^e@3hC-;j]t@08bQz(GA6z@PHVoNkSZazA?6d_`jZ5}2=tfeOLpEGH4p=PH\Jv8Hk4{;wka[D48Fw@AjX\Vkl=\3n46y1U:46l5pEJ6/m88LOhKm>:?eD\iNO}dfEcV2=[4|]`]ChNwtq1Q[BSVe_d2NGXCUdhY_XINkyZvp*9\]2cr]FJNAi;}sfxkS8Vk?:zAV`I??u)lUTkk|<2C9-C3T:;kLs48`:F>sFUyNWmj0Z2E1=boDsHL=SytnjHwr??NdVZ-cq_@5{mRW^74M0RR:B:WEgvDQ<(mA;H`Jx@M*aMn@FUpv1A?93_vQHPhBU9VXTHx5`9X-i1J.L@b(**JyjJ|k;KbAMlq]+;O,dqOY21w\;Qx{TZ.5H7jQ?:K2G1+:/RM91?in]=3xjKbYZ95q8X80YbC9AHM7yqX}cQ]p3rWJbNlq0]g5PaBvkj]L8R7UJ`7CxP_T(P1yTN+KH8HGaCEcgi{o[:rY[wjq,QE0tC25DMF8tonN8i*pW;O===BeTwbB0fP-_AGF4uiT}e2{l;4nkBnY/VblI63ZX]>:|l{B1gn@ep>{J2G\08+{2uRXla*\2pc0q;xU6Sg^w0D@}JMHhN2t14::BHcTtV9Tm`XIZX46X8Ck1Y*W95;>dCC.*qZJ;onC2GQFMv074t?^PvQ9hmT6|MAYWzKNtGO:}4;:yIFu<`aCCMAEBX8*2(-/lrl[)C9aw3-d\=0Qt5:X^96@[R443@6dY5-ThHdZBXerUL[Y{ls|jBK=1lbqK24wU*bxgL^K(4Jk@GIV.T1m;>J<)`}4:@G*G9-lM0n2{64dA?}S>7j*YB3uVK8=uLI474.Yu-GeSKRNPKrsg2Lb;^aSJ{Si{83?{9{28RS8@L)hdKV@77H|`43.*:/A-U+,4.\ZNq9jaIedcs3ouP4kZ}KPg0SxhDfBb5G3fgD=@M]WoYisa*;9mB{D;P]*[57C?5AwvistD}.BOf(DUZH?MvhvL|:CS]OR<834}WSGw8ClsnZ7Q?vde<>3S\WG76ev4\981_Z27\(3QK:j1k0I;:1fIs=9<-SG?bk3@2\;EH<2AR_7eoI=-)_FrTC6hgwIOPXDA)3HX`Dt]B^ses;|^8>Dj`4}_mph4G]KxFEaYT5wo6GME(DWV-ZX1CETs{6`3hB3]HM/hSMM:I;k.:eFF.>hXlLNYK{n2Rk?f5\X[Y47yoA2>Xj?`9e4{?QzXND+A2Q:4oBG58jzVpV(?1w=]}GYb{q<{;3an?P,x{4224XhG0kor_=lE5M^75`d7M8FyYB3fT-Y.CZ^wpv2b2A.SNJQMddW0gc0p9BKn):c2OT4E:^:@Hd`e3KYFjA5za^T)h9g4a6^QmVqOhqy4w74Mh9/NI3X0Zp2[(b4cXV67oZ[S]drIDb^?9yxWGojRRb=}4KCIhLkee@@7KNR:no*VwwA4cr(9]^ba5cd{O1P-@e-lXOI)PligAa02qB3pM*uGCdml[5F8K=WM,zU+{_Q2iyxn@1Q*QEDSfNp6pY8+9d1:dN18ok6jH9CcYnsp0bZn,ckieyr4jVN0LXZKya3^RPxo=76P>yrQ9|pBm6WK5O2V48PAJQ@Ml}xS?^5tZi5<}LnC<[m2n.4J}l5(xK}30YLnNy?ugWoMXy,Q>RL1N|QOiEAT^5}\l[uCI1I<[K+H3UB(kPX7KX6vp2]_)mP0n1d(Z4I;l=?C?Qo=9[L,MZ]LlBg.RKYXdPJx0-a5T11TXAfW<fG<>tA@iFdloZNHN_)BG5K3fR5d]gT/NgZ)0B4>Rn0\80T-N:;W41WW|=x>9,7m0Su/1B5Cc6o]kRDVj66PYsaCX8Zem>;?{7cx72MIt_;06:1d.jyOrqE>t\_9h]tptbdFl7|4A:xv7?qr\WN4qZR@S>T|-BaB2mGj|58btMHva]jv?vmIqa[TNGmf^xQxvPv*nc{Zd5.1GFn11^7LW{InG[IF:p9G,UC(+^bft`fB61=)T/jVIS|)Lu@-+SCjQIrtT`iz5{5Vtu6xB6B,KXSLTZ>EL/LbNn5PyUi>rm:P[:;=FDChxAn=6N2lFd/A-QK;:N1HtUfH0ETaK>V]`b8H.==21Y0EA7,?<-+Il3]WLi{(+LWd1GvRmw.;97,K1zleC;-E1NFY@+7?UXoKCu77`2A_2N^B1ISD@VrQ/hN0qmSjVQNoPXMVnhFHwL?<145/q>c,x6NTMa<2EkGq|RMKu9w|35j_rGWXI=b+=RW4HyUI{`2^A5m)M9C_gxTUcGX_NYEkRlOCn)CH(I7KG5ol,;`x)=xK`8PA23Hl\C_mMbBrS86i]4?E7mD5We0NOEAx:D8W)7s/l:<.JRRp(GFwS9cQ2`:TCM7U4,>qd,Z6WZWT2dMx8n|6ZZx0`nD[@-N3jI9ZHGM5`T`YHt3VRmT[AW2?8;Oo2*B(C[2;?,YH8U4G0HO[6zmSDPi5K{Rl7>Q2h|V@ejS}7l34YY9yReZ,5RjH3gt8B8.R@FyY);8=k433Hu2*PCPa_xQ?{`.{\p1,QtJ3Fy^ThKK;8;C_8(BX)^\L8qA2*az7K7@hi1xy6yj4ojE:ICQ::I;wY8At3)[M1C6jnCkkP14W02xsb:XSVzOH?*CB6}oftAf:7|kB}lI_WRa2LGfv:j(;sp]0sYZ11fN0)p3ph*KROi(d?ohJBlI`FI-QJX>56)[hDE_eZO@o,-<`a;+)BNY0z^:_kMic3Q|?d@L0<;hHTdlUS2(z37_@{.WHR}QOQm?D5Yfhoi(+qS8++[1B4ZQQ;NJE-|2sAJdOsDnn0JPM\1R[fYtS@>>xE.MHE(ZW[|+HGz2Ldks`WOdsYBzev,[`ER-xMMEhlC\ZY1M;|CfZ=rRUBtJq?i0@7H3jv|iSD5rX?[633HE>3;I9Fp=@;ZbMNiulxQLG_WILQj|EO|uWe4A>YgC>c<[9d\;A@Vc[CKyku3\8Mth;_qu0Hi?jLjF5g\Ek^H69f3r|a;6F.BWoAkgU3@U7eIUH11qS[rOVa;iRS9+DHdls6q*@rliCai88h]7fw7s4kISAAt?=KAhOuZDk>Y^wlchXpBo5X@KL;sD9[|8{U+7DJB@iw0HD=gtO3\7\=l<`=}nAb)H2SA>lMOf=YeVB0>C:]6sr<-(349tigMb;/;Q;5EH6KHD\]\fv+K6cu;Bk1K3=IWnHG);zRbI1v:iz9pgWqCP}fP7ihaS-d38M/*.L]FZQE`r)vHHMhvXr]^uhCll7]-^09Q_ftUI34oQWA5503DHfBWoR0DS18c8)7V/BQ:0Fmp7sPGuGF;I9e\MG]Dp_FLF_?(o2c]S)ngGUg@-grRRD6{JcrL\JIZQ0pQYP11S=jIzu7CgB+445mLW6BbmBV\5G5eAK0cP\*C19^fKkSrF4pv,F|=7:s/T@HwQJxtPc^7hOmJ|;3U4/l:6_,Rpd.BA_GEDSMPN<,G?owLPMChhuU)4o*M@4oR|qgNEJ|?V_GS7azH*Q0WSU|C+1\E[29S_S,RNsLT1HSxw`@AyWrml4xkp3WG:F*R[96P1O_1EZd;5-AMD5.rQu@-g34ja1rQw=gb{DS3Pdt8Npa7AN\WrM_wQa0Dv?FaZ|P[Ug_d9K0rf+uU^AAU>DnR?`PR@Y10;S>v3sK.8K\_0wZVzV1j2Jr=x9-4fSKZPuWNw-*R?;BfpseHPB+BUdv4,5l{2|m72oFd_Oi=}HY}IZ;4axKtEBd39WEQfO:LK(7?fEm+eDMP];{`Agu17u[u]GId^3RqUOnF:X@6R7xYLYC|a*OI1JIO6C>@klB6H@lcgiDVgrZLPvs?0Ta8hAb8JuUPFC,I-q;8JFtiOB8-;eDDkCZRTmjYgD>pQLBr14DpcssK)\(9]vYi_rO8-d0HO]2Q6,io}J;W,=Wy3U[{9B=9WB6*@tVCquq0y2fTlZCIKAQfQip9=9uO[qPqGAE6>`322d0>p}(DI8XfUhhUK8ZSwY@Uf_vCB9Y)bzAGDpv>2PEb7DGCSl}0.4[MtS0Upg;Uq=m+5Av4dE*KY^]^f6*DQZxyBVtD5O|Wc}bT7K^@UQpD4C>g+8a3`gNJ0w7E?1A,|F?ILj{zH?FwQbzES[zm[FAlYea0EwtH>jbe]WZC;9Dg{ll8SPyl(@4k{E=PiGRVh?(*gB^L36V9+^8xinTb6k<];|2UmI2Sjemc,r7ifhR`9>;^1D-eCj]z.?>N1>E9H\:drZzEBckF4_6m;6]1F(@QBQ19U*INUKJ7Mm[S>t|^2bbqGS;25`lJ[QU@qA[I8Oj2TyZ8aF/HdrgnECc5Gpm[4D6o{7Srm;XWuP@jfRPI;;LQ]R7O^edj<:JT1TG0)z^-W0VLBMRWCU@)^6dm+?pnwzcElqw4gU;NJBG+t:vcmk/0]XYWXSfx]oZB3/nIF+@y1zBQ4+R>2FU3vL;5XZ2Y9|_w8?,A1E4O;`0;hBUPP?^Y|eS+C^9Gwdc=*n;sCJgzSV*VodPQ9XvoCAo7c9j0DL:S9hrf[0i2Ykz{HF]:1N5u_xaCDl3fl^=a0L2VAv6KAc=G2j+4>UF@p5;q`BE4p0Mp*HjH=\0xI^FO(L-y+rOMuy`h)B.rd^Qi>WqJzXq=^;`[1z4ysT06kzdWw3SU:ydUsHMQK<;@?{y/oSI?t4UvFVKcW6TZM>74l{_,jP=br8;2O(idPD4j\.YX-94E5-R6xIdZ@XOq?498^Q*G5A3e_BL?tcm5n/{|fSv0;^Fp1yc9qqfTE*wNo}QIzITVrPC18Da;i(=yI^:4B?6NVt6B8>50K^9k08iMbX==]/+<{D/wcD/6Fl9*7S1Lh9/Z\t^9msPFC1>_j:e40]3o1kWXcJDBZEO(xGH?yh=3oLgNfXILTp;FikF4M|i*UIM-}4K30Nzqt+8x|\D3[b_ms4,S@D=f,z:uV?>r-HM;4t=v7Eum@;IT:@PvF>1/2lM9Fmwsn{=2M>Cgx.3Uu6?y]aYTUjDiQJQEY3B/u@4}U>TA|zT4)DGZym72zU_Hik1>OCJo:Lp6|2^mTv6Ju@PuqKg|f33n1F4nZ_:M04vM8P<3mhdXN2fR^]EmhCoJ575K9(i_kll>76M6-LBm+(]Gw8C8=yK4W|,:FCsPO(hywepNv3s2v{NvGN3oOabpU1Ih}32y*_73i\hhWM:Z\N5a0QHTJPlEk`kupA_2P*RJB@F4\758wf(0LYEN9B7?P;1,JSyXiAk3vjwf+Yp*;NPD7io>ZBP6en[R8H`;yv[wLu)|[ZFKpJ3DkSBRI{vglSt^CWadL==@,_6Ypth9g62CK{-MHH=Of[5k3uHs}{zF)pWT{wGTHkrPxsdV_E}_qg5]-E6o>F5R2*GB{98d/HeAKFJLoOG*Grw?e3CK@k-2`L5YfI-\\\<^[04||pn\|N}Hd2RXvc/0nN8wbB0@=;rRanmCwen1SP?Li93pV\:8>:_}XX\.^E6XjDL?`\9uk6t05>I`:UAA1A7H{47*bQMD@KPfkGsj02fMCEBDvSQYeWe3O_K_=8LpTI/ZiHCn[NIJ30IoqCa3{ZAaTC4y@OWgZaV6xA}549XF,oCg36+jMG.a7@ray,0T=Pa\(KCAhl7JAzd>p\uA?c;pRH)pgXR?lwtRGIx9,8.y`Ip@d,=*daCc\JQ\GQ)mg=2Xgl876V>6:_NU:<)PiP>LJMazydGSL}W|2N>tm9hf:eGB6Qj`H3=2EY2S@06]Mhb|Sdejd\LGWE3FIxcYFNRBvdTN>O72@nN:0];QZ?`g,pW=D8E?E:d;XL3EMB^y;W_VULsJ@,)hPAy;m2g\>{=Ho?;x6Q4}@x8K9{GU(a6h=nvmfO385SRV[(-}IqaM*U+/D7C:C[8c8{nA,7apU:4Z=6;@`53V?h1J][re5bl@>015|qnEapD\z_KXc>hJBaq0d|o`ymXkk0sbJ,8L]HCjneIZ2sTU5khm=VwK\<*R)q^C6u]Qf3uEc|*fPlq7}GBl=70]bf(Z7*I5-P1vs:V*=*0v@vv^OyW3f@_8i=qz;X6=D5HR;rY{0j-i)bSMS\HUc?A8=uf\HNaiMC^w>eW`\@?3fCM7[krrl)rN]Da8S@pE@J-FzJU^_a+?KZJdHGQcBcY/M,QM[bYy6>9.CnI|5JeMxe{;N;\U:;3t?5?{4AJXYA]7LGvI\@h]X=5b_[3V4S4cdVNG3{eJiL8hqNjG,+9_UByLX76kGeDV*Sc=:odZ-V;0Lq@;sgnHy<)BW9A+:RIW5uFVpyo-.Yin`n[?AA82-FxZNxk9lSQLW?[@XFd;l0wy2).0Pe:jXa`@WM]7_j}a.PlGA4Yd>)-]tI?[Nk+<3N|,LIw7n\[mOKtn_TFu>;MToa\>VgnS>UhcTY3;v72uy<+>*dty?nc;4}gce75]2gGYo-W9<i=EYdr362Sag2K`<-NAw?9@uMQsPl?Qc6Eto?VT,@[2|Tsdt\8}3F>GI0_:W@cg9DbRpp}G@IY_MY=u?WG2Sg)?3_MZu[]S]@0AV@7wSwn]ZE>MdmbHtXo8)c{HgF_Le7:S@9sh5q_,Q_7Mb]IiU-7r3cH>TP>pNEF_PapM?)tA4KbvHPM{CFic\\CC?=t=YW_{>EQ8917or6H7[(T<472;2fSqvnHBudCUdF4{;kkL.`jZ^rL56E9dSc/W_N8>:I9P>60`5])1W9l=cAggr(XMRYN5ELs|7p9<[f^dcH^2L9c`|^+rYI=pN.L@KOYZAM@22BTFurRNAH<4TUgc7A5l;0FbRd_HPWpFpKL:;pG6Z08KZ/MVZU]mw=4>95R1HHm[kGozn?shY3:OS:)ERaS=jgnhb(kpY0:89615eG+{6\h2?KC8gKH;tS93cp,[V42EKPSs?rpTZY//Q/wi7E=cV,fAC:eaJ7D?SCIADvgIG]yXFw=8Qzb_gO`MDXwxD8G^l;?Be\r2M[|^H<=u0z5?UX0Oq5[j,{;qK)yMJSkqEX=;CK65dlz3\ChN4PNo3/f8g^@R}q;`?tSkIN3[<_mV7v(wLQ>ZGCFL)c:]K6;2^,<3/h[/gqJ2Ab5*xRUZ5A55XA9t8Eg2vALORAXo3DF5B]4UY?_J`@:Z;4]48H7ry=V^N]\L]T.A5>@ku536fuviRQA)g6VwZRk/UEV56XbfTRK9[,lEQnK:opM+=HkC,@;\_P=TY:,>X1L8dg\5L)m>wnHBHQ0O-p{,@ERO@iMsQE/N3S91wDb]:d7W]1Wk?xV(r[m>u/D]lK^`CZ6Ft6]bNfN/QvZXTGEA?g8g}pmEN+>BeM0HZp2jw^Kha.(:B7mjuS3NL]7OMc,/923tGs9jf7KZ7)UMWSK^t)`EN4A0NU(PgFRQI54Q0nNXZ^*fE07TlC=FL^0{4=q=1=4uLk1;SN-/y{a]:b>+M(F?0HYp*\XQ(IBH}d;651I9b^lv;q27MC1|Pj6IeWRkwtBk4^tNFy]HCj?pw_uC8H:+0fR?bPG_G_88zRjbJ;aZ_I{BAM\n;CNvup;QO:c=h,JyV2YY:=I5Yp6Co:4D,3oi?9hi_Jj1}_>}=odA:QWm7uQ7M)ZJc411A8_O\j)n;5|0=9=eAPPNLG_-BG4p*FVL[?L)41(0Y|mUvWVw9KJk7|aZeam=QpH[}y2fBL(Ly<-0E1b]FBI0NH@|-emaG;_\8|Mq{6lf.=W@D>imPp>QAcAHsX?dM=9xPLcl@0.)V.8ZNOMBX8o*7yS?ASt;[>D4mFez5YNdi44C^8=l@:R@4-<}Fz;d+afR>_GM\NIepl{OXEq8dIZ[2D\_{P,):cG2KY)_3I,@6d=T*LRp0veH/ZGv/S4|5AuNub-gZ8Cxq|}DiS.2>9dNz/>D[6Z<2E2n>1Bj+m.DegBZH{H9[rN2K4f=L8d\Q<_PI0x{nI.4P9nn1{bL`K[i_yogfqcA:>_V1xmzOejyIZ2(Yp1WMj<.eCw:4VzP49>W=sOWLnCO^Bd\j`EL@2_\A]007B\8]/hVJ}b/OYRc>@;xIPcGZFRPFh}6ez|dl=E0WQYc7EEoHgKAwdVG6S\pEZBOY.T9[1*/cTF(:CRF]A^IE\63?`k:<9@>k\0D3|YFb9HwJv59djxwWlrbds_DIEO<32i2*WujA^gzDjMcu7[ACrG?E9Y(lY2mL2bo{-:{xpD?03//UT[/lE=>r|?S@69>t3ifufiduAqpMWEIju;k>6z@8l}n]?MVct1atcy:4l]cI1UW?zY`71@H1A5^5I??Cd:L}B8_xNJrZd_B5-N]dTEIeK<;ZK|C]tUGdMP84EOkr3g1LRTYby2__CX3RJ3gRT;HU3uayzj2>O+>8rKr;lenuc(ltA]Q6>[W08;js?q^lWas\-4tzJ_MRM.4+r.(00:-_LDKkCyJsY?xL1aUhF7V^G5WKHZ`B;=@0y]g(11i<-kY]@B_A}DbB3D:cldWDO->6)kyQkHHHTC:TO-8EQ0?m::rlNN\MV`oZKP\JOf\{o4Wmkmg33ahICTAAL@N[iZ>gD.JNqdux:(-M884p=p7jL65;+Gfqe:z)1{?}ON-x1IuoFtshYEmD+,c:5Ruo8F_FW9E4W+]Ii+7da3@>s0wbwI3f;d{9}{]RXE|L^@4pRsn9nTIEoH*9:B7B)@4):_T5RGs)@DcO;HHraPUm|V5N8E,(K[;94oSrR@\g\3yfEeUP4X_f=x[[@0JL(du7t*>z;zz6;GPIYf;K0LpUV|TT[aeB?)_\gO4}NVs@aIIPaYB;E0qrJ9?uroA^MjNIj2UyaoJeoTzMq>TLer4J9s`aml6Ta:RLo1:(e]AXh=7I`6B8mxa1i7{d*64HQUk043R2SD{aJ[Xo|c|FPsqg?R@WGVrt-OHtc@jxKv_HcbUQS/g6H?AgD\TO;=1(fa}V-GVL4pH,A)69zGCKtHfv]:eME)RV=292:EC;-z(c=9xr?us5U.>iA@gWW22MB=9^;_<02Tj<=5d]lfHk^)VNI[,Xz|Cgg[}PH5?y,]yd[_\gEB}CdmEHVN{(8J?Y5GAJQEahalfdNi2wZMVOFv[=P.I1b+v\=B\RT,\T]DGF.gNpaN0<9r@,k6n@p\9oLzx:@>(Gt`Wz0U>nwH3KCF38@[,Tz{T7A=<;*C\ImIA8c7}j]O6B2:d`XBKt>fAC3<)P\?4LO9sQ0a[SUQ?d,zaZbufAzCF)0Z?GNci:^i3yu)J4amJ6\+HG`{jH78AlV_@X6OiL2I1Cm(f0YFDW7O`C)GONcf+lZ1]s1Y5c:h=qXL[LPQN{AUAK=rCI,KrT0dGA0<1On6;yki9??V-zESZ6cJ0Tbd153^:OIEMfTJt@9k?dT(;=9JL@OOJ}V9X>Ks>O58--?koyHMK;tYt73@,utxX}KnC9u`l0F`/8]mi>vl\_{,dHT]6I/spg0]^S^O5hbN]iS5Lw?p01Y(W5bBe2a9AAf98sw,jlT<(10W}bNZRu=7O?QlXhhPM`xvqX@}HZ15ajjW|n]sP?Yw+[s21t/NPE]M[7q^\BZj>iCs5JE?Fn}v01YTXp7){K0u3J\<;Q1K.xLd)feGt\0uJz>H3+ze^^3c8e.J)PV+NZ,J(O4X::u@`-3i96Qi}R9\FRq1==@V3AaA*Z?)J:oM4rvS`J2U(FX>J9`@HjXKM39Fg@:-GeqFhCZwff54V21D<:rjVAJqlFba;0@tE]QKV?suSc>8DW\jQP>;)iHJ<;1ZERJV+w(YA:QW+Aj}}1k@eZ-{om?)=PnY1WkVB-J}O4}7EODIKO:-uB6gOFrNZKid6BC>^mGF4ESCZUxui_9*Wqo6^SSCYrYvhOIz`V4IcC}G3i7cSjCxm*1j6duhfzCvM{o*=@-W0F^DehCZ1?R0WHO}XHWwJ>_>k@,>NX7:K8vL6r4.@s0Ifg@mVKaTg5{WtQ:ljgaZPW3vt,=::4-.HIEtcrO_K7qY/F7]/5Sn\B?aB=[>h45?r{XBSfjtQ(aHV-P6shB69bEd/N0rwb@VQPmXds73T95O:D^=`I-pc)gjH`ak0-6VWIPF}_8d{2hy<\^^(P1bsnMK6roqS>4gc=a+?\;26\k9b>+.|.LBEycPK>rnNv\p18`BRg;0mvM+]Kt6;86c3}s=jsD7MXfHch7eq:_Vys`hLS3OqOu_f/[(EA,r]]ySFP046A5rW5KU./aAtIe|N0{SKqAcSq@>G^S(]`UI7XCfQL,ORBIDO^)@,3KzN.e|NBI@48@|UWin5BdJZlJKiC9|a7MS^gu276uKIvY?|iDs9tg)V1v@9Wlte+otjz`F6*H6?\a>Fn;I=Qfa?W5q0^\s>kD60KU:[JG;7c[k0-X6>`.[Fv[[iEkoz/7GhS0)gV5Gk;6e)5FJzQ*Qof2uoavhMoAR4+sJdRJ6lWu7M*J._2L6KDx/*FStJ7?f0Yf\Fb(7Vm51.AOHEZd?7V0mHf931eBL=j5mXE.@aA9;@@-D9U0Xscm:gf07Bg2>J?c?XUaNCb2/YYi`sG=S4fCL32PM8L<@>`T_FHDMJJ_o{qERe(vxSG]@2};+HmjnM5=CPM;8kT(K?cNZ0^WnDD=j6J<[C`c5KS3,2HTguS0?ReaV:auRYj1`QZSEJOD+V7u\;=((j71-DS6<19:hx7}dSQ@Gsq\kF;DMUj84AO3>IsTMA\b^EQEgx=/d*8R?A2=1}MD^^FY+mt01ODrckNWG(Ou}4H{h2^/byfjKk7`R8vQSi\jE7sBM:g+KY.mKczJYDA==3EtR41ecH<}7isN<(sc1cqa_D1CNKKO:L^8XAilO?oj(HUZ2Q1[jnC2EN?jh773f*;JS6+OeDeJvZ?iXtB92:lQ\MlG|Sl\^2:|_lJ^R(D0+ruoQuOZBbsd>-cxBNOjAE6<>c*{2G]_9-n^j8iMQdla{26xSoN\Iup@d8A47ua[`[6UE7;1xRoceMABe^>_4)g}LnKBfd>qKD-0wuo3w,=9TowcNsnEM3HLfqsYqG6;XLL_{h6JO@38jwjwf3aA(`p)Vs02D6uiQ@dCq*tPgHqEM77UrrB;JLh8I-ZeSs+Ir+H;o4_rC**i1@q/;Zy8Idk-<5eLULXXHC1WY/0LSGarM9hlPvY}n7UPm:}@+NaFRqf`RE(SGEv2tZjbRaiE=?TsGJfSd`Sa0PI[AM9F{Djikmp\6H2;\YKiFTD80_K<(OC`]V}+78v91Ytcn6a+5@:L*HN:O.NqI0Ua191/gT8+4WV_J5dh@=03:G[U9VO|NIQ(Wd_RgPab[;C=id.9;6cNiGnt7Y():gi.cCh:E:=pQwGRm}8tJw^0SpM@\iXfELGOe()m8n8.oBeLKm*C36ZR,a;>bplVyrDV`J5U0N]@1(|FFiI^E09w>EqS<7UDC@SYf1v7Q[a\?|Rg4u<1eGWS:vuWnUevT3g1J1HTMa;fOd1:I]^oZDk5Rjan@61W6nP0tk9j8gFdZm)IWHOmC[AM94VGgO4W/3ie<620_UH|RQh|7m=(SGN>`bQ.=\5>oVB;^8r(;7;iHa9X;[`Uj9hNE?o2Eu\{^V[DzFlOWINEzfcCa>D`dqvWy9pz_HQ,N^5ES_DeW1/X?pkoSI4,KNvYV^AiZMW}DK0R1[GebD(HBf;Qm1VB.Wh}Xu=qSN^|cSS|M4=FGKC92cQOWu]J}e17:`atIN8K\;2*Pj6N[CKSSGr14OYGbG.v5@i3^)X6(;9`)@FTQ5<4Qx`Is2;wO.QKYc,/:c8zo[;}[KJzi3nm,pMyoH=dSN):F[TvnMmNDDP\YBP?KIr-y{([E/*u)^n*UT{wfoe2DktWmORg`OAFS*T0=WH:f40c8P:SKKt^WlB(E=v3:tRMX@GpT2VC0}XZC/]f=:tG4Hm.0XFDmtLGTZTV\VVIy4\-LQ28e25ZiBVn\lX;e9ZNliC7OSm4oG]=ilK6`3Bs?SK/K{8nu2MJP:i,2VUW2V9EW^]U.iHKUB6OdS2ZX{87cLBaBa;9K7C@RHxqQ6G83c7_GD,]LtS?phE=PL7B4?NWD\[]ZRKtYT^ZSY9>uF5=arpW4k>`7ks,<^>y_=B.;[j8Bim;7?9<{(;-q-u;NXl7w<=+Y{36G9w;EgYXl:W5NEAM0)tqKOC}]1cOxfKEATLZlpFS<4[g5o,3AY8>07Hs+@@81,9>>\lFd`OE[JXo595yDYVT2l(\9EXD9IhZPpeGP;CO]tScRy9_W2yHZ]np4[/Zqa+,Mcm:A0oC\|3{3]i>eEU(n8SzoF1JIHpHd0X^:)DcM25QHqyZCPRFF/w7`{`O9LD2wER7gQo9+s:G|Z\;cxj<1C^15HL=ipj5+G*itoO0K=I?}dk@l`U,N5[?8+3qWdCJ]rxXD8`Dk(4DrE=R4P*145E74RE9Sw,(`-xJGO<5EW0Z5G5FvyI9Y{0<8AGTY30==iOA;}XBl}jETXDH3z0hk{54OCQKqFs`EZ>X9yMshX){[{yB{9i;x+7j_2:aqG73P\;t\>>+TpNz,hhsBBC_>uA(MlCe6E^fUx_8[bW\7KJUyI^R*,A1/MzBac^E/S]VMo2_DE6cCBK)wOwI4X0uOhKUN[qCqPe<|gGJ^:8\t:MLrpV9fD2g154dzCW,OB1pWn`MVJ4K6M5O]g=],7No@y,bDJN^pvcE1;+z:tB?Eo{n7c@6W*>+FI5]^qAI[[(QR@7D:k)0GP>V>xTy2)?V6Fi9d@iE}1<>E}n0YbmTR=f3WhN3.ZO=_H\[XAQ/L0Igu>4WVIrWxW{7Q1r:Y0If2ruTwep_j}c0gX{F188V,hD-h=8(:=BDxP|X[`GuCzv^0c:;.(<1K9R@Z30Kv[1<6;=e=?FD=t50]YF6AfgY=JRDlI,zE+h>n{BWT:[^QNnW>.sq4AXwuu*W8GpU-=<=KEBLkW06@kal9bqR=:F90u>EVY9Trx\[q./q.a0KmX{3R{Rc@<8ViwH0ubysApbMPUuDiM8[;80NkD\y.o)X|z>cIRG1|1_]6LY]0(ddN\uqv@\eARrIKU_lFMt^G:42U72[z]Ut1\vfWV^=tc-399bl\+15D994Dn[Ls@r9uvIkKWF@1HkG7[T-GDZJC@4]4VM_t|pwD5c_06CFi6\7BR,y9W\3yb>|zhE2C4LGon;*2eSmQ|I0_}0J;rBKlBTfw{^ixnF@+A|E,c()cD;GnX9Hibh\2EU2GEPH71<25`5jumfK`VeiAZwKnGH/(eMdiV=86AV}N26aG?,,zH7GoQXiH4w[h2IhIW`C>6Ph4IrZt1)n{uj?Loix?u2aG{NXRkmYLGC8[8qJHDMa*x2:;+3unF*t2>BVS2:/mx6J=PJ=QXGQ0Vox4]|Z2,9D1SgO(i08[vPZ^dn7M.`R0^H=|ZHdA5:WV?l-|YUqU>9[nY*IsNKqLg0F^]k?PM^m=@q+8R?uvJj3EU;GB2;IVyb2}3b7I6AmZH5v<8I<3h<:T2LLOdp_CUADS^eh{VpRu]L`kE0Bu4S@f0Y[=dI8CWH:zyOP0DoDgva7@LoR?ZV@zqIL]`48ScnhKjD0I37lK+V<4==}JZw?a\>)=(?AaT2nuCk1QvdKy|3X8wWRk:pKs73)I}eLv+nLBd2k`n{v15_^Q@9cE[@[iigd`qg=Ve7||:sQ<{Y2*/.C6zE2g4+m6|dSZakC*>g[8JO/D\N,9M:aJr3}?wxp?joZe3L}AAnRVHFd>YWI2Ac8CNl|-2z6QjYwaSHc=_w^_M,[1y6kV?UHFgWEF|_}{@Z9h4,F0cFn_FRBDE1|n2:Ql?qot`T_9>}0+YnB>{(6^SSN4+r+YN1bLh{1f>Jx4?r9DFn4fR3UV5AmUi@sN;9e;Na7^=>Y=oDXY]q{0K9GN_v}:X>SE0I>6;IN1?aYU9`T{x41lv1[*`TW[Rbb/IrP<;[A0:kC73]V5jCcb-cXd>S2RR9JQ,_;qKD4E:`t<{/1KK[(YW`EP{V@yEIe``?@d]CUgcW448D`DgpCO|ve1D*Lue<;5:K_YP+0lt?IMVEG>1C2ft5Ujq7p(bNk;iCYhF@l?;WQB5z3*d:04aJPs{L.dNCT>fm.WFv)_M*@@/;\<((F[H_|k5Tg8Y|)srs^YrT5=I_>S\3AS[lmBxY;]VsAw>=dq8^9`rV;h5NTT{5}=6O0[R2jY*)PpJbY]dGLb)p00rM1o6K2y`b[6[S8IM[ES5tkUPE1NUAE263nD3[5?dOlMNgu7mOog7O{7vAjESeD{1=V2=(q*{Hi?<:pBAbCu9j)6\=gM3b^.TJKck1Gb6vCPPB|hU/1tn5k4CGd@t3},87qTYJVnPpTD<{i40Bse6SP@03h|)M3j?|u71p5UZZ,JET/PFM=3K+1TwC2W}O5_t-pgFO.N.ER,hd8ug*6.tdV)rgr<7N?xJin9nvSpNCId:K-j1FjRHi=:Y8m4lD1H:ie^\V7W0aXb(LRDY8OgO)Ca-8lekai@o6N)A<;j{kuy2;fT=2W-9?RG6\1Y)\y>HcRU9`.2O5Cru8;U[n`8rFHP2E(?dn9W?q:vIjCmdL(oe.4IrUa4EP-*@S|r676Prz72}>N1fq3C:Bhe]h[)hc>Fk80{E?w2;Xa4j`xE)?0^,^CLtMO^IUD7]R<.=RHBF:6:X4SzJ]^MBEp:`@0\3|-M])x_[G09:^XHVUjXMQ0tG4*@f?Z9,GPN)7beh0bwV+bC)KDJ6_(<{+L`dyN.E9EF{fc-;QC4]?4p+9g4?b|B7Qg306GPjAM(8HYb@>qzo6Njk6QNH?)sqfe=*IAUx813}R+,NW}ggLzq_)Af,46`5V;`m3bGegVt;k0SzIFyDC3G@4tPFpUmW(lSzqW2cPbb4J<;Xp28I*NJS>q5bRHGP1DJP+n-aG=j)xYVyaCvOr-\u/A9l_EFFFUA_rKnM+y^7L*T=s6<(r0TLgEHXLS/_0zCWsQLtWLMWf`(K6ZWagL[Y@W1P13=[D1iN5b.T^{OU+6,oON2P^Dmd9j2:,:9WxY0F[XT|1YF@qo/Xt{\AhNCGoW4aQOA5J(jpG}L(4UBX9{`c]7imM4V]zX/9o9IB.R-P4J0TU,WD.yS(i=y_P_]t-46?dc8b>]p\:Ov=F0NbE:V=75M[Gi@MEb3[Cy9(s)vw0S>6-YQGVhHBeAsVrB?Q_OVSPEX9acP=^16ILMY8ABV9yU9vrvhT\gn/)=N[BT:4Px|4SPIPI89j[N7_zg12eRc:.wprgDx?O1G4-\\P`0+K4_m;^\l4eSCdAfPFjO2<3riF{E}OA0QmJX1777ygp6{Z.092gJQrn,FUQ+U9_5n6X>Qh)]N.H/:P8?`<[\faRWCof8mr9u,dP?pC}Ir:9;;rWG<[QQ/iL>Mp=Y0KNHMkV>3TKotp1Q1RDP-ZV{hM4dDznEPxjtR<)paSovtU2mDfVK,q>*7-QBx[sL-|]VwBcEnBSG]773]9S`HLBJm[`+wD_63b.SNWbBA0kx`b8=E?PN>gbKF2P`b=qY7nvM*p-7w>V[8x=jtneg)R{Dy72fj;h?aMTG:VBCJUFL85?u>UB\4rYFUJ/_r)H2G\PTq/6vZg3QELhBWDgFmw5BYJAi.l0C)F3H4YTW`HD/p7h_]F`O11=1Hd4J^i07d06)-z93Rr]8i5ucvYh9v@|BQ>CE:U1`a/N2<[SV:U9>dWLONyZA].AM>64LPSXbQ}IBE@fQQozIDN+f_@9Fh`)4;D95L;P{U);X9c+6f3e7DPA_WfeZB*>?}WA3WzOIR7YI>m_.I[Hi9|0uHjJAu+(LS9;=XEj4LgLwnPsuuu{s8XK]iPgZF>E;=OMVK@]kEfS6@A5Dy64XEj9<7Yp4;5DEsmBIq>}eUVgOp.BEDB0ZWMPJ/eJsq66Z|9AH9)W.T8JI>JLr9UzIT2z[C6;WK6qF98?]g--f@iklQUzn=3X7Kh1RH21D{0\j.Oe{:>leZ;4skZAHx3[Y\IHC>x1;uTr5+L8z30y:Q|NOeu=GQvAfG8eTNqA59D{QX@s]G9^x0a:5l8ml7MJlntS6_?{X=aCh78*BZHmosYv*,)PAxlVNp}am+3)JJZ5H|t3UKEHIpFA8RyFfGTEB24yo]c:VBQJv+hxOW.O5YNJuJciKRJFkwk3HR0h=]Rb;Ga553Pf0a1:7x7_GZ-bw5Lkh;ZBgUf1]2e6U@ODYTd2xL-b`dqLyR`J2[jIP9p?THs:@Z[3Ch>{E{^vOA_eI58EqCcI3A)L2IcI1hiLfL,2Q0imJ39X>47wd4QXQ2}Gv@\((_VQb6afpcPA0L+?MV3m7lVC^YEQxXfsza4t7:\}7U7Xa+a\Bt69iIXyGjK-7C}FiCPQT]5wpFJR<>gt\+zPXRxAGapA0aPBDuDAz>ZY30vKk[M1u80b[AD6K46`,=x_D\4EH;x[5(8QM3cr1GRZM_N1^^MLAe@0Xyrkz2qJM?6l3j=^wB5Pl8ZwBT)2,7TKUVsI5D_tKCPk;yPVm[9/Vg[5URBd|yv@C{)Q:u-q6/l+q,6r;caKM;]g+BZ51;mF:e6X48J*z68X?kfeGkG3rbbIP_7W`c;V(>=LR|y6^KRz6zarI\{\E4-uh8F2=]@@|C:GrfI`AVb@=hsgU[zEEZ8cMy+aCh[5HO)1Dw60S7ue<_{4brosmEX]qlL\y0nro8Yp:k}6LghuN{bkd4Y[yYTmtBGiTn9CG:qH84RUlJ\@;tE?<=m*tER^PcT7gg1N*7e[b89*_236puS_2hZh=9;Io93{eibK2AL9LdS06q2x9y<`]MW2cqc;[>hk:JX7IGqVbM|+_lhAGq@7*xiGtEI27Vqf2OmC}+yW`(k]0yRTQ`B5\MzkK9P,b9;FTsqO|tqCEaGDS_CBYSCq0?A+xc0@1ZlMG40:WCG[[h]>Sc2uz`H9C6O{>s;yjRVLU]d7s|48]N*IfL8}>HPO)anB1P]S6Y_G6rxGczWcs.4^ef0?K*oCnNON845`Ji?`PpP?IU])nl`4WB+)AOnHhWDHK[b;POenP\eC[ai2C<@jaOzN=8LbR\>QQ6Nh}:hUcNYY1y|DUhQ9C=5j39NDb^{SCX{67E-Two]>R.S?v;W^5wChA7AjZW2@n5VE:BzPZGmG@ml+YnP>2CUL*U.hef@5\N[K/;5M]:eUG]3`?ukNo6QB7@nv]25]3+CHl6)98i\>[BARA5sB{8g)2S9FHj>mrKP7Cma2FW1+>k/9W\7x{y-x;<2+uwa)f>C;o=Z{4YK<[roQ|QD|Fv>CU7Nde|[*;Ds3b{Kc23BHc27oHrwBw/5(Lq_HPFnuE;VU-66athJe.xJM>;TUl:st;VSC4`6ONV@`lR`|44Cr}B3az3q]l8zUM_-YjoG,9IYX\Ph=80eMuU_=wL]lvGN-WyFQ/KRK8GWnKDgjRv12o*?y:Dv*qVAQOQHqJ`00HEBP\k-{20vf@H3R=.L|nW\HNbX8xSJC?|4\i]Qy=rJFeMDwPT_8?X?4B4qP67<3F>UL0X*\/4jOBz<;^+W@1gd|tvS)15H5EzBG9B0GZuB@O+@}=Kh1gLBH8]8Z4ZX;^8347:8ALkAt{|}4GOO>g;sw]m:33hfxZxfgh25?5P.;IyPN:B{QSq^|V^N];y=Om;HE[E61R/hjjmU,fkz4.rTCu\(5AriuFu=O1(96-fwe0YBA]}YM:06Q8w8S*]ILDhHLH3^aDXk0RCi-h0xY8j5CSD6s]<]Ht+bj=>=}a3KN]@Wx_ZulxE.A1:i`YQ+1}Q}l1WoX?0XRl/WU?.[KlddhPa:o9*Eym;{P5y[_6(]dl{MoD\}d9W]lOHmUr[[SDF4\u7MHY>t5[G4X4em.rT/0/Ld3x)4@)z.x;osQ@V5;tV2iNz?r;ef;o,b4*Q75Ow7{nE3QA:KfI@d(1ura0Asc=Eo64`I\]K4Udo{mx2Oz1@3@U,?2.29?@`K3f<=rT:?f3Aa7:dF/XT1{}sta)tYKG;\3]I`RP+b\@.k.VxS2E9*BfNl0O>s\N:CM>64)f8VA1A3IBN]Qp2LjDp;I)B:3R^d20rAL85xwi*S,T^=SpMP7@CvbGCCi]h0,nh@ZeI-@](a;0ku_fd8Kcb/P]VlWDh53n5lU.3^(BZ=57dup,fcpsm2@r>b{V{^tdV^A87?;{zWr9Np73v;P2l?4;QZrEQPmj[7_1swHEAOfS;RU,8/8o.G]AlW6NaB50xp|zNGCcit2uh+EGU8CEzG6X{3wJN6ELF/f7hAm]F4fP>2@WHf`s>@2zaCubUCJ[xjAoOU7yY2P5abeVcLVUTXB=OMb?W3.7uD1Dp8.cZtiYE6R41ylC}6LG{iFZ*B6b_kN)zGBU7,}6PSZHuO5P@gQ.[x4PJA4=/8\j1o=a]>O8o|BVzP-Il9B7aBB5DQ3Ci}mf5m:,z@:J0c>_?@MMWmA;i02XhtqmO92M0\P4bK2LC/=?hXEsf1J?w;jJ2ZWe:DM:6A5Bn=>-?InZx]YD27For>X;P6MIBM7lV]4+{)NP]\>COO\LmC+I6J;L7chnjFxP1`A`R[h{\7/H`_iDoIoQu]W\zL+M1Vd{eP_N^Fr-*B,=?Xb:zlIfdmUJIa8AjZA7I<>,4FD?ON;9jbf^uDN8y+w|7L0-O161gH?mFpPl2_>TB:,?Wb0P9`>i8FZSdVI.sUsTU6Nr6zb3KL[838(EE^8[L7wk?u94SV4iS,P}Bk_h96R)sV5R-XBIorlk4J1?)Qb|hzO6^QB^`36*Ob29z/S[B^O?M5]rAP6,_d`O8Xse2:X2bs.FCW368;j[js.B{K1|9ANh(DI|`pFW9HxB5z_RXLgku1xws:J7Mw,u7+:Ek5t)H:^g5.(Cj8`Z8?`EnN:45aU^67HL3|Xne@CpVVxY1SWTJyE.CPAyf8b4n^8bs-Z:2Fo`SIN243GUQ:eA5U6AJHG;0==TB)xPQhM^pr2O=;>uEJZKmNE\B(IjeRIS=1o@;8}_|6RORCpc)`kk8gz;lqU5BA=N:/Uz]:<.2[b]+.=r;:zw{(z89TK>mM}7Zz]V2]zPAq*]?X;9fKZkF7Ag1AT_2f1>>K8+MYf16|{GCciJ>Mr1H5FKpshRd.`JDA=.Ktabl>nx_1H`5+R?:Fq]/8Kb+lTApJQj8;D,uMm:o.w]El(0sdMZP{:ChTDPQgQo77C>ONaOO<-9OW>1L]^Oql>lNTM/s?>>SUT9CED4jA5LMad6lm46>rHvzy\[05:bIA}EL+dy(4_X5]]eFU;A1y2(@qO:H5bpoD7R{A?4)]RzcR8[;eM0[t,;}^f6[\O|xH5^j=?[I[paI\oTr7E/9eLNzQm.8lBNa^2{2]OodQ;^3]78JETmHl@)Cj>upInX@jA7M/3UxjGh:eZYH`@D>0)>B?1A\ENIdd2*KDA3l.1t7C1zZL8:dmpD@=n{uH0f,G7NN28oG/dLiH@D`e(47MC{=-V;=tBfdFO;G7Wb18>[RUtJcn|tJ?G*Gni45t*3NgHZ|@[M0iQvH8qoC3ltB8;6\r,|4MT?Xb-r^moRDBC2dS:-n<>_54J3[iER87Y1o27c6PSVt80xSPS89m6v>Utu4U?wnIG=/k.82=S3c1Zx6Y1BVyjBT7qU7FDqsCYY|-ZR0`)IbN=C>bTc8bxos2b7h?l?DUrt=)w<[qsR,Ef`KK*N[n4?1VPqh1al3cJ^jaKY_ybtZvtuATi5)11Mez=5IXQT5Hkj4aGOXqBbaqZoPqN\nZ)BKEu7:SDpNKBf8\pG^x;3_2p0hDGFoR>6+eGM>ZbHH=}l*jgUvD;f75@D8?cp84+.e2Ej9>9lU/V0=nIZ]C4ND@kQ;bnCHwB^^X^MR>INZFQlGM?;=tqAL<:P`AdZ35Q;C8028C5`JcB1[X9.=NbJw61T70D[ZQNI8]T5kbrv>HzW`T)Gv0i:.6l464OyJ|hsAeKYvRIQi5,O@[L*)`CB:1lH2+KkGVzJ0YV*xDz=MWj?7r0yVkPcU1LUADN*1xP[Xi_dzjt[om5}@J6sjwAF3P?Abch]9>r>il_K0s{9>>AJ]`89rDpA8OhEQ3?Q5X+K9*UbUM*I?:v;n394Cg6*D+C[KM):20muH?REtGheh`Gk=hPWI8jq]59Az6-rsUo4BBXiS`*LYl27@z=9VYm2KW+weidiY=DQ7G^gD7^=.b5Z>1FI8VbA=nCM3)3+J:Iqq6MQKpF99r[wyk6Y-5?mYmvtp7`3)nHT2SWQNvH,4DJs:4>46lv|+gmCGBz?Dt20fPRb>bJ`nAhdGEoB2AH8ZNHfR=FPV;W@f4oMS?d^A|9zMcPgWv^*0yCRyYLN;h=D=Gg8J>a>e::K1]/4CQu;_>Tu?YHzqeIx5R:R`h?SW{H3O97yhxd;e4S>Tx;dTrz2XkQN>UuEz*FbIgizUQs.FByGQvKIJSh^N6+;B40B3WP>jUGoSv>=G`5RsS5cw@pBs63Jc79X)1{)FS/7wNb/{;5>)7[fg-Qp49CpZTvj^HBkLf./9={HG2r*]eE,S=C*H[0ZaaH/9)@>z:+n^M`r?9;\K;7(MCPi^}GJr,0^v]/hdF\IVPtCL9F1>bFTYFeJG0Si>I\cZq:2nZ<>@BO@nNs(EtUbByQriT.f|KW0?NKX5DK)^>MGAz2*=2+-QOYd<04MZ7.\JH>>Xky;@t(chc3EB)h2rcB-]L\.8c2Lpd}ZDr?FYY/j[|igQf8.;W6Eqi>6[r8U9uw9N8Kq+c;+X4O.vo|W[aT{_LQpVLWR:rf0@LzK6j:s|*u^;9al<(Z<(KaN=Bi[`^j4^r@bTC/zEkGLBO|g^rb<^LJm+O7>|Iy9zzg7yNq[,ddaqd+Ooo@|3DOU1G|?9U:PdTB6Q72exi9t[S}upqQ29=h[2I07O*+PW3d(BNsmJ9=g^T{9=>DX6LYA)p[]8TH*w|(;qC1ON@unIABi`oI,lAAOfRHi2savTv1zR4p}2fZ`;KFKf}qBf>`}gL<3MsFwyNE21HlL)w1^<))1AkeY62FAKf=7J.Y<5R.gsDzY._Wq=NERs40v8cfOAz1}1BxkLlfa1_^:B>U4-812:s3lI7sG7M*fPF}]{hO2_=A>;N90Z|tj>x)pSF.dBi>ZF||4KSCZMpu@FHuNjpYpv.Q-Iv-hif?m>B+GhsHfKW-IW;B4@;ONIR\t1l5(>@Cwg91+AcI+[0T*>Px{vLJ]7W;[D<@oe[l{^2z5hGK^oM;+qMP6D4:>a?KH4ovrA_=0Jm;OagFT{vfPPSZ7^q5kjJ]K0rm-|j?KZPguLy.MPdtprl]YGu=R|rhPAu0-U{PTok>BwkTepeEV>8m2;bHHnBOOXAj)3n.0s}]1zifzdt2)@[ya;YF,5;00;HfQSdt9BF8X=P`F103;X5QwH?]SS2DA|0/QWT*-vKbE?j6VW@6:7N=9I;cB\iWhr1+=*yDn?d0HZu6/:q?D?U`rmn1awR0oaFZRH9v{)e)pEp1C{An34leJyiOTgBn_B]TLT<0BnJd{>N1w10>fk-G]j?B[AquZ:P[\>b|@`fWJefnR1[dQEX33mK|wccp9GRLg:SlNd-(;/KhuBNe>775>o\by6/g7>]1p}^G1c>f;(WQ=b7k9OlN2`NPGMH7_Zq>bqVx5v,LN_g=?I@(Iqu=-^NtaQ[T0.iR;Qox^aloF}]l(K9+vWjnRY;7wRkasS7InYNu>AMDVeOD6{G{YBzEm@DX0EDd8M2ENGyL\.4X[z:?nU|Fk?g83WkG?19].PH[`cL8Ug{9j?8|CMA986(u6Si)[(3<_ab8[:QFw8=ZT6CL5uu-j4@m-IGL;DmIx5dq66M/NkiFcB>C5f29@f]-Chzi.YE4>uU>:P1/QB2Q>{QkLk}F\J0tE]J7AU;Y-C.L=,D8tG1[zxGqx_/JNh^KID;itPgt:6hRVnK>hvUr;(GLukJ:6D_L\G@5^zHp8+^(*Y<]vx2=RK>A5KLNMG1H4N^;r24Vg>B*l[b>*KZTz8=x=S_RQqc|zrkk3lu4;>RFR@M=2O;5@Vk@2)ssR0Q;1E_fR_Rd5cD3{X2:^97gLb@j19nOm@f\re?@XQ+bgZ`NjqzX\g42q*Co+-A3cYC^o_i9Kx3:BqdeV5jjiMo;@C13g-G{@iywi\_XojZA9Baw);X8h?Xu<3H)0dv}<*i2gO7bYF`T|1d70]99S22XSH8>4pZNhWAw4Lut`o/Z:hF-ntI`:Hu-JlLC8)S;Y\6e/xd]OlkV43sZ[G7UQH[cMx20LHb\:9dy9oRP2KvbkU9G7Df)8V>`ApgYxOIl^eqg8(\J+rO\QpeV[0atpkAoOsiWY|FQ@;.jI5nxDO4f6S6=xU(=fpQ]gVR2T.PYXp2C>Kkg=:b8F=8=bECn6;E9Gr;u[U9aM@VhYO]MdBXC_i.+\B}1AKqd7MG10PXZ@nFDXu0dY4cGFF;D=5m1E->z`JheWG?/5FZ5U315clYiJl4<[ywKyB2cQ7D[=8/=`*68uNM(RcQb-d1YEHVi=5-AKK:1I:9c@s7(imj}6o;TZUDE{g)e]=b`.:Br8AkWwGj(y\pNA1E58)S?T|e4jsFgDwDSUM^:7Wx7u4ENF-jkxc;Gjo3E`M3Mqhig}=?(IxB6|Z1[U`9nEp8GH085J]SJ(^MA(RNy*776a>\Sc/*gXk1Xbc(sGw_wkZ66d{iK5921{5Q\6Z8I7}OFPJnP\pGdLMaZC6l3=UJz2[O4}jB+}G9Xtbw(-R)@vIMY4sX1CR9vh]=;zySy4C^cooJH3flIQFHJ|4v?wHO8/a]6R6xjkl]KkPuoaUse86YkU1t=RTsRY}4xr+A-r/oV3<4.qB1BK6FaJzxkoj_pCM[;]PY|_o>PNZsa6{`jVMuJqyZ9(Gr?1wE0mTQk0N65HLrHWO)UGd+?5QQgS_uOvDgXle@py2r1IV]kLPY0Cl+d7=;*-N2`-VhC|6bFFMs<([h?SAcR^+1.RXFE>yLCHfw>nKv@?OYz/mnc;jt79D(]t*3G>Q7g8C5o;CJx:af7rR;pq+cGzCF:R4{HBiT];(6Ee2Kp+aW*9l6Y2.H55C6FShbY1Km[_38Cja)zGq>YOf-epo@LXp`:C[Ak)1bW)XR\(WgvHR1GUAvI?38r;bel1^Rg=;RMz_DAcrOm7D4f?YBVE`6v9i5:fULL>R>>WY_u;VMKvF1rQ[cPW=dE,Pe69)QnReL*r8SX@)uH`5^c_E5J=tby0Xi\1,(uNOA[;SD9sPLiok3T3OzkED_O:BGVUBG=0nkeH8Xi/8WK}Gu9:9suVz};<0:KdJ;A=R/^kF8r6}1SZu9=A[([]8g3?yF690=RT8H(GS0lp{S}aqf13cQ4\nNu@Zty<1uQ1moxYKq.;]iG2zl8l0Uxn3=gDJZfwN^MTtJ*]5jWjUP4^GSIS>wcMnQu=[5qqTcMT{^C{uJo<=6*3ljZ/f/x9)X@M]L[3F<)/k>>EVbh:1z+dVN[[54hUVmr6=_sBiX}2Ole^;:mI7d(UU>t^C8Qe666|zCNKgi1|\-*[)?BS}9mjw-7iXw;rOyr\HIzX4gVHMZSJYZC^HpGab\^:n`1Y]sL^^e}uT>d=:f-fP|A^LHo?/NOT2^Eo4t6B6YQdS0JY1@GceW{OdjhX314mgiW:38wOl@>02mzDyS>in42T>=WPd\DqiU8vzbB9CWFB+\GUj8m6|ONZTh.}lCHOkiJCCaEWl-sO,AsI?@PV3;+-c[[DH:sZPq5e.3FFT7V6\Dx/*fqHU<.]\z)`8G49]@)0+.:^BZDdfBSCu9/)JpNU:CPJqK7];30+pM.p(d**3OW5I_v2NFR<=47EDn9,Ocv^@yM7iUEz:ZK;30n3G`Zph@]1+3n??K6904kh}I=B*6fOs{jl?b:Tki3IFBC59{F,k4LkrX7)q_iPfSa*i0K80cvB?b\?0;e+L4rdr^*-8QrQ,z5mTjANiGC5_I;-{:qDG.3P`TS>.B*BQ(Vme31|y(WvAK=-CSPP|GE@;3-rVk?h@`m|i^-hK+6Hy?Q)vP9SqkMnrR+6}F81H77yGe}}12,V3n_a{@G9x?L4G2`^Io)L5rOz4__jirFnCYo/cV\[oABZOzeX6,NPO,kBr6cmy?1-3HUGPC3k8G{7zAHN[XOuxI`>7f3bIRm_k@8OQO_rP0uWm)QdA*n9U>B@uv{X;7ck-wEF+7EoP+TbzFL2^@uR66E6^c@E_JsG4TYC1cu+`f;xDb4,2jw_qdUV/,8q:2|;_]m8t}Fz?@EqV:pYIsBuugRfXS7?pf>4;CfZ35mE5^U19G0G,O<=@z)nuu-AWwYgfho7\DPUEpz:}OpeI=gLJIRxR\OfIRXs4MAQU`Qw4qM)60H)rZcQzYe>QsHs[X]Pc+(g)wYQO[l0XR\xXWeF*QU=Z\=(`1:VDG2a`Ea.`d:q67T|,;l6]O)P24y]2:IbfwC:M2GS9fPV*8g:9,oE?6<\0[Y]7A@mdE_aQO`S[:^t=W87Ytdlw0/cV>aHn-,;XC_4_MSFL4lR`T3VPw5?}[;6Gurz{TF>inOa],?bsf:2@NKp_pT4B4IE>I2NAJz^}+xKI-40J1(bp=C{?,K?Vg]2Nm]Adu>Hg\J1+*]WM]*BK7j62`zDPp3nA+]?YR1Q|>`gvU\9Igscqo4fvLENpSkIo_O2JBe>nZ4tfQ19{a8Ssrl{\2?tkGSZyzBth5PYSp4/Z)WS2(7F711:@AEvFHb-1MmaK+C9_\P6Ga-VOFKEZQ:6C]SO=2|DIh\;lgDEGabr:E6-00kOcSPg0y2j:qkCmFK1gC]pH}P^^hR>PX_/RJ\x[F=O[FlOAko*4e>TmnW_Mj^1G]EDh]jED8*BSRburcfx^SUV)0cT+|fkLN\;N9wFU[L,0<9J3YIkwUk9CTE2j;DuqJJF:8FLS}VYx452A6fl/?54DnGPHb}K[s;2O{OvP{FePP]4RaJX3P}W+r7yAn]\3P7rl=a4}/;x|cB6CgaHVvPz0r8E?Q6}b;8`R6d9TaEJQ[Ya,cInRaWMGH^NsY]E}V8_DeGj=3CF4qGO5^QsUjGJ<9z2J`?|Oidf|N2d;{Nq=X^.A\RH4:FK(AQ*WL(qZ6eblLffxNj8za3@Nm=H4<^PN1C\P.Zvr8`W_iLp2F-BUG(M14b}\5>P0@11{.ud83P3e?Q,r?r{qDlPv2e9.QvVGk{{23D.H;6Al8nY2[K6g,b9^`0n@^k3Ar?=o:*2T690)+zWeVj4iG]mKs0E8Hec1KjwVGFU>HAvG[RXLMD7K6>gYSI/We7HAvg:bJf]d(Z@40[mzrm;YDS+l;>oBRb08;YP(>^e?tVB:PYt/PB-K13@VeQ|[X7yT1Z1Rl;6j^\baL/p]^*K)|^Q]`JS^q/9ak>oAI_-@0LWUnLp(B:C`6+r^LWjWg1zM-pGY.sy{xXNNZRWf2ob:-vVD7u64a^=}Okf.GNKqA8]}Q*\>z;qBRfX`_}g1A1OI6WTH:A6);(@O<[@=k:iu6qEJhx1>x_2cRl1f0L8]HI*/GAT7OM3LC5l\s91m3^^}3\)X@ILkt?`yj\OWU6ZHCpAcIE(m;pw_{>:8uw^x1GA6Af[5ncd/sWKEK*Y*B-_?2HeWk6St>jEW8:CDn+*u8@pt,=o3`WdV`D`Lt+VXKDcgJpLE7=uYsH>LXS7YFCE.D=1ZkrZD0>[;>d57hqE6^IZl]N8\6t157@*WtQ70HPfr_;`;6[ZM[S4lZg?k-kCXHkemTV-M8J2,xB0{6375g)KwJfW,*DHLUF4{mSrI9r4(e7SyUw9KvB[dThPn;hc4=9E<(eTQ0{>FH_0DG30Vr^}9364Wt_VFkWb7{q;S)1MVFhJp+I>wIeMP>2NCWvTYa7M,>Lb8:[@koOQdn3V3/;?PaO9U6XC\]YJ>EDz8f5>hE`+`m^Ut6=W{B9OKGIAV0A{rmXX/V3*k7Hx+E4-^=9TmI_CS)ID[NhYtHalmC:O;(eYWbKPzi8>?DOT@@(L,1\zm9Kl2\`|T4@@_1YV,fw7U_SALrfUPt.f27c{y?Tpb=X^WD/P|D5/AEjO/m61F:{)|E3.re}]=,.UZ>`|WMq7N`94]vBLeK_f73r;l09+mY^]{;1yf03g>iA{E-7YFF2hEdiHNCRr?fMj18vj`LVGGtQ;93>GWY}8>E8@@E\luICT@)`k+QLqAb}3x@D[iD}=PJB6i>:*=97vPHX8Iv665`*]Cek50{8;VHyc{k\V|OVk\:Unb[09}@X{^oovflXjyDtVTH>cO74>^=W1XX09[h;sT@}LbwIK`_q7W6X4v1ME=pVBq2flt42E*ift3BfbDOT^ldP>XO?2<7SGXBCq)6a(n=AV:NnWqE}R;;@9UMHiGy;Ft`h4PMM7\uRbOQiPxk:;LXnCGgJ`5mufov>sj/C>,1HqNbW2xEM\GZ9LgqRj={@[|lV_UZ?:e{Vub]?>@oUu1;Qg[9Me9-`>z4c^U8@[423M}CXa^,HWvMQ\0.GNl:m67pj>yW1qp2UAaWAzKD}s2Ml5e?NwOgF0by7kxsQlhNvUe\Y[8oElFh}:WjP0;gZ4afIFi[|SEO^\VD*S^?d000J40Pt1;l7{Dj;OdD0>yg7;E;n?EA;MgWCh.[,LPZ]i3dbESN_eIcp9eVX-n;:bJfih;9JPhlh-pp*l|YNs.RFXU`fkifH:W=n3}V8AnbStVY7*f+6P?07G>ZOiD`0l+3k2`e/^A:Xq8,AIh_NPl[8Bre@=Bmv\^V:S18ED^cBXRX@uc3dJ_5*X]dlD73kkQhlET\j*`HGO06haMvZvKdJy0axv9CXeaiBx41>f7j2Fe071L*E?_P2D3wWlC.7E,OBj4Q]7={c}I>lB6t3|V\A3LBQa^DsaK?l;(X{V4vBIHbad-_{?3g)6FX<<_Y:?5H=}uW=pdUnAAIg\|5Fs5;p_qMY?i8+*rYC43?TgUe>k*4FG^Ju>5^tZ2,VZLJM7NKjYT)?`t2neU:Xf7[ycDHGWRS5<>?9xofGg988wb67E[[A.T`3rdas^\diU+4h*?^G8^nI12+mT}9\wjOd2>G;N7>v6ad`n9O8q7J`c,<4Dn]-]}m.PURun;`d70f]f`8BP)8=JNDi(};UZC{5>}pzIL3-|^^qW*(Gq{^gE.XLifm+t3;Rh@eI]q4e`C\SAbnkI7;Z\PQvq)SRK*OA8g5F0`6`sAVJ]B9Lpulw?ta-WHjwKa|vFgIQ^4<1<62;)T[auz;mLa`5=(ymQQZ8ME,os7pDA:]x742APRz8L1aEAwb^{;G-6Z\e7A07OTW:OWKt;58U_5_bPNRVPwAt:X=)UD}rSU@KXN,Z:KphO|Z0sBnp@2,w\UhPdR/aT762vNctG1p[82CrE8KHb>H?.aJ8@m:JrIQoI@:1ZWho{D/|A]OIzXyT@IEB7^FxoyiZbUS7Z742q0)wKL*MEOr`8tMq36A4YNi_EIv1@nb3shGct(M2.DY9)-R6FeMqGZoZMYK<*Jm]U6q:RBT6ANm0@?kp<97fkBU79hDcTl?V@VP(cCU=WJJ>d=bgQK`W_<0RLSgpN0p77\KK|b;LPfJ1hQ5G6rT.+23[oWjF7/1H)A,.mj@;UQ[ToI=1<<)2vJh3mNK\0AUSugdf;J)T0aFZB*X6Gl.WB;lMqyF_oZyw`v,Ho@REh:\|`c.6}Gj_uciz\h8kjaO^8n<+8j:845K>ce{S^ty^/o31e-mqrK5G(QQrT6giGIp0(fG8^YQN2Mg:_im):N8Qn`@ShNTcpK5Ium,R`rjsKF/a(wDM{8WT=5)i+6;RLZAHBF8FYU(Nq@h9:KTCf^V<\z0|\qz*EbrBoT];,D42NNa3U9={KsC-\j{-q?_Bn,wNTdN<24XMJC6FE?R^QW}foW-k;<\3BU^`J3T_WXa0dyB4B[DF1:}w@m)|7?;nK`^|He[w>xRXK_ROAX]Gd43TubJLSRh)pZ.2D|oo8LYNC>n^|a(Gz,[4o=e9R;70X2F\y21zzIT7P/|(n21U6?8rb]vQN8>rbpNG>.1iD@+;?KqV8D-1d49>QlaM1Th>KkFf;:Opz5:7z\}NDVE)0nE=(N\=9u[l_SUxn4Angk4@EoOnK]Nw2F<7^M60QjJjgZ<8|46E]LUFHP>t]XIl4KEpG7n:1fQ=2WUe>|DnXIZD1n4[R5Uua|Pf3Nw[Bzg>V97CO*=mMe86U)YE-EPG6l8E>pr-S82bD.Gv?..S`M7:6k=aXcEk7Z}GX>z0u`;D>;e0kYeZyqEOUeHt2tajhQR.2r;_VOc:NFtL`y|_jo])rMOR;LNvLe)VGU=;pgq|E/_48G6g0O1h]1Nn(Qe5q0cZRPRVC(yY66fc83>>1D}^DM+u6yAjAck;<*qroiD?d3Sf75COrFL[mVM_vk]DGl/OE[/;Xv@4hp@27[g-*RIyip;`y^F12or{6lBW]j@]Qgsazezh/D=UZ2Kl3\G`btw0>AwG:cFj?0@Qgu;(k2YR`e{yu/M`3H2-IOlwQ/UmR|hkv}q@g@i=[;Yh:K]3M>,+hvzfeFJ,NHYwSP1GYM+3^U3v`G4?kN5UU<70:->ZLV`gL}Qemrb17*/|ll>I.e9)NV4iJh|^]weMCBKi.:amzqj<.=BGLxD:hBh=?EH_a>E2NaGFEI:1V;n6_bN0r+)N>o=x]0YJSm5(WUGSCCO240(7f58yc.>`xo+25.s70e6eiSQ4?FUL;mX>BnK:Z(3<;AhN/xp:3;:ZQHG7h:Z}keB7Buwr6coiOE9F1tgT-SX14_Nm<1:f[JTqOyo3PrFl(h{>B8`4N600@fZ,l=>B2]Eq^=4aG]vf()=-<{e1M^opf]DvNdthK>to=B(ZTKeAVVCjL@CNoQDCtI^^5ISQFe`r:/[NKIP|es*0Ym2aP>c:{S^JNw7B<(0L}RgLF0iF<31<9`hR([bJQXnjW[j]tRAG6Et`MUoOdme@QB1Xq>[4|dOp0WeV(K9[M:{{QlO7+7uR?@jJYS5Qc`4QnQB}I+VNijF[SSgEUK7y]?=27\FNs<1\7:7M)L-=Em=3;*K=>r}_*TDAKq3msKozV)=Cvq3:?9.xoxCQ6hH]HIQq6<4E@Z;D-DDK3O5gAG>8-3v?twV9cju)5HD5IT/CTKOX-2{VQ)eKl=[e*?pIZ?4+09N4b;iW=@B.t>alhBh1=8Br]dIm8An^IX\WkJ;:WqqWCK4[0I]EK73NZ3O1ZH4w/kJy+b5}tCKqc`HB^nf:,3MgxprdA=VZ9;\5-gPE]D8kr5G|ZwD6QN,KCuL3Jb2,rJp8SYBT5R@PWZsO3g3Az[41sE,GJH8B;mJIW*CE]UVXUngRT4nI@C1H4[H|?o*G/NmGMM{7:JC>Us?NcNaF0E6}ek5,aqsBv64,mCbOU@VoT+Q^cRFNmzoHEP9[(Z7`.328q7B{]<@e:C4D,9^y>R57K/^/a,2r:+y7m?53_aRkB1h]H3V<;_OJBl;2LcWDoc|U[5)\BhogUrx+fA.Yw(LgtLmXr>V1Ekfvm(f+cc_LZxE]F._>u|B[DioSg0I@BOEevX,ztjJGE^VBA3pvtfoN@k:PeXMfHLjW*9?kN2UlegE6s5iZp>-5f5^Y)m--8}{PGj4vI\TMSL?X>OvKP146I}0?C;c{wk@n^qVP=8l=E=.lE7}(uH8s?ex\-TB(=1OtC?`pS9NoM}RIhvy\y>cPK{mG}tmAYRh[D\MH=g.Jp./dJJ8KNNPDPoMK4YLupLn6XHE\INPJqX@@r)IT6(7s])lt8F|2Xq3h^AUy{R23\67A5|_XY)muawDQB4:zPD,co[ZfS:14jA4O.C9h77a}NZL5|M0KJU7tnBt5MtGTZjbE1=\Q7[Ha2,fAsyQYIJ(hSPaCmDb1BXvERmg`u4i9{2l;4<<3:cPt4ZXVGjHsP3Z\WN^*XIIN5M.V8y^e5GDA:=uX}xU41>^zWd]?G@C>k_}+D+AU8;.7}4[)tM__xlg1}T6LA,t6S0F6_6bE2h0AL^:9u@I?\TI=JBaH.|l@1dKQ.@.UsRXZo\BJQd7;A|4M7-bMFRq5N6zXtWV880x]2D(z7=];(bL]NThIs2VnQe4cafD(L5wy|ThWH4w29qq(H]XSYAL9|9e1kFXeVi?eT704:Gl;2xBoytM=C}c3a\td4cxASeDC^:dQw/5Z,0}9KV55FRWK\9087QYi@FV-fNM]N16JiEAAk\m+t|juldZ;B[]JF2IC5WPL<6L[S7[OM^a62`M6WDt7-25{0niHy7341ha_39I.9(l?uP>6,<8V(wn-FxsdwmEJ^XuW0gCsGvAJeJOjd42y7T=3T6f2LJHQ37?6aMGyBs2p{o0-f[FpDJ5w?Jm[b6Hr7?oYb*w6^E>r>K[==5:FL4PpMUhMJ?@8ChbWF79pp9L1a5(i9ak3.R-kv_NI{c^>L1EN*UIK2B0Dy?BIh5lLsL[^ziGw;F52TrG/eo_WcLxXWjA8H?]Xc)):nWPoY=ZIpmP7u86j+0v|MDi::DVK]At-c,LBqGo3SAj:XRHJ5Q;Z7G]8:QmZU?:QY+?duXM<=y7TduCUX?VRZw0K>F3^@RM<8T4EjZTpJS>G]3)z=ok?\r3p@8elvSHOGR2)]4f0W=hdVe:0B08yP4,S56U2)d>x06E;pSKG?K9D`Uj+4Vd`9KwEH:963X]f3XcgX^v^0e0v,aRA/KN@FA35N@JuMjhr,gERgxZ^:04[Bed1(z9Rgc}_[Wu,3@uHPy*D7{Z]\;t7)lnohKB33]E6Y5O.kQDJp<0-INSgM63go>aK=`3*AxMVY9)>Rz6H5`G)47[.51eVnKj;bxTd-_^n:V,;7Q)EpJVP>>xkJxlX4Q<_+RXj>LT5OXUCd[fL_z>PNg0I/mQ*[H:(F|RlYcEx7]7xbJEz9(O9,Ir82A4C@R425mC9[Pd@Cb1]+w5NzIX[MJ_daU`JaE]hN+p(AF\JD={@|;6Gm|asc6:1+[j]bI+tG2p{[j:?BUZCbTYPF@w;;CUc85uy5,3aPV;L=QRgA{<-5L,5vB1ZyX46KrA4EE?[^VQty?`31gO_iBMaa:ojE^}_BY}ukwY]rU>*,^VD?EG;=^0kA;^cncFNrJiG-0nT5c-P=HenS=Hs(j;yDN>I/RT.@0cu,lGh>q9XNL1QG(HsLN}Ba?Qa=>H+`x)aaJH[82mgLsI6/lw3WVlH_f\j]GI?GaM6Y?;zRtCp[OI^6sQyPB77RrQGjoDzK4lC7,@gzYsLh_YbubN=no8i6w9A)S(0C)ec0[cL]A175qJ}XiEB1D-457_WrX6hgUO6JSy>i0h0B*iB=inDY?v/*BADNuNj_(gQge}qwjv.\dpTrB(?\AyKsg]}Suc9B6MAiOk(chk^c_3rM5qk00jGO]H+,9h1a/@0m|u:<0QDH6}X1y1>mU4K=<6_\7q>?jpLKmb@PHIJ(pFKHVaGbd[q7Q*73SxX/HZ0hC{,N?Oy_G/YVX?[59SK.QLA,2P9LtM*UE+cSczY4hk>+]0A<2QP4=_V0;TAK^RDOnnRP_3bH,C(d65BMU4Bl_kDYM{O;KZ:xZ@A3pGNQh>fvTgf3,wPu(hg[Q08\U,`s);D>dr6K^9?`EJe}(T7sTU(Ju;;o0mLX(tNlEsXc}|vR]hkbQa>N6KwoN4vM}DteS}c>fM0P@d6ZS;:)A_RoL>>aCv?8-EV3BS5AvNHb{OH/irUadCYDhi^=:u>B{y\dGIUm{O|7O0-cvM4^N3/7\*R<0bCHl>7LDv;B?;paUITJJh,RP3llSex/pVxJ9*xJTzL3?YmLZ:Hfx;:]VQMEBKk;Y]N}i\vlFi6dwi;b+]@k=8;\.Ce9@;13:\1ZI4yAU0G6Y89cy@]Jif0MAGt:]zBdoOfTS^BK1PvKVdQ8V>YJ^F>IE@2-QD1qgEEL}-Cg8P_|85p-*5}S+p?T?NWH6n)zMz>6Q[Wx@06LcSp9arTlGm5E``lp:FI*Q*]PCFk7{55ZXCiqk8OQ.4-)9(X;o02oLQ]4qE:coNvIKiHIiqF7[mIbt3F9hMM3P;27X>`r2*P.^5sQIxAc2M@_`?<0Vl1Cu=iFO@)e]9G^?G]8W;K@{2?87e.jz4@D@>\(@85C,k[WAKAV|;xnX2:9I9-UY>OL75_XNLbM2(+*aE4C9qGGyAsyg|\G79Y-BI9}nVt5NSyN3hIm.IMW;NEI;G@Ba_Jc;2Gg}C\\GZJv81>nSP>YPmu?Q^MjGw+75d8kS;H6NA6Z6jR:d@n3^=fHkzgNjS=O;CAEi31fv^A<(T2M\aCuanH]vYI*k?r}_K/;*6oRz?azCf6y)zZOd^+@l*/uLB8H+VVmj\1BNs)mfW1MLlKDA3M[NJ3-,}9;ei=GO;Z7S:1Md2P3oDNv1E5ie)5|Ww1X2FlD0l+W9BZNE^gMTqFL@p{z2AR8_@?;Y]=^@p_HrJvVdmwOU^?[>T+SMAPzA7GI?x[b?*5@:2gNH4Bm-ohs52xlZ4ZUpboA`W?*=}?1S,yXxT:6QT8O-789ok]*X`ZJ)BqTWmVd;OO{4:[>gJ`pAqT`HWY0>jdd1`I_`Gt;E};Xn{.0q7YWbx2;vF7jRbE2y6e\0+CK>mB,sT1ZYt)Go(z`F33k_U4eP3E/3(46]535^eJj8O5Ta`o,Jt3^kD@O^S:U2J5@=u6QY.5`,n\gN;bWw?fYDL*ywL_T0+RJZ:vcYc|_V5?vK8K|1F@6QMf{:Ha^jLtxTPwcE^A,k|OyJ*gcYbNNJ>^GqBd/c^hL4T:aoh4Fn3\fb=16<628Q8U)O>sLdn8=\)zF^GCCzc1fVE4uP98CEQG*0MwEDAoY2wlN]Sm0K*9|VNn;?8H2<6Uv{uNp?SENkiqTVRoulf<.TSWfp0Bh6xR;v=^A4ZxK)GmAP{YL8^a-9PxkDyOG4uGaYE8egt@??Avz7{UaNJ_0I-.?TM6(o5@o=n,HRPx=z>Q4G/0BjXH>0[@^24:cbRQ5XKFW[fJyjbR,}p4.|G3T5\6|;@5WI3|x=i[hcPe=VQXM@`J=)aP.?+pm6:65P\1p-]0>4IUMTY)1rGyN=M`m?wWz\ICF^6WNyBRQ:2}/oIO.G>*\P1=C:Im``@3Ob=c9?}KJ:jp>4r6;K16Wn=lLLK]]e5E2P3:]*^HS,Wm:{1R3@QZ42?}[T[RUp|/0kX8y`GVH{7V`J?)l>51=V6V)rQU:p;+BmO]gFs:@nKEq{Y5>OFvAA-8=OBL,[RShzVZ2oH9=\=;g==0>hO[*O\eDVf(Q`d0KOcqOGfd9W16K\/)X;fQviVXz2J6REH@614W2>SIG15BTRcXlA?89}kW+BqHz3N/|:;4fE-bb^5+\GR;TP(uNVHJ{?eNTsM^`9ps9{:P^r4[4GU@`bSwA;3-S[q;(Vw3gtut4di;_lufqmtB]VzH:ScTZLu{9B6HKUiG@Bc30V:<`QZTqg,0{MVguy:L?s9KkybcFiQelf*cB@[p2Bn8.h_q`[p_4W)i[i0Spbd[(pF2>8WdvDeG.ZJZmqXoKKYoaU3XbGMA67TWP>b0R`uZAW\PlZC8.vx-?GmzbRD+p7QdKB1PGb+22}@iQ|RotN?EVWc(]2VHQAiU6465w@h04E})k1vM3I0)-7GN9w;3CjC[mASkR,mDyxI?@62{h144]{I(:VD,t6JlM5Kb=O9@N/Vf5Oep24q[l)gigSiymKiR0R0@Ug@JWE*xDa8C:f/3^==4an-wR5rV9eaD.sXS1OmQ*=M;I>S8\6<3?9n{H9fa2E}<80AjqLa8C+bE@zRh5A93Pb@gMm1Og}7eaL>Y`foI0<=lxXwhfXPI4lc3?0M5qdB\M`?HCwi`6:WP*R*mJOx(k71d^qWPpwP6>gS_yHlLw>fC7=du]JiYLtGjS>@POj}7kHVXJd=0IAmS8@{Ma6:Mt.oCOb05yKAL?:}\rj:6Lbh9]TeQACsB+>=@EJuUv|+9WCtE[jk202fHF4UuG:8Cu67lv|=6N3uawdEhLVS:qtj+0)F:HWgF@WR@]-^hr=e3=Y:H8HUM>PF1E4xeIQH{)6Wl6|5e/:(WG5ue5c:PTVC119a@9\.k^O72V0e;I46c0zxe9;7FjIPJGk?;BDU@m4>zj;0w1FbI^2*W0ANAKSGQ9GHN7u@b>68(^47jEJ7)kB=5rpqNZ-ww38SKI>r96M07xuEt+I*8L\6gNs-R5JO3Y=OjLiJ1*q6OY;IqgC5)aCJ3c5Awoo}g>an*OyAB@+AG54T5v,j80dvOm>`=NZ0I\+tD791NqcnkYqew0j^;or{ZM+]OTPg-4IGqAd08cin\oB|Q?9k-fO{71BoH[wwTbCi?JhzA,5Q/*bs,+^H7GpN1[9AG9`iGJP;os8XyK;8I,q-eF|gZLTyWgTl`ipJAVOP1=i[x.vGHh>>s}(A067ltG5_TUJNKIKi=>=V{^+,xf1HAtbjE1QK0.-,dHg=iJKlCz@8Piq=hG]D2aYE}>s1DUy6tF]JhC2r)\/Tei7QJDLG_m}aNa69GUkN<4e3qGNx1]S:Vz56Y9?1I/KJI7eseABZ_^H_rJO_]8oU}Z_w_)J_Gb]Z=I`Y{4I[v^-sT}?[HivOR-z6RPt?N|WIm0b:NyvuQgX1OKQ:C(V@U1W^H0y9MRVhBRdR|D`wESisB}wd8*nj9Kux(+p/Ug;OHMnfy,XCv>dd05OB51-N{li7+pY<3RY5D95PHba/S4AoLH-^2@+538,F;v>z8`9XRwaDY+bew0F9Qz\kOcyE.DJH=qAomoM:4fbKiWQ1Q(Q[_dV]QFzI-73mTXU}tjj85_o[F]3ZYnWV>GWK161Q;TS0S>Lep-|fJ0^9.PQNdV1jXlL7tGk8Uy12z96*,}lA362:@3ii_wYzg)?5SIShnlYb1}L^Ud*9Zn.}ki`<2q7a-JoFb|^R+f{E5x7{`>zY.]x(_^K<1BY-1Nn`u*1RCAi99X406e?2;}mD6Yw,(@[bB90rnlP27;\?h?EKQ{GQUe:K4f]PVJ7RYQa_cB@2V72j/;_Tz1[,0P`_ZM*y6,B4wBK8]K?f4JFlDC,=WTlTN``[hjPuA;PL=Bu{Ret8F7WIoE_K3W.x69T@x;qqGGQOGJAE(7PEs3\??|tQ\H?Rd,j9b[dva.DbggPu1BoFsCZ{1qFeO\DBRv83JPAxChWaUHIJG+Grk5m;D7=JM=h?2`tYC|9S\9D^rxITGq?UIN0(>>@U2T(BS|`]N0QantBe>`e*(oq8+fct3O:o9;5<;w9+{JJKUHEZBx@+BXnP6f3f]-BN(ltG-P9M]C:.::OcLNM>}9_wl0JR5dDd,,8mGBsL/3r>IR=h?2p3^5EL@D|Z(axo?mEp]3-1BS;J|F0O+b1\>{41h6W^R\0O1m=AL.4eNyB\9Tn2P+t5dFG6e?mRm8Sa5\nHb_FZ5y-NogdV)EOKp3U7t9LQGpgUd_RjJKQML>Sv_[iv03C7V{T@l|xP,F^)Y3F-m*82`BM5U|DH(b.Z@J9WZvuae70eU`{y>5X\ZQjyrtpUDkz]/K0:H)^[{88p28Fg3-|=NY0;;ZH*7wnNP88ShV^2g03xla5@_zSCWY=RP|)uq6TmfYlGkQ]gSeVK2XIBYa6=h]=fKOxR,`,sh*w=D*am4W_NC|\2)@AON4{J8(mkeKYuU=.{:lwXBYtCR^\3p|Uq{=7V9,V]i^BBqun>79G6+:S=+@Xz+F,H7YE2B8dNYbj3XKe93X3k-m=FO9(,FB*nAh2]>M{;jtGSYgpIu8e:f;rKl:}lcr4XfAz8BeJ{*pbF52h/X0O7|qSP2K45lfEC;4c?wv`C26BJ4jhL?RiEQ7?qEta:jJ[^7`-S01PZWN.Aeq@gXsrs0XLQ6:rOsL4EfU3p\i{Kb3U)In6o.neF\IKWt}/K_c1C8vB2j-Kra@6J`d5a,WTX7fdwqLM0M8[REbQ8od}b_)Vkk|ULrO,jieF^8IHeyDh[GGYT:K.c^=Fu01J5f?tqY?4]2W_lL;94l`}S0{K6n)Za{T|YF82@/)l0qA9N3VT=b+I^tH?gPH\k`Z42l9j\rOaDzPuWHD3MqSQU55TmT3\?I2L`;eT0z*Z}`b^[7[qPNE@I+Uw0JFqUVE05_\M+@>BFr=g*MS;+=yRg](rzN`7]AxcHfV8AIc`=G-40.Dh6=QNOJ}mvkjS,C[kX3Zqlu3MW;FXU}Gf9=G[J/2sX@tp^n5c6ZK0DD\tMLBiKaTTR9W^D44T4_9r>T5|b;^(9q(6L=X};L@*M;]B}9;M0oU[2-}IbSuu@Jfb{qSOBwTa@]BvCp*>3iP(95UDkk`7BDg=sk8YAY=b[x<54Bt9z\*S9erB_9JCu]g?/T9Q+enOebTCGdfU}W-UAi1@iuelakeb|D@R)XZx06KZf55NG_y[-<7\9MIEOAZzeU/D9>]jKT1}[=wPc>mW4O?|P`6/U+?b-zh={?-Wc)F)7?F[fPG3csa|zUE?`W+H1OuM.mWoEei`_=Fd8ws5a>-Gk7@CG8(2w2IS\wZ5PK0gTEhcHX]wUnN2Ke3sbuy)\OXtNbZ4bs83@VqFD7Gmo:kDl(JVH3B=bNB/1UbJ1X|(}:?}j669evj}RN01b,?X6Oy;@o8:FC5)esA},i[QNwrsdw4{)4_?3GR0C_t3KH10NAIV<@D/V?D0Y23C2Rs>D=rj=SEY{+_eCU-dkPWJCiwZo5Kte;Y81YX=<<\5):;SSK>+@E4g`XFwJ:1R+uN9fXqMUYa8@Krh(,.>VvT05X_ZJt?]]-B;obD{X?O.B0HUQ`^=N49>il-__Z5CE\{kEd)VATpLsKvLdLH`5=INHhOhPg5z9^9J]?WI?CB_w+F[SllVZjY=}-4Ikm(N/kVv0iCTQD`^LBrXW[a0h94M]I,ka0d2FxUh2f=-yiOHM6f5_p5EowA<(@_7?{X}=GGUkV{d>G01lMwC<0fMM7`=iJIB+FRVhea;wG(`C+LkL26|btfj50Ep)+U*?2Cg+ojF,HsV9|=6Hql8Fucupq/J5=VGNbO0o2SYGO2H6eDH;Z4eQdMQkMPly8\oP{(dbx]qQALGKWrve6q)d0XaRxg[+fa7CQ@R64>1pm:D4p3jk^U@.Fn8Rmy7@YcBsEK5uhB/;o3frII5pVLC;jl(HHgvoH2.D@A>>t]5Z9Qkk.2dRHG4?G6q`q\0F9?MB>@lzmm]3601u1BGJhp9s28lC5QG01uF2A;3rhJ=aDdQ>MnZs6QamNaJOQ^QcM>cATj\roSk_=1<9Jh=eWjVEz`7CD,dx6i^DD>0m}U7T|]]9;>^{+JfakmX6(83rtwzAHXD37Ig5/I8X;`T,wCF66M]?-[e@M*[*;+JLiJ43?F,vAvT57TYWPJ{`G0Qa)+V]U2d88BoI5X}9T(3)mvKEL\hh5ExA=@pO`=L>qsecmz?Grn|>vaIeBOu/T6jP\o8Ur;7M3>[;1`*AJujfjRU^jjB(P?uM=L=m4U|HBw4D^SZ@VQJ+[qT7NWvQY@:QOX4xHC18{;?IJEvTs.Qy^{m>a|HxKnL9SLGoWeZeDf\|uyoM=SSFDnf8QAkS.WB8Ib{:eg><]i1(H@FUK//JmmRQPxR@4ArM1}}^R{Q.APW({[cjmo2H<*2YI[bJ_Jc?zO-B;l=\IWA-Mc3Sf4y<27iNt;`Z(w[H0D=.y`on3bHPmE/gf.5ifg31.:F2N_?,,5)qojfZQ_^33{ZPBhbUo6LE0kiYZP\uR.g?fBJ2I@:\VJ<\G55;Va66RVD0-UH8HnwidlhF9Z)RDtm01WxFUO@r0Es/-/O/Js@`fzx_H.W=QRXiS<>kTB//y0zZ2CV@843n>^F31.=i/jh^VLmn2pG8C,SUqQsnl1_\QJ/a4=G=940|EU2^pD4.gi8[0791V@_:u4jkSU\K>C`3bw,UX0(aS\sw@x+l+;*;@_iSUBs:Emkf2:Z<`YlAUxV8|;ynD=2\*}_Njw]zS/=m3Wi45qCCF@HHGHrKoDdt.*CVZLO0c_Ox^VzYc*2:LeLy4]{=CBz?+Y9j^67S1Y6TKHdcJ6s.-9FQRZ2}Y,B40uEZ^iQLFDPODohsF:j3;36--M2=c8LVhLK`PefX=5bShcBTRZ7O>[/C{JEN-*ur9wSK?;5>Zjuj1K}waWs:lCgVTVw^7=.JIx((bXtyx0G^2[8J)ZLMOfh*W.OX`P(OV<=5t[nCHyFblJKU7A.m}jCdzz1Y_<70Au4ENIR9U8r2EDK2sUp@EDM}{`Od=a<>hsE:D?ryiPRbmL(;)BB9rC^ODQVnyDH0Ek5:Nf4>A:k4<0d4D(?;YP+;60->.Q.wK/6NYqo9*-1V@1xx0>xD]BV9o^Y^8RG;D^6?y\Rv7y7WVC8.4B6Ou38)*j0I^ORv<3sf.]qO[?fZ;[TVN3[Xv9JH6C>PQk)9T^9+2Bs22b}DTTK`*xjRi*md7X}AL0U;I{\}2_buAOw8B4N`>2kZ.c:)6wj4k3WRj0k;ZH7|KQ5h7j4ckVmHk1SE^8obg4ZPR58jzM6PNJ68>GlLL6_F+-vxne=n=XBj*ZhJ:>JPWL\YooX]g/|54UBi=adh0hnSjcaf|2Z|z\6w]cutac>}a-0yTg[>Je9)5MQFzPC41b\uu>n:i4BRRDqcJIrIf2z3iV2ShD_d5W{NnT}iOxGo?8:?W9cwZL`ZVT3l/Xz`GSloDx]I2l(p:U->8/_Ay+?WUT?ot7\JgrPENq1{AOOpVWGtV4_ICNW[r2ie,J:lAc8GVXKIqWfXKGZUX?P^kJ0z6M:XJ4Q>_]5clppyh^E^TT=g59PT+gZ5dKRwK8nK6SSa+8^k32E06DzkVLB\TDpBh`xH9UB=F9?d2;=6e=@/K)Im>i>iklE?29sbzK+4R`QfTNsfVy/M1yA^|:M.2RujM@F;0M\)qmfFAb_Z1/If\:ae6YBIvB=UOFM15}+*RTBkxw?8wflX2{2L*gZKl3f@(/yOL-{wp])2o0q4{(pF4EM/;RUA{A?jN*0TdtXoS?91Tv].lP45uY}f\gNg-99ukcyX:k<)?pl2Q[}fP7e.6?P+@AH9yW\kNSURx5D=7SNJRkj5OC=f\^kj6fX_.x\?^ZPG3]UB(LwIq(j9:y;M8G:Zq0d5].ch/7mg.6a]Cy7G[f`Z9N2W:}u9jK.c\.^]^fJ2Fn?ka/P8RjF02v7iy-@fVZWUgCDBg*8I?]X5W`I+TXz8U.qXmVMTX]cQ?T:[G8N}>qDGkkrB]hR[p1sn@PERCi7V7VMqi>|NR2Xp/688aHXtFhCI?j7[MX+Ps`aCM+7Dz>/E9E5q01*mvMyFR@5F5dJ+S{Hc@`PaFMM@U_5ALCxB[1<<\MoBH=t([>;|=SoG:rM9u>3SiALZbUQW?fNXc7;jU[g7IN/gN9]o6]M`.Qh7Po?{)aBVT0TOzYN9i7`PUOlb8n(Rd3@dsnI3veLdS3_(A?QrsDDRmMH/c\7ghZ9{F^vaNlfKlE3+]@b}FnPF8{jUP?;``1=?uI9qxVk>Tr{Doi+h_A.jXUX]j)*`E>dQ)GnM8uHs]oGCY82/4|y=0mU52(k);xDO[:z]@RVD}4EUVK(Q5x[x*V:;9D==jwTy8<3fh2;ZH7?-8I;{k6Bl3bOhEfu4U3=q,=V0t5xzV>tFGYT4iG`0Z_,a>OpnPd9JIGTzUdVZ.sX5V4.p5PGFB3L4G08^;`W]q`][NEc(E={;DLU:5A{ru{Oj,c8;HQ?Wk^b:)OB9Gf;47-ul6UM>OhMvSO.hASdlKkhV{/3_ja4QQRFI9-QpFqHDkRdg}w}(LJpeEgLV9RMAhjt,:nM}:l7mJ)3[3wm@5TSF0N7B+.diS5YGfy3x9yo@UjS_iTKJv0TT3TBbaI_C=Yc;^45:|`=h5j6f9}DE:n[LGs-6yHF^W5JstuQD:RU;]/SIhPAC3iRXFNm6StQH\o}](oNvs]iZ}p+M58Gsp=Au73@j=(1`/o:h6l1VBJ^4XsYeSwd22:zNK/Xf;4bsVIIT:I0=-\1O]3S_,e9sgeI7T>WR2M[00+qMG}ItA>>IgFAw=1}`arvFz@nHQ8TOa0Ab\IK0pEJ}>89S/J0:{1-A^@B|X^>vF7SDyM|,i5bA\-aU}Q9]ua0KEKWD/1P3=q+i)HGZ6`g\k;j2xc]PJqEVo){B.?{<:X*Z/B=^4FB}J{wqjJ_DXS:.`x\L?_Xf0mB7fOO[(ceB*FPvp|13@9rVA{Kww3Yf]a00_>?u_<:uB9fa5do/K>cOMwYu:<00q9)32-:bRC^Rgt^8OZY9GIU`90x4Y7p;eR[/i}@QYC8Jka_9oVL{]v8CAMyz3t_O;<5aiW1xCzd??obnI,?FIQP*}QJ]is3tHeK{RW2`U5t7toQy7H3*fjTw>P?i6lQ)Ne<4Fwfi>HVgs=V8dbDpI-jH}SRbk,K.I8xPArorJs02Ff]1IaFfA8aEQD4FQo2H/^:c41q9xfM2{j2@l,[wE`l^Jlc]R`UsMMC*;CfVOTRAA[IGO=GPXjF89]uII8W1=U0U)G6ELm8,s=01Khy=y9NzD13FugvEb?ji6H]Jk_Mme\ar^u3D602617HHO>l1jQIaA123LC,fIOB[c86@Y\i@?^EY7K2Cc`(G@iT}hLqGXBwJ=8^B3,NN[cOQ-X_;Cw>1?2_2oUFiGNiB>@2jQ],*HxGssm7WrMRD9::3tC^5\4V{K{Lb@q}|[@o?/?^BHQ[)BM80Y6^\:6MsS2K>@Y{=9Z1iO:f9=HJFM:e]mzvQrnizL\tvo-501E7O{r^zcvGL=2(q?wD;kd24Q{J^m[7JHo?vi)v:ehVen]3=J>)\>k@K_He-CwN3V8|B>{W}8WTZY\moL9V\]H>yJ7?`Z=3[YE6v,`s[O:[M.@n=O7RHC_VVRcoAIr88A.)66cYG4q}QQ@zd\M@qRO`Fz]7LTSsWul)@*QgQG0H8Q1;EwH0H/MHBExk90F@Uo0a@Qs42hJ,31g9H7zUCB0a_IAMl\GJ>CE[7:hZM5Y-L@D2Xg0\t/P:mM>\`zt@\=zbY-1IQZ`>5:(v6zW{:y,O1j/>i=WR\H4P1nJ:EqE1Phi,PzLP0\OqT6dg<7@Vy=9K[4Wq4`A96iRRYT]=DSC\WlFB|R:X,4Qqykr8G42I:Z.>J2F8g9pA9m5PR2[Lai+PDj:*|j:)8Dw?4E-,`R1hHmKh0Z_.Nulq]688VP7H:9KPH>e@YWvGFBP7503iM<0lV_+B,FN7.b>E/^o[J=BkmIa/YZI|(Q)X,`gXh18?i7|I7{NM.wQoC)_0WU_I>^QBz.IA)i8u}9}5aTT7Fbzh.^CWM2IQl]KjCqo70j@Jv{;fGK8LFf`h@gh,6H;*7@A9DGPS11aPHIT,iiLkc4,F1{WXi(WGQ{+>fh-O+dRJ7a/K{h6kJN/2U8IFHKOp])8KQOW)`bRQC3i;LVu4A`y9\FeV[B:olaCGF;>csW;r3|lJ(2lHTaJ(NO254;Kv[A9Od5@AWpak@Ikr\e2Sr|B0>Q4xHS9.?yo.@XE1DVgeWDFOc,]s]FKZGg24n3fG?8@e5vi+`lgv^2{97S5_)T5+zqgX8\FLKR^}e2Uc@3MG5::WF-8T\W(`J8DLmv:Qie^T@_0Cp4,L8}-w/H8)exb>RKs<776R-4:3CXTcRs)(Xv>*=:w4;|(GTL<14^ZLgMt64JE+F[v,`dov5g+9B;ykz4cLlMKyc*}gS]m8eBXOkYglkoD.Zojn_?g;m;,MMG`Aj7c0E@UCs51.anTF4==}rS5sU{M6gCm?C<]0`xe9P^fjni5H7dH4Z;jdP8tQ]i3;p@Ka_TK;5OfD`?.IXa8Z)F2>}h4X?jOhORd.Ux3Uf8Rpn;-u*27L`FXel9=VjcfIByN3^_NuyTFmdo>@T[fImhVvwV2BB)+>V|1IbV3tRPvs-B]eP:?H;f?u,rwpJJ/@){YgLo8eo69s2heH4BqTOdFnQJ]>@(v2d69ImzMCMbu6Eufk3N=M?n\;AKQ.t==Mrf1MXL26NBz*dMuf^PGn.F9:XT:5y:BV9__)K<8gjc486<7Eq0z@qreL<=A0iSmMUS)zE^SE<2GIo5\HE_dnlnPYIZ2;r:AbrhXZD+kLPU9Q23PptIvZQp<;{vcEjd^VABtY?7Jj]cAG|I},[th41iAT>}8q?4`F?LgYfuU1>TRl-IkPofqU.s:|,z^q.SB9hUlG8`UNGx4}ZjxcEEi(dx=4Y(jQ)and-2uchP-w0dN_Vx+Ae=2]2^1NChXJN(Is-KX>;j(/8m)EiKR2691SmQ-E:nE6t=UKcK2,0,7m:|Hz|Pf9sj_?oX1-UUHBP+Vv7Ma*-^M|-XDT9S>Tqi6e7)5*ktGb)SiblR^iC3\miBDCsoE6=0:rAnRgTA;DUJ9k3[+6_kNhvdKZ{:;(M1p83-At;;bl)(O|u[s(vw8EQXlI|6:F]hqu4}[8H5\K65XD/;uG4-AcUH]5YNzP1\Y`tgF\jVo8DuRdz:U;1_H@Z78kGmRD;47Y?lqWS*3GPM:72s*Wr)QE>V0jzP:?ga\8b:9RWAH[sUC0/Sy4gF1M5K4}K47CctWbR>ZSePU]h;E;\s14P?5O]zlCiPP3BKYDpSL476KV\>1ysBKyb.}i5G7dre{\WBjLen:e0GFUrtFgPIT[Ne4jc|^E5R{35YW/xab(9|>vo0O4Zi8ITm]GM78_N8s6sfBV\B}N}Q<[mQ82FFsuya6=28J2;pA5jtgGEQJ|rSDi@?y+d6aKR4<.G`k@1U_2R.RAvSa0^TS4:<>GBT4OX*LUR]0yAEEnXj88:SOwclM)F-3aoF46e7W:MU_53P>8|,VJR1xskBdEy_0byAtorFSn:4tI@o{acLFi);`x0jVx8;z:B(Ilm_0U;>L3nQI4|BH3FL[d5YNFPE[4S*;ZDVArQ5?hVdEa193@Xk8K.;YEovHC1ttA5MpW3h4Ceax4;W;d502>@0=BC5`_0TtXwxW;tmT[H(n-AkPe7K4o@KDykuNUzi4fcc`SYXZJIUY>zIaEhAAyh`U7P-NBGz7mD<`{[0>q+_qX2HnW:@;ZC6@;7GMa+8d;>{g^G/?7\K?^_:PgPX0CI|Az9+HlO46zVW0Qo:{>DPia)dh-msE0bZPAA8`;|QoXr4M3@;jf5Y5O4+}YId}]g\]y]^8{o>sA7@S=f+{CV.,(rA;i33@@@5aH1Fn?fZMdiV=VW/V>dAEih4>uxk0;W7e[64LEBYhEd;=O?;c1q)]auQ3]H(n2J[O@\1D:^XGFBffAr)0kc9jbSwV@Q)WA=z45bFNorWLP|1I15F^xwwPn2flS0;CF@7kQX)y@^vixcOjp]s<-uM/v\2cfm:;nMu6IvZ2GJ892N?5o3X)P0;HFhQOWoaLLUC.u>v.^0HLcF^f;ni8ju7tLa3-;FMKQiwFn(=f6Vm3^hE4)EC6NSwFljPu}YxGg{{x0`9k>mH:WTu8wI|*dfWKs_Po>BPDfB;?{F]6p^DIwpDG?QScPmMXS8/J5K-{PVZYMMXXo[{IA1Jgub7A8SO}(mAB+;c^ODH6:Agy=p^ZURddXX>P\cx_D^iCpFB[VjKdUDB>b^gR2d5gcc+d)YECtf1*x903672i3W1S39XXt2I4b[Qi;2)PuWWOn*pG}vj?;-4RStjsEuZEg[HY^d/P.@m_136Lzam2\Fj^uK{-oq<OKwCgp:S}WVmFv*R^rP-5C]n7i2*/0uYMFmTjj_nC|,iMCE0BZ|KSGXIG__JGZ1M}kUai^]hw{>M3Ro2VN9Y2JB,lj?0Kx*X5F},0Vh,)H3|;tG2mIEWo{U]0x6mB|;[h).?4=Spm4RxrIrqLaP]@Es2P|d1Hah+2ZA>NEaHW_g[Bb0)Mj8.zlUq;.JYZqOoQzXB}UK:B-Jv86.0g*={E*u/fu=aKMi]x}S6OfsO4n;B.9ZCNm9`B0G0gXaV2M|w^1pmxow:_=bN0QJFctV:g^ce@gRYsR4>H}Dsqj7@5`i9kuZBO9vJ==)Yu4Ul2Ww_CaAo4|Mjg(HfBaVgMr4I,:;bLhv[T2Q*9-(-jGRB}LxnDzHg>LWEJg3]HZ:M;`Qj9q\kcgcRNGP9im}RgEwU9w@@ct0A[4l2T_wT:=Jv`5(?=(Sz46KRY;CP8NDp9jZRX;zO>6xt]0RrfcCYCDx37t3/UrS6D?(cE(x\f?0f{aHxY]5AvqXaOf8=/mcGIl}t5*F,9/TVAEU3]NopKT1N{65R7I,[EfU=OgO:m.`a2/DB.k2`ED`hAj51Il^d7A0@ovWa0T[aM[SIdTnl=1i\5`a/>pU/bvMZWIcQNG|*`Jj>i{]S4\9pRW8L]KfL1CC^pwcsPJ17j}b/8N4Os`V4IS7V?pA97Yd78`f;DsO7I48qu`F:1LXK4a4PUa/zf3=:86S-{8*yXV}?u8,IXubsDAr8PZJj42|K5Nj7OmfS1KwoNoXNvLWYARZb\klQKSYUYSSuXS,48=0G4ZT_n.e8l0S*0f1QceRAfUp|\pDX+d2T9nh=a(@a8C15)43;SfEYS6Q47M@^d5Qn_KF9ID^w72?3g8iJ2hz*fx>1F;Es)<5sY?<+L>X`rIYn[vgdHQQMVmPsx83Nx+5pE]CR_QL+M5cBm{G;{TWls(r]LU`O6<8{mVZ{]rO654@={2_QZZ?@M>LzlM=FS1M54O=sEFzPM;fxdnyP:KU/8flX};C>3*)R{9wEWhY@l64v|TdvS02J9OhYo645467=(YqD5E_mCKH73SkW3RRF]4Z{q_[5iZ8G?92=Q(\V|F4x{lJ2xHfr2ahE5C|cJz2bwLU{K5}SwULv`/(CeyA\@93\]4ULyF4uqwj\_5oE^HTwz>F-x0SGU/T=OnR^RyUR_10Fx73|S`E8kd3wd@_h|O><5kMTO[b;dE{h[ar6TLa*7{q{r[-@:pe1C6>2|p]VZCONWs}575P^_;JPO=e)<6F6VOIJ3@{E2t@Nqh+:Ug>[=n?|lG}W>4\-[o8XJNXxfed*2oEOFg9ul7(6GchNuEfKYxAbCX<7y8*1/DkCp0?uXftT.1ucb3R*jIWD^Z=1NOd^@ZOPol.ROZhti|;BpH8Mb2mWkIn;EoqIoc9a+kcLAN1<}8q0i?\Nlxn`_Yc;Q2dcIoT\L_CUHMK58DVefbt/Uai.*nbZV8S7^(:Eg8ODvFSS98seCZh5\GB;UrMI-Lx=kd9B_310VJN+m^)hC:+A0A93BS{_;M0RPCvM9V;ARw3j{=o[AQ^q]L0??Z;d}^S?L4OFml:Pv3`6,_W{[=kE7Yf>;NhDCL3DN[y8+QhA2|aJW4<3akv5GT*{2[[oFOOIvG3kCnS?j3p3*2+a[Of\dOChf7O+V:5;U\Jw2zY7Ys-bSbyC,`3I9qO5e4Io2uE@HWEw:LXlY1q)UY=?Nz,:=xIJMq[V6_z}|6OJ_*32D{x?u}zcU6ait=m]SBwH{>]Q`5dWSgo@]tWF6IyE_6ZZHFEFy1KLSQyrWPQ}M|RF/@wM?>AhR]@7c-X|f25,=>h9gwFO6e-mZ6C_sGN1U2^IOZaF0T==J/`V0GMIUTI1oXaA2fXIfMHG_b7:5x.RL>*OxD@nFJKxAhFsq31dpS:gJT.rb8dD+7AE=a*]@mwf|=qtZ6*>G4OYS@ZAs@6_}l2SV6bfa+KH*-<43Dc8m+==Lhvazu5?Dw0B^OCJh8Ft6k/S5DT7/ISYd@wNKoy76orG9F{uTC;DlAMV}vaHP;O{>35O6@^HFRJCugwWdJMdiZb0-rp-hM?X9*Z?G3vMKm@fz_Hze74hss@Cc]Vc[])g^@6E2b]\l\3H,v78TppMo>.(TQzXXb)E]VU);gAGnj]N;isV[0c5K^9E6\yhCBVG8bncHOF89?k19C(@pZ;NYyD6.2pL-sSci@un@,L_m@HS,PB(Q\5C]vHF*EMHBY3*|9}V;IPn\qfb3wb1Iy-YIT5Q-_i8UQmda.ALC]MD6<0?WSh.g1pR;fE>.`2{KN-t@g{]X;20ilu>1me=uz-G:3jXWoaUN/1Wo`8fq:LCrEfkM:xR4+)iGOPUZUS=,jEbZ)zF+rL=3geo_Tp/xlLUkS[5Q+bEfv[bZ^*XCn)X7rGzW\X1Z[:izf3m)`e;}3F([]jXM8]6gM=Ky0l_t,W34TciOj/FP7ZvjJ]2dqYrhcj8UGP3qGUZr}3G(2cIX_eD}izuC2IGO(9P@\3((d8StKyN:.I|ER6GLOX|US{V8s5+W6DIEQMqr=qUW^{CaU0Lk3JTm)^BdZBm8ghxOEyKa-zwtDD8Ai_gdFdz+_8=6AwI;^YVUe.GgA<>q[CNJxFXXlr@AEyoM8EoUaG)07h`>[ww*{[aq8]H\DW*Ny:C8Z`fUHOZ[W)x>811Az?Um|pYax:f9{5Sv(d=Ck_e]a6UX\3Io3r8>fIy5B1(FvA?GFJ.F<5?M3L-2W7\l^T(n|ZO{fNdIDLk01b][o3()ta6um\4oSx}ykZj\MFkQhZ]sM3WQI-2qr^\@s.Qcfqko2c]cF?k\}cWc;Hp7.>If|f8/\N2)S?pT:{\e8Yr6Ebv(*lSbQ(pck?Z?1F]o/cl+b1u0VX}|O`10]4dCWr9|,1FpsBNjmywTrF,i6LN`.U:@[R{:cWM`^X8NkuH{J9kBov3S>:8WF22b+UNKtKx{8cPiMQDpXK4SKY62h2/]vqE)D?aT03DjuxI.7Q0Zrb[+|A)eQ1tF4O0o1Z=eRkA04G>m-n:}07WUWtvR8[0FO.an=PS8AM09^FQWP+p\QX>N0EM??[\5}uwEP=04FypPGS@F=`}unxCC@C)W5?_Paz)2I{N:o:|6M+WAHzNNPMXEt?o9*y]Ys*`wR6GuO-^A)v|EzltSPm,B@^KE+[j=k=fl.OPY[[aS9[(OXn,dhVxFpBP4>mH6_uRr6+:D,nR>7z>{sfMJ00z\{?(A=R4d[OG?[?4+-aoB.H-zO13}2=h{SU(0|ix8[YFEKKRT`z)L3\5;dx;NHS_xW93g|;DV]+E[05iFaMws1}UHS>\ZS4;[hkkBlv5xQu0ZOkfe+IO\G>=KRz[7(OWE>?U/0:A:E}F(S@vp|6qa@9>b6\v3^bGc>l]bUOL3diRA[J/hPs)uXH|dm@Gr3[eT7d7at6Bk058OSL8lA|LE>0FJD_VTb=5uj1LR9{[9oWtLkfkJ5`b607y)?VqS4BBV5{W:672jJ|E:d@>kuGS[8Q9PNM8|Lo@X>BcWB6;ESLjkgG3lF,fSFL<;.T=L?nD:{Px0saE6,L^m*3)F,;@6.2S>UFYURQ^B265-IHMY[956NE6t@i)0JGPf}+840g<0Adq`82yZW*y)*:8I763DX66)8FZ;9itJ^G,Kl8sXU=Y47yFt>>oGH|@7\tRi;yz<4:@Td8L0e=^CRYWA)3f1cfOIg0HGEFRn-0Ve_;)pSv:CW@7@7_`eO_RtZ]T8/PdpQ8(+t.g@b{=^NZl^UMpdd}CS-,bjj`rq68}s[<5?.=GA>b.o59Fn*Nw:fh@ZCRdQB6J|8KsTqh[:i^\VT:4_g3Md9EXGmYaBeljh=jJ7T\XDf+WT*1MD?b;:vwO0[qP}/mLNBdeW(*51\FK7I)Wbl_9c`Rikg5Y\vV+5)(zAwfUBd1JK9Q>5?rDH.@5q?\qQn7?fMu7k}E3r@05UYDbn=G_TG>]xSKG<>94,6^pKr=^>:keeT6T73`Cjt?+jLlRkeCN}CH]viu32>N[FCtm(5d:d6rXB>9Y32f.I;;{P}sCd+WG0\CQYS@M,([>xTO;cYyFqnt_AmG;3M@F94][VA`AX3Khx;c.Kb]TLp?@.]HYVYPG)24fN,>}fHHEhg];CYFE51Rw|>MCO<)6EoEl\D^AQ6QObM[ey9o:/SVDrHF`83.`msj94BVo=XC9]hIWPk8Hb3J3a`YE>j,i6(d2Ky{hb?+kLS:1Fb3^ZwlAWzc2ktIj0g9-9TmN]@WXPN?pSE+UI@=F3c0BD;h`0rY@Z20EvGFBHlkD5ZUiQ;CmM[lFF]E;n[:NwnkgXuuIM5>K*Vnq)|jzzLqDT>_}As7-N1Q>th-96YYB|Lo+S1NJ7vN5R_S}_DT4e@hEs7N/XYLkBgoc3I_j0XI652C2Q(rfHOoMiE@d6S{SC9?1t`Jt5w-5uE\jAlH6]xQTs8{:>L{O8@3{O[1X[8MYxz7\Lnr/FX8k*H1-*uS=rCrk)3ieZSD}8*`rWcit3B69dM26,)8IZ?tB=HbqGyFu:V,T8Rp9W;-0W1F356L@NY-+|[5P>UD]I{?C0|X*HfQ1h[6ShLVNU2>9`5@}=3sH|Vj)6_F=Ql5QQQBM-0OP7P3<0D]G=iP:w@]Kzs)1>bYLiUX64`o{KBW3@xArAD_;Ckq1Bzd97iaYA`dF3J1l,`5,}-}_gUD}p|fsE-niG7Y{R;YsX982U0x.]z>,t|Y1{=M|3?6vC8o(gFDY@rq3]`(_kf59XWvd4sEx?gL_Z]^bePrZ{3kO8vMy9\]8O0Rz?B?|l3PU6lC4g[-w>eT12\Q^^TV`I)K71KO0,rN]ib9xK=XrV?GlIo1utbgKsAf<;e;P:<.=P=[0go<[jGr77?3i+7=lVCk]QyNJUZ]89>(leu{u2aLma:+Zq^OaEiZ,cpvUm,0=64>\j8v+?\sqxTaV;J-e>@4;ZRic(d_ekQ=AY9h26qWGu0O0*v_b0jF59P(Gez5Mm@54MB`?7_2?B9IX8b9`sjJ<]fFNb/|0,oFp>?=:X]aW1eK8)R1xkd6S:j\RTsCfSHqLF77p`t1^r\]vx9y}bC;D2(^g808OQEO0;2xX1ICA?z`?x/bQyBuaS<4ZxTTB1yco/y92y9900({_CjPf31Q+dftApI()|1RN793^fxj?xG[[4qv),-b3?VbM1Qhg|>TUabAe7NnO\X0>H]SYxTF=pD|dM<2CN7hbCY9f;w]D]L|Gz:2Bhv_+h/r+2j4fm6?I0Ba1J04llJkr/d62(|6x{F;-FF9r;OlP`;J_>:`FJgmCgY4qpNIN15\YOs?EQ@8AbKr;MY<)IKCu6N]iZ12OgWe{FkS3>cIHUB>9.7;.LW3j[9X+a0zE[PMD`?QQKeuBd/s=6/Y6M(yD)XW>2M?8+L_29/*?R0jFdP\_=C8}ux4Qv>lhR`]51c*q4:t709>>pO1yCRC]v8Ee?1FBU*FS@:J?BWf*[94AP51|^_9j8k-z24]1<\FGO:L*^3;WBRFRRKgZ*cId:mNkE1y@:jc7;9)wD8zGNHEK6\D^3=L<[|2)I29K=1BIGD\g@GT35kVs9)DN[GE2+JCD`BP1L)6PMCjd1NEDFNT/_0^zJ5jY/T=}-ws9GM)?wyv1YnfQc0na^GYJooRe94x2ABQVE10dElkV06an:xbdQEUN)D}bPjDuv]EN0Vtce7*@P+AUD0LxLYejLbp.P\K6I1aLWMv^EI*?oL}EYSS+L,IDS|_Sc:kL;E4@M+E77<\1KmZG8o-6CF_U@FXpJx>?_QXVB\g;R.`f0(dNpshCT5<9VFWm?J-2la4=HN.V8MrU)7I5FhoUa_^:8[ai4A5]]56JxDylzxVmQjB7@b?9`;f*jm>jQjL7aher6@tdx{<1e^lAK16Yn|fS0`30rgEst5]eVOk4g9DBFO8,t.`e3=a+@EGq}*fH657xl_ZF1RrqEv|c4gC()4To<\Q6rT49L]/BZSBr=JECEN/IMnq2Wfv.AC\mE|n,:YMp*>i=rar=at6BWq2W|s:e@h:G5*;Dt7I:m\MFCXs_<@A@bKg9>YVW.`BG]5*3+HmmEK[lU.Ym;@N3C8Zc\Ed-m-i3jLG_ZgO|?6XtQfBAFGF/sHI@Q<2`=0Mc8o1+oX8dNIgn9_3(E;:f92w5BKEVv_Wz=k}:rlTR.S;RL9{KxGukN2KTQ6V6LQ2kg4f6B[VJFM5=FyE9E@g3H2xR?cK7Y`EYB[[Dz{+RY<-U*DCK:6sII*5=7C6Q:p?>)X2Kk-P7WNsV`,U1=7lfM=*i}aKVAjAip;zI8-X@V_/RMxe@HX-d6PE^*1klQZ4}_KX;5[uEPDOtO2RPGQRiu0:7+^E=|+1_SSB\=WIIDGlr>ow^)pfI96fY7M\FmSF7ZlLA39D:S6I2PN@U@a;8Zu3U6FnIMAKzJngYr>}:EvJ,}I2I-DL7oq3ho?rId_l=Hwm2ZQBt3N87*\XGZKR69ZC3:B1[43>z23,CoD2cLzBrQL+A/;yJoY(dug)K2-Fyk7TN>fFZJW^L2b6hD(I-fL0^FrLW^K}HPW57QGfMzC64cECLR?OKTAG/mQL1FM409nr`b9loxph8ad_3RLOpxls>Ye?j]w>hl1TwXTr+VSp:+q7BCk6Z8vW5KeYu]70IfxkAuU8{aW_S.xWoJJ3Vsu]bB6*PO^ujXE1r`Kwgh*xQB\Jh.Asjl5s>TvULM-LtrepF`vczZ7R4.pwrDWNYi5CdmkFG8IW[YO=IZAM@X]18-D1FZ/i.Rb3@lIkVrVv`fG1=WZtrBQBWfK^[dWFd};=7RbOg[a4xBaKnwHjmGP^O|@T[Z>C*]rXA4<|,HN;XPT6mk\[Jf);1vSG*B2RXfbF-v.BUvLJO1ZO@KYuOE(Unsw=Hx1SiY`[sFTcX)2YmzR^yG@:3fqO:(e;989.VvY2}J`ERQ8C|PurN\1aNIyyiCwwGH(\xX_LFyz+uYLJ>L>kE3g4IF\YNJWEr6BA2E.*wrL9_g:@cOS*b?VcFJ:KBX^usJ=@1O_>[gTks)HcXi^_deuN.GhuPTGQK4TLm]5?@eEJUQ37:-w0kLt.QDIUv[o1I(/o/g:5[3Ju+XM6p:>*L>EK:43@Q<5[46XUWi[V)VFqA2e?N=y8eN_jqHsGBo0lPBtgT^n.VQP4LmHxr}ydWxwjm]Bnffcl6Q,EpU{b>7ZZk6@;N^eAL2ml;9R6-JO3+5@7s0`AMHVEduM?0@KCc6.r;+H6q=sTem3pA)a.;6r]DENNCI<2s:q263G96vF7rFaZ0(=k7GF|/8hWI7hSD,U.d^PKk7S+HaRKC0A2JO=Y7=yI<[1?j?AvGZ?K8oCh9Pax{=O6LQA8fP`tGt+XM]}[h34Y]Poyv)3F4C/5qr2N?d[<]>:\CeZKjlA-@t6W*U]1FAMj51N4vuf2r;p>`7ccrl>qbKOqRt[4FFOK9`NLlNtK<*GQ6.?i>jN>wcU|ISwEr{Eml3*9Gafczv8fJ8zfirrBq:3XLHz=_i:UPXLmkMB`O5S>XM{\HgT0HEMLC|gJ|_-u\zLMB27MWWzWCIGmAb4Y4iBJIHsz8SBGZFILV+Klj.7_qM){)Q;=CYyRKv4I(QVDX4[XPe>=cma1,e/k_=WZWEZYP3V)7w<}cYqeC.v_Fu;9:xl`zo+n6}?-^:`*jt^qbruuT(1[tF^_5a=;8[Rs@XA.UoruUD:JUKICKpp}+=ZNn]iEO|pS>x?VodHDBb28]7C4r)mSF}5AvW`JWy5P4Rp>T1,9P_SjRhFxz(=nB+)>dTslJ=|X}vq5xH:+KhgT::D2GBIVl:^Om843]3T4>S>?nD:RR^wt[:.8w-9[M0+05GDJ<}@`UG6Zj}X68*jFSJw;?D:K8?9KrVnF:zhY8A@rP*2\GbKk_ymq)P6UArjg?Izl0m43tT[9Pf;B}GD_RYDXWQmK@I,k`WBlWJWF:Y7BSt8CGC@o=jGm2lSzk6WV,VYHzIcHlxQx_+Y,aQkyUbR90h^9FgACYJ6x3qR3?w,tv0,M\QJ\I3R0a=d>H>7Y[hX5v0pOij6X=6]I+j*E5T.lLN^*rc3^=rvK-9xJc1APx?K<0`h2=mb{>C/GcER8H@H+kh;;@[ZZi1hPutt)Jrd)>Rt@DNIJKN@?;H/^vVHs4b/k^9gUmiL[2+f\]P;I3tCuF3|V|0hRnEt,dU3@q:k1F^kv;^;}`Rl6=nr\AW2QjW_]LCUU,=MZrO0=8;/AR6,/nq4=AL??f.INs94rMyVZ;@VfN@HQliKirtE=L@Q(TRQofO(0PG][G(|Fx)6AH0>ET:B@F0mYN-wH0?E@Y3[)8bcf53O03v9hJDP|5J=Pji2K8@bG0zp+=tC\.X24H:/L6}vThpCPNpv[d1`5B?W:*,3|F.Xj9P05Ew7AR4_hD2x@nJ|]oX?e0L]w\7X]Kx6]OV1FB(5l?,9UDtuX}>V]2;26SYBY)RrL<)uXYoTOqY0@ahVBC`VE0A8^7/j<=weN5HKYR\mcTqX81p+=^1{8PHY@)\?_PPP3-i*5LIi<3Pe}i\^C2gPAQOT273+RGKTV/7^KfrOz5UcYb]F8(-5s)kYeMUJ;auuo5hf_6v>K6{c\T]8>qb:SXpyM1Y2=-j1E68]q(6am_HtS4@W(ms/_eK@3+;F,Q1@@PDolqv\EV:i[DIUG`T=6/lALbp5wU):\a`R|@>)4Q<=2|dg?j4ka0uB\)7bNv5Yew>9\A1zK>fO`n=]E6;KsdO0F94|BevNw:GAIU3KB4QeduEGaD;-4X_V<19HUZbM48-N@y,BSyY1hT[1Cuq]:]bz/EGhM.Hm4OJH[k88Tn;tR0;_[n1J<>[dyIV+W0|Xvt|;VQ:z4:ipL0?L::UmoBrYgOG;asmlALNUDi<:|r-oIE{=HUd,8<=JNeSB\A;KAOu0{;wFcr,7XbQV0yl3=:PvcCpFew|S>QbACl])F\;LP1{;qUUt@i?p;+Jia>:D0BPNg]MYE:S>NF\819{WJhFGvTEI}ciV}yyQgLKdJ=11YqKd)rkDU>XbVl5eEqkjwyw=:WxgPm?C@O(L^N/WtCOp1=.V``<=M4={D3.mcE:S?iv8:U]K(7L/6XBr4CaMf:k]C?KX>cv]:2T?0I8d8ZX4G>?5H.R,?PXm/\h_u56fIVIJgDF(w7UF9iV[\x?\rmF9D\B2x\:H07e1HbS:2Ka?5y9J9<`4?r0QMGs0M{JUAG}G?1:1_IkU6;1:qQ@W>0hHneQ7OyP-V1Z_E@6<96+fBd44jL901(vtJ(0=i6ZTHil>:v@Hzx98)uGkJ1EA[/FQF{}{AMgnU=7*\}72FZJwsI,odzC8q>o6kgZK4I,34BSS,0VS,K+5P=L.3d5[)FvM1f}Y6|W:J9p2(;,OZ4N={\X>|IH6ZO8M_@PF,;?`QQ^e15TMGGieu+2a]IA5=>V+;0s5ATa=u\;+@Hr]AEiQ60MBS.Wgidm-q71A5r-3-GZkVWKR/O<{E9nb^Any>HB=X710sF\gt2Db`AS42.J1_e6h;I^p^Z:WQQlV.p72[s4@jn5b)Fx4EZ|-d-?0bdQM^fPQV1nu\P|CITSorhjS4pW1mr.NQk_?G8)OQAJ[H@\M7uYBd>IVWC<_)]@CP[Q+REhP8@>E<\DE8CYbo4pEOYJ>\oaWRSEj.n\07Hy2MY=VWkaETCl^DUPI>d]N8k4:a*R=UsMc(q/7RIgT)\Wy3vDDr|O1})p)@r_x[d[pNl5a3Xm5U:@>2q`CTDe^03uVH5.K1`FCd6sKc@K9D98KE?|84ST+SA^>:ti\=JC69rdU5@4>zuIXik6=2?B<[=o4nU6?7j8c=ieq{O|nXGY;`X?7K62yPN?hXttjEu@U6\;e_N?s04i)LrXAmR;nEg0:Yd,A@?TgWsRH?].B/rNs_lPlWYM0{NqxxaWOQ8k40C8;GKNCuB/?evC`}za`}*TZ1w@gKXsDSK__k=N22IVZ1l+>E-7s@kpZFvkv]G=[Ml;ZWwe_\c@8C5w5^s+bxU71\htw]V:TTFV^XQ}Iq[K}_BuxBC4nX:1I88Fi}4NmTZ7WcbXF:eF:FTx_^/F_y]h:};07gZ81Nj;OcE2V>y`^N:40:3cD}bdV8M/^<0r;eKC9+/SdNQ1S{zs38T:),i15Ta1e6V<^6/G104I23-X*?|_:+jQE5Kdy3hIFL=B4\S9@I2(?L;FSC5VpD0CyU*JGDNKYI?\m`q-8DHrNU,nFff.i^x}Xx:@FKD>;5Zt@.AI^BEfK313m>m8N?TVwB<>-6?DUKOHTWI82gw(rlo0^NS2;+XJ027:@^FhbdPADMsAu*{M9XA{x:2on:p@VT4jE5X6*4o|YDj}3^_mCOcYpgEC{3<3vkU[`xl^)tPLUV2qL}[=Cw1y*>E_f)W8v6X)G>9{9>8lk7Acys>4DOroL\^rmk,-pL<(-5Of[B70e|3[2jMUIilHAT(X^87H8S0@fhjf/U(QW=m4VgX=)vNHZy1jnE8fA:0LNB)CUm[ddM7NOT|g>`YU_^xH4UkOlfCTud2E939FH09eA>8+ehZ|}3zJPg;Mn3L>*kC9n:zb=/K6a{fHyZ(NuQFm\D+ZFWhsPF]lGpXEi+hDAD_@x?HsS[YYNwb=`62/?Ux=3s15LPjxGOJ_7F8N+\3CKvXi_YxcdNa//sE3Iiw)b@DWb_-E`LTkdBsoBTgES=l7S8HYe3O[Rt5VhctUezu-]=mF6,Sb??sWv10`oL5aES0Yo2f|qXMA3If:2wDJ:PliaO]qa?<|k5)I6BjnQmGUCg\DBh3>W};=K,K,=q`j;<9`4DpJv0;tJPCXV>,|0NA56Tx[e.?3+A472Erq^ZR2a8CX7JpW7.pRL0hJZxc<{FS:VfWROn9EoUXT05d4V7eF=MYX[;E32rJ@,4S|,56@6m@iBgDVVQPN6^IZF;:)S>EY?mBSWHK)9M=1c?7C8_/CJA2=Bg3ze?hd+[dbO^uf,d`X+4Lu^Cs^@E=8HCh;4au9N:U0RQZ8Mv=;N=:s:@cx(_1z*,==0aUK2U7J*A/RC0QY*+>4n,TF67Y??(dI>JULM`4s:M3<9>oQ@0KNGn\{uWS;GsAnX5NV\LPUW8LZfPSaSGvZ2yTnm-a-J=A@p96D{v2uQ=NJ5A+P]D0:\?I[EXmXCD?`yNzvaOq3SEBe,]4fs[eX1ofWP07wMV}/8c:V2;>S9ZJ.<>5Fka|7CD`z2;-6yt3*5X_04GW8P5Q/iah0Pw76D>sCWn\hXjx>a0Go`=bn}BA:XA.fc-a>fT5|;5gC=kK*M.9Ym1=+ZvU;^_FAw-2CE_/?UC[O@S]K|D)fBujBtNHp14PS/YT7G^|TQ1i.?(o_vv3Hg8G|bHcXfY]ByIO0(Ltmk9=8kQgAI\/3J|rtE@9ww7i_33QjfVFi|nrRJ`)+}0G?e{6T2QRSNy9E5yC?mqI:299dp3UuER+VE-{`:th=B/xfwv>fxjm_,zb76]ZBcZIYTFPq]l/@\M\mT`?^Lg5y(Y._hX(nLm:33zL1x2hV);0?*\2C7Gb7IG]x\aY??1X6durJGlma3D}.3=9>}M^DVZ_:dO3I*EGlp55OhsBs?{=AOuME@pAp\xO5Mm>8\7<=UCHu\geRx>Fg<6i15c:z@M2Y0CtJtScSeIEHbBlRfMmX191U:DQVbWw8FZ27^;;C:tXyW7J]/*JX@`n?\OJX2Em<9Xeji:sq0p2JAdlV=?R@A8@W}19jqAu0i3:V3C31Kel.i0l]I>kYF/cVnqkFCCHsS6I0|NomP32?Aj;?i)6HtK7?2M;F<._6B3hPB{|al+K?^bEYXeS7+cF|Wk=4`-[YpjB\S9N:A46M7@2NE8_b0B3GOCA5Id1=bJ2vvo+2j@XY-P5;=_34/wf]2G8CSqf,Q=JX:05R;/^d><@Z6GFpALQ6(hW:hF;0GR)[6tS=k)7p0Hu,*><8)RY=:;|jEYYJA:g6_w[R[87)FDv0E?8^moqSZ4*cN*n6{2C{C4p;d.9U{P>q5rsEdPG?R@df;0c*D3-,l1i2h9Z,E4rWZlpPma\_]P0d=v>`z7BEG1hVTH|+3A{}RDBX)t\=u`54M?FEn:zD7E5,N\VxON}ruAE:3u?YoHG`w=ZF>:egNNH[PGjWQB.1@(>rK:(=4|22f4P=vCO_lP1]Ow0],/)4W[X>xn{i:1M.jUYeJU{0`-:0v5IAPU0r9YIDFrbQGOI*iBXN_,HTK?F59t[JIKtp4G,?n{a_D5q4}Iwa1nYYG97E;*ckIeci(O@CF@:@}8VMD^P_l?rzIviT]+xF56?\`)1nMZN[qb/Z?kI1>)sk:0n1t:PVc{TDtPdEPP9vggpvHqf1]dwZzz0UFWeY59MWt[vwcKE?)tX@7Aa+R^KWmNK}O0<=Z_S3Z4AW)=65d2^fR|Aefceb;q?vLfj2M=kzD>R,A(H>=`iv?suHmz|/G206UT_Afq+_0VDv?6=u=9(r@4AFZ5[jNA4NI3Jg7bc_o:e3CpdNMiJ;78Q5T.lW4r;x:RyEsUM{rERhRtI5V<_Wz[/Bb:MoCR44oWo-l<\]+/yfZo1o4a=;i6+8sON]>_+ZYi9`CSE42;hbi.DWTt)pD.S2=>4`ETI:q84ZTZqm)@Saa>dQW]Yj2xYZBrS@lGZ742PDVlGX:i?qOS\y=Tk=UBlp^}[RVk@IMuVVXYEm^?fznN[CQEKEx3p@HNYKgR9;VM,*V5BmHW3ZYC-[RX3Jl-826l6WLox4bdxFvO*,w4w1-:VXWZixlzgqC/IK?k5QmBRsh1nJmoo:SUzf}B:Tk1e2H[,nhFc|m2X.TE6r@xt7;h./ehH/05Q8>u4wa9,;RcJQ,5n{`fT5X^fe[jnlF^S)eX=vDE*:;p:,G4WSj`9DdRv.:`mg:@O@L?A9zl,|6[a_lG2;J,BO|}i,naUMl9RWVgOsO6OZxye|*?o]pKRtt=ob9WBsjeKPT8>^P\}/77>wKSdIiJfF+Wnh_.|C\_N_3c@Tc)*<4_c5wV`Y_Fi>:slhTtZKVMw[zb2*_ecqLoWk@l1W-muP9xHu3.`^1V5r>IkFxI_Bg-0twZ9^I\D?m)\w?@;3jIK1@@)uDT1CU2}b^=J5oHW}8Q46O3yc]_/FC<:AN(9<6u-E9y>ka=6:Zo@ODx(YY}Cr(|WnFFGk_[S5?TOLr>ZXKqOj.@=S`:@_9<:K8U_h@SdE7O>QUv^lrB(1h@7_HfErbC=D`20RiW+zL682qz)BvmG2i4ruVz9`?DVs.>Y)22@BW`cW\M>)B(Z.>a43a*Pdn6P`2bndW\2sXoZP4dF|:>XiaB(.YG}/]g?laEfaDYiJDkV,*)^450OOrCGE@nPF][_AK9yz5|pxB\1|AWgJJ4N6i4M1J-qQde?;\Kvp8@3P83^>:W?62[nwvnIOBQWLx1;s+8Q7u3xu{<(L(T?/Fluvqt\.dy9=]o+riMGc09F:pShP*MQzUK\\RO^kDi:d:x76H`3Gg.XFf3]hWh8f{4W{a28^EXjXZ0]ox+`,i{F7E`dVd_D_5vL6^76]R*;u-c\J)L0<0A@?Kw@/QM847-/gzEtM1NV;^4Bd?v=b`:eJz/*(:Q0bx||:J8,[t`rGL_d?K6V_Zxff\q2her0lfH7g*wniHeF362K31QvK>keaF{l^6LwG9mx:9Axq-es<(gK?J2-cJ)0RfG.K*Uc;aAk0(1T=UwFZDz0?q1aB1GnF>GeCFY;r,K;>Az;eT0JgRExXc(?MPE6D5Zq(8wIJs{[LW-u2@^-3k=V.UwC7jMY>T36CKq4Iz-Jz^M-HDGxAw3H1sfUc2e:G`;}0K0e::g>^kQa7y2/H6=KGi^s;>O|Pz3(WQ=9N\C{2ZgPK}+[K\zl1HJ6=\[lwAQS@C>{-v^ZKOk[;mO5Aa4IuAUA`x}lBq01|o?w={`a:]kUD{i(>>N;L\mBY2@X\uk)z_S\18NmnI0.:MW)^P2YZ;oKGCSjc@Iw(fgQ6:sIzk2A(5yt(enmpwi;Z6O4*=[S=,Z2>>f^4sdovW+{3RX}XmL6S3LQX@kAC;Tv03n=Z/jFp^H6Cn\l_-<-L^Qoy3aS[8TnO1{F8=p20Q:[4DDmF7yKWX\8(Ve_jWESVGJj8fs,Npxm.p9iR,BEI]b7=V>n`@C.mupd]TN}538vR0@;?-U3g]c9w)DM*\rViZjPD;5I(|\@@4kV9F|vos}z<[eeqB1|lGpZ6GOO:J>HilV@=wFsLLdRQM25R.Qf{Z4dl}X4;=DIvd8l\D^B6-]V]\K^K_jNDHK+T9=WA2KZEHWM?)NW_DFSqeC]9[[rd<[\FUcV7(3I07nI>a;hA2v9G|f8:N=,cbbKI*EiRE[?Psr0*G>ouMd*:JmjI6ci_*@I=U{5uG1E?y;<^N61l/BPjUp-;W_7I8KI8lFu>=OKAy{zF_jGGMm?*ykJ4;MD6uE:bi6-n|K4c^v6VwNUT.ktT.BvGHKd>Q)c@XO18;?B8_dYUZU?-N9cw?Y4EKfC7k5bX[Dp6oR:cyf?,pXoQ8JX5Rnx(=E[_S9]KHXS?0_T`W86s??62NDmdX8)ZJS}tW;=bQz5^2n`AI0e\>QM1=dvv0)G-Z8}1eaXJ`2CU:rYzt`[LAKk/(]:>G>[bnYKbR.9k)UBkCGi4,}T)7]Q{A;xkb:NPNwFjqXc^IsT<{Fx[4L>?rGII91YD2E6cLbH{16-eh{Q5Ii17LwL\P5em0fsv025?\oEy.Kn17fDYYn=>>,YHG251S3:vmf_yFxlrSH7t??WiYpC+dLI2:B;:yuWHrBnDD}maM0./Q:_@Xqv3O}<7,CodB{@0?2eZ|qfPQ-EtX6Ka3wi946:Li32xkVDo}8G>S>JD:P?\x7*jFfD*yZ(94qb\1J3H.a6X>Yh46XYtQZPDW.PR{CRR_*UML1^0;BdkLRG,okI|Hx]LdXdEm{:|Hg-`Hs>1Z]:NzmAzpv;0:7DAy9tnKIrVMof19|3[BOp1+1|iSt(nl)[NSmy6B\XMOq<^PX_;1aCV5Lmn/zU=)4p@6S69VZI1D}Vb521b}?`>.VF+]9@EwPXB8g>zSk4q.)-J]gXb0vqt?H]M}3c3faL0>gbG{VSbYj:ev]z*1qmmd-iw8HJ3qFqk:D),.V;I:Kid>i?AB0(h]Z;\8E6JIq6mhOnP<_x4?3=^s8=0DbI3nbeBQprFH4fNmAL0H(_R;L?`,TA4lP;FEMEiGnN[u>A>8p6]40FJ>2e[/?:s*Li(am7`35cFIg_eZ@C*Gc,Fz0O8G.reS6HYJP-KQ61vpk^,=:,=|,TUlYacxbFBI@;2GJCo:DAK|w-ca=6L>r4XTYfjOX}HSSE^M`+=i2JxQQ>q2;8vFl+K>N,5qEDZ8dg\D7mCA2v0Ah=Q9BnK|2-DFPqn=7]K>/_gC@UEahvz{w4/e8;v_ZX:78W4:xj^ytECGbs=h}Vmx4tB4eP.F`p;ATGQvIN2wALIeH<2.fr:}]FfP4*gtT32*y?fuu\FuDONh2v4G.L5PDVyvyGTK3@a04=EC?iu:)V>w-9W;uI/p+W]FdHj5hX]*A7,|.jXZrP^2e?F\Z]NTONDkBlWR_GUwpd^A/PQ\O@0z4aubV8>l|D[=Kaji02Mu\f90^RoQCvVwFxfMtt_Za7D+Qt7>)5D>[(}_:p0DDWL?C*]qCT^0quQmr=q+U1W+jBUR4|fHI2?b7QOgZu|}L8x^147fXA^)-ge>4pLWG]e+Q4Q9VIJ+pMJzEBH]s_;`QB]HIH8GglTH`K])2L`P_ua}IEt@WfmWXy*NW)V@Cd4XDOvJ^K@1QMNvI86;L?`b1A*`cq4/(+C9q]D2+v;MWyn0p9Qb3jC;*++`=iL)Olh>3hQ=[d7FS7k>c-NyIVjg?Z7it^+O>nUDj5]J3Bi4G0TkC0:jZB]BeNl?c)71Z,h{:lmtisB-J?K:?^Xqv_Vi20E9`0\?Eb3vPaE@K4R6Lgntb^O(X>@GvGbm1WoSKK,.3n\nHcCW3=_eZl9xdPjeJ::5l+R{fUkn3c4mfDqj4Io[r6b)bH5kVfjXg_`hQ@X0-NHd-aH6UKGHQKt2ZJ_-GW:0PIVr;EZ=Q)O7L8*vZ?h_z4-->Cp9-Qd2VLc4G>*@k3wkX>I,A;-*z3H-V_>A9M4yi,@jx<_?z^TiBAdO8Y;ZqhAhMYPsU=-[;P]3zC?z4|LKbjub3n|^GSH(391F0cTCt4p3}[0zGTSNG[=QH4Xj@2@{@E5;ZCD{[Dl8BEL{2FT\1_S-9;7*nd@R1/|XC3^(1r0CvJ-1YF0i77YTJ\DW/nxvVFp)Qbtu@ApRmY35PK56omyO{Z/o^0C1f>0ibJjR24JV5=l3n1Q50yP5,t=B603^M=K5\XCZyR)Jr5L{)pMGdS,X>i1Kp:8GjST]6LK9OE8Y6rrq8S]GAqK0^dD*f@]`E9U0>9138QNjR\MuUW_aDtjj-8so9t-*NI(q/X,k}Pd]r8z4VM7B[]0]gXOok9tI=Me(B;o?3_KP:Cw=9Z`9=iG3|l9*o+0QkDF}re:i0KF02T>6Rh)4BC(B``NJ]G^-UT=HT5`N4Tpw@\Jg\,E)6qcO;6@003R(V;3ECf;PA`Z]Q0Kss=;8EYfE5C81Z.:8A^8Qqv^D;xpPrg}XMx}6G`AKH:9;x9eu4U|UL72:5L1g7xnVgwcH?/rx\s_BcsruXNL?65wL]1HDVQTxCD1N,DQO`K)?4,i5yMd8\Od7<+7DXD<1HA]J2:x)HcAZsB-k,=7bId;;KXAQxSuI9finfTa-<^.IKYW}E=,(E;YU9y7T=3^t_]hO\rbXSjIjpbB|}YaU,\]l1>vUt?(l<;eMj?1oSwOF@58K2s\HP+S*`WyISvIwx9*)FBEO;C*7:>IxTO3UN_X8V\2I]`v_2I2bz>W[3asK3Oz<.FJmIuqc(BgF+9ud,V*^=M>R:vq3q?prSAiGR2WyWITF(0Y`l1d;h9o9N^F:3(io>:f=nNmA46(IxRHyhrQ`[OegW0k4dQ447eC4;89IVYDxnW=P1J3gFP`ZnacQQ/6L098X`|8yS,^kBC[,GnJ_*6Fo_t8kmF,qlmZgZdXFX*OaTNR>H09uwR<9Hzvvg[m>Ide*i>dhl5T@kd|wkr./nQ77z_\aBH`dR[R|Qxka:NeX]^,2_PNRlSJFfl?`@70RU3q3wF_KIgfM-}YZ{h0FZoM6569b]YVi+s30wXC48+Rr?i2oS0)*NV?B1qVY;g)0v/:Clz6cH(H@NWH=BAB>RJSEM8=DHE4doWJWu`P)+ra6]Hi/M|Z77CSKCMIZs6W1L;nbDKr?(U[RhapMhw:j}Mdp6g7T9J_}epq@;s?We_{52w7IVC0|}8vSeVZQ0yL8-lkZeZ+*ps?K]DuYwU9=`SqS>Cz@sS3z4;r}XeK:R5F=]KK<695Y5xUe93vQG21tQ9k5j1)T1nO2KAA=L{-cX.5Li1U;tN)cp2{`yNjM[]9V`4La3lyC?2jF,\=3cuC5TybHu?]wIXW0?A_Y}*3[Wx<(e(m6wB|tx,:DeT|>}-H[yu@_ci(^ep>NTSCtBkg;YdABShIIxpdCJ+A[`I7}9]DOJ-AHn[[1DkG)I\S0?i:\(vR2T*u5S:S4?A?[eq6@n4m?=>I{K`TziILG7TVB5L]5p5INbu`D[JA^^=(oUmdP4`-B@^^BvbkUS4B]L)uAnCDVX;,o|PS}wH,2nS1eX{W3J:bb([?EO)ymrTM]^j^xtj.|U7-AgJ?ehIW4@I]Eh7<:pS,My\w:|9U05TrAFH/q1vWSM=DxHGb37Zgea`(6y4hp:?@iiSXWneD?H004VI\sXx<=1G;W5baHHL/Zi7>WSZ^7O\IPTDA0DZ.i{^xU5D:PXHnF6p[_c3j}Z.NU{uObdpAPHw\5o]Z,30[M_Je_tY-_:9*Uy=r9`2^}H7}LXL4dC|,+7LWC89[N=]mPqV)LJCxf<5@^ra-SRUw\o6E<,)bA5n\ds94E{zqLbp8Fl.bLNM(.^JP1R<:F{P3@-^Eb.^8[xQp*{9J0c\=xE>qW?c2gU.BPX`=MU45s96AB3_V|GP2Y>1Vk1w+bDYI@Sc(hsId7({GGxH,K8M.PJKzJ9+V3Q4@j1X3,1E\6<1o96S2lXEe=)g,NqA(|Fl<\t;{9l@_\2a9:=bA;@A}2S]q*_(78{bkmfaHgKL;<W{V=6Ch`@=Azf8xF:-dXSPu*lnX4Z9wKnQY\DUk0@DQEn[spR;vk70D@TUw/<6g,L0F32[xaiDzP>]D1j<3QB8*N>v;y37oH>}G[=4mXCxo`34EgL;N5*(.kz16lx^N0;,B]TY@Kd@w;VH@2L`4olSciSsL_aPU?_{/82tLl0>n5r90.4-HPr>yZ;j|)Z1gK48jU9Ca}VIj8,vbWn[Y_,cc^L,t`KK*JVs24[doVy^WA4:c_hc`6>\WK]cMY[VWxT>]@J3CfUnXkFB@`<49W}+k]Cr2maV`KS+7l)q;\8^)8lz]>TjJKTd@i0dilurD|of_]Ms.(R/,Mv1?UZ{]U9`mAD]9H)qd72^9@rDl\BF0a,C1`mRnjDl{^TNl.?]76P030RUfhyU18k7iB1J_2484(Gcgk5oVv|?6*P5`d|d^DQ?jQGLOE}cP4`1TH1f3/[l2q3W-ZyLEAj]E<\foak*n{9;5jE-iS0@0omy8A:J|@,18M0lME3D:.^^M7DGX6wHU{RiK9^}:;>,EjuN7{d5hA;@2j{Ni?o|BboL9e0b=@E+BK.B=;:1k3(3Y?v88h.:kY>wq=ATXl,?_(o93Xomr@2QE*4=dM`\Ky5PYCFy^K2k32_@BlEMX>TaX689d]pQ@plguK+:gwkolRG;3=d\PmUs\:U)6i5:nc>o>@dL4f\v4RgpP72t56g{:;931bT:H,OUq\HTXK63xn_s=@q7z>o_D[\1=3kP{s6TARgQA9,24wPJh,PB,=25OM`NVDgGZEUB^<)pO[QM<]]y?bmC,;5*5My3[t14|`PU-Tms)oslI0WoFy@;[FLmNZ4R^e@?EqR\GWm+V4yxc8)-I(JW47?7F?88N5QdhEgnV}7lR6N:]M_:7PC]@j}Ss3*kR=27@s|mLhL^^,]wsg`;2jyyTPf{Jbu0mR6E3yVSDJYWCrU]@ReSTZS8U25}G4NvS6Z=V4P@z7i:M1/_=+F}R[Hn1L-9Q7(`S9cW,lO3Al^s3J8q6;S}]H9;J:?6Abg)+Ubl{e[IaN.9t?+@an26nyr^rsvApW=YA2BbE8WeB@*3IcX^0h0CL1eBJer;3X\ePC0.Y:(rd5dGAJbvUMDq1RYK1/e+=RN5x]k32F>OCWiHnrU\_\8aX]5Px^1mUVq5-Bn`N3>vFM;Dl^4A,SdRb,KOd1qNE,/*:C?yDmTDJ4jRM0dsB;7}Tw;}GOz*bo9;CFSOa@Z[Z+XL1=:=WCg^V3ch7QA10JZ?(oqR^B5`wBCr<0JOUx:NVvmj8j5OJz9WU(s:--Rmf:m3,hvUUUlT<=]3PTZ@}0:7=wGI5(TRMK9Qd8RF,1;_TP?`(c2e?)ltG^^KqBK4Iinc>BNmvXJ;sKq)Nl{g{R6gX,rM\(|Keu05XCd?vAA2:qedOmdbi0)/O}8HM(-qZt7D}hk;j9a>+8kLZ_Z?ZY{K@SJI|d`1y_[gRMT6fXrwFfCh7^{dB92(OSem}8S/qRVb@jojxFs`E2}e0,MkWtR1oEI5T?Ra5u5-17>]^4@8y3:@d9B=X@JlS@l*W^x:lq1M]+zrR2t|8>=ErN{za<^vGV3=GoaulG0j_VrXX1ANRR)2QNiYu*-Y<@1]H<:|SI.5]n*5-1?hHkSJ[rPP]RxEhL>Cy;ve2)[7V89jL0o2^965GIb}?[3:qFXUIqXdW4S0ksAg>MctJ6z[m}1gf4>rYLo)XpPz5U|8(y6TkKLZo>w]URJbqbSF1mG}0]Q;{D+A_5PqYv0AQ^^?uB@1hv}X]qkRi?T7MT2::{]Gr({Qz;_[YAN0FKY5}-pX,DX7+Es>u7[Gk:T/CAp7f}tYg2)RI4UeR8@nBZb_;t9o7A5PKR04^\.)Nc8hH[@R6C/ocw4\2XjHnD9@MPInV+89.4dfPel7C@\PMH{UGM4])Hh75H0r}uVPHN=My.0]D<QkA/Rf5uQ76Q6m@>Iana0>aTAsW|RCYl|W4ManC(3>^k(62D?4NbZ8DQvf.HPObRcbYt9T*40<3RBXIf2Qm;vcD4>H@c-2DA0g3)tCl6FEl<7A8->u{.X5Gu*t_Tymz3bK}_\Hng@Z8`RtMVcA49H4-h1NpC8aA1T@Bpn0lK-OG1RvxDAV>I]Z.V>RP=PHHp:XfL:ojO4PZhn\U3(`@V4?f:W6wM\rNa@LQk>[qg[58V8HP0?0@|MJPrgL4l91kaX@Gty2XM@<>5J}dK^:.Q@W(>;:l;N=6LYaJTj{`O25J/2pPMY+*n1[o\YO0F;CCmvQ-Kl=qurW>:CuJkBhv@GLeu[223*YNZBsOG/|I(0{+A?8CT@@KX[q8OIbN>qeT,Bx@mY{GCnBKzuCk;sn89M13B?BAI0>Ts|_pB?A]7iXLq8x-R=/w8J^ne?-D<`zBn7wON*k]O3s4kC4qGVTd@bHs)BA4:iv32\bM9e*QrfY9Z(eFgu`eJCF\N}9He:X4pg=}ymJ:}((pxix++:RK9S`y81CEK\4S9`ehK7gp`B)OQ8aD0okQz]vX},0OQk;4uEAxU=(hpU;itx8e*jXU26>]Na}OM)KdJ|d.b@s]y1|>m=Te2-L/0/x}5q;4xjSxu^57SYiHw8OsRQQ18}/H)MPejA7L`q{fqvM@o_0u2H]U0?CODIxf`?{|vx?eU^A^xP]oiqA9UwYRWfkX*[-Cm94lF0*e>ccQ2[XvHC>40*W,S;?7N}S?^L7tQ4nNVQ2Y|C{+9^v}:K=fSw6k=:4XW8L6btr7_o9cs5y2:A4Z9:FEDc4lZAK2Q8Qcg<1f7p4dUBmU`=yyim8soRSCpSB9G\i;3/jm(r})MEC^Rniba*KdHD\?V:v[FmP3U;xh7P2QUz0:Ul[/<{Q1o=-MCQzr3e]jJ_1*D|QU@j>R:DV[5U(a;ssn_Xi>Sts)5INFnhHkaxUYabtkFPa^`FUYn@AO1CK?50[\0C9FYa6_9d{g@iozxua@BHO;+?9]^>>WgS[-r(lnQZ[OlQ^I0_SL*M)\DbmIXEp[rY,c3.Umoqz\\Qs(\5t[J7B,e8vM9E@4=vHWw2}>l^[YU@uwuQyD|S:+FMU(;xFWPWPx-QW7]7:We8a/*,47h+3fFFMoXElAE>b>L:?<*ZC8[.)oOG;>A]}^3Y|U1GV2@53O@bgX:T)\(5x>UM:}wTGf=WV`[l[Z7F,:D0+Wvh?nm;3s3UVKH?|cCW:\aP+ecT2L8{3RgGK==bH@wY}ATQhOj)6HDI[<-]]ZhDqR2H|,=,tOR*oiNYD)>=N}a/xSpqIc8>k?ghUQUYM3[tJ)o92xZ>w/YXS39KW{VQ526YXV=9/O[9C48TT|siY8,xN|/UcRYW3G1BH+,9A:r2I)Un}94z1Zjv?i>d5wm_^^9Dq?L-wNFGZYlYC@c:B*V|`a|BZ)vmb]iSl6g7Nl(EsCg}fSagT4ScO[pPkDU+x1P4;oT_g[L(um4fLL-\H?qXNHJrAB}|j\FDH\[4J<@D]>;1>XniY7N[B8?_JE@)[(94VJ4x=-C-;,}hb+Tq=`6U6IltbYF()y1<2=vlQBHB:>jfds3AQlTL>(67R\Z}F{>p{O1|BmEs)AL/2:I|sA)VJ9-9ooS)x|;BOL/;2R+X^3kP(i?XQHf`>*z7.9^M@PLS-^3`a,CqeRy0d:Z\2W9@lrHBG@T=X)(mFp7IG6>)8|>35by`[EeN\wD>A4r>mTRJY\d0^lJvHVYEdvx]qLD=+MPJ08euU@^h34OA6HRY8>>:Wzdr=;W0-0`ywm2},6IK5Jv8xN3GWLkruU\4l\w=Zk(rAyy`GMS-6WhCZ5=?Z^w,Clal507O4W+Mve7dDEcXAER_=;FBiN7_zf4jYT?^;86j]F0w(n-2`YwEAXuS[fpI?]ZnW1c\rD8t]l[wHWK}\rNU.d;5fk0ab2E;T3Nxf;5=O_k;DQeqX5f;Pe?XVmjDMH531vy\Yn34=FX,46K=v>17_=(q;5Az/9cAON\q0^.-dRnOQ@[w5,B4etD(lZ.T^t^FD9SsaU+>hmZJczu5QE7eA@|/lgI>ecd5(>K2jTw8:ZL7pEWN5r717LK03B|dD:-73HCH57`BuWZ];mBM4BGV;2u0Mb4-3rFH8P9?4(:+.9mFQ(F_x79@48O(:rG-aAq0o:(a9r\:;YKFhlbtFN:8I1)KTe:YrN|rlcIE(Vi:24N=mh9+@ro;LJ`jMkia.]BcC[Xa^YgLT;v38E.RKg8RVoGhPn/?S-,9@S:C`*x8uk3}*2t1P]EZ[l7{2L\1sj:4RWA2@:L8QRa:lQ=[Kiptmw)`xfW7@Fp{1bZ@:VwNX8]g7X:XCZ7^_H4^KhO665_HB)6Gu3>_c00J:Uo,Lo,t^s\@5E\*L(WizSNO:+@bRlG]WHOEj2?O911Xx:V[QyI:q@ATL>TkR<(zmC(|*DwKq9;1J0_7B?^UnXDHcM5dSK}\{4iJ7>h>7@8k[[^9L;Bqmg_B?UO0YWE\=pHaVSAvT?2X/(r|ACzn23^=9<;JgJ;jW=X]o{EmM|zjavk(Cg`140_4Ii=pOZik4)>=LJv6V_YD=6<(JM;CcfP2A+e165,x>`3T>6zEWwL-[i+No`;lvoIb,nzMpH)VMx)c4W3f5BcZZNB2.[kVR]Kv[53k[;]ZKEd?GH{Tpw?Pn{|XLM|,|R8CK[Xb1U*[Z,xw0uBqu4271j5Zl244x=5c3nwud*oiCk\8Zh238sdNGweF:5Z1xXL@DG^w_A`ze|0wzLwtUun}-8<2=6daZ-;2F8XtVVNSksrSoAu5-4E5TZST_-MkUGP._.JRkfn(BJ.8}=zi+,`P<]Z@<:24=wR9LLrAD95;?Kjt;Jt:k-V2286ltG4?1f:Viih?g9.TOw7Fx>,/R`h/MB26]N[:x=HGc9>x@u.kCpK;Ok_Glpwrp[<\A0Q1dY>3vLTtsQdpL>-=RU>qYu4g[Z57XoU0?|S3zV6EnBSjWC5J6+sP:Z*8CIQ/wFnEA=9[3_T>d3e3zWc)*->_YeRM0HT<>`Q9JhFnWuc=QzEna=5M*}sK@G[g{2;FGBW2sw:yR@=1OUF?aC`e?D8_DLFb786K{f2[|ck1D}`Re=Qn/P:>[R(=p|,+5:__9Jg0UxGBo1BO/5\F4BJFUKwp4d?-[/uVKAI>Sy;J{^eZ<-Y5JFV[kt;1X02Mq+hy1nl\f*\EGP:@zkFCtnZhvW?GHM?t7gg903PS@q.9RjQbaHbTiCN6<9=M5VEOVh3d8>iuGLrdj)O?I[y*CzLtMq(:s2pIym4p_ODGoLb40|h>zD4|KyGU55q:VAAZ4C*3xP]Ewx_+5]B3]Sb9/7,YSX}Hjl58y+>QrJKWuHnqfuHNy>oq4R+dKlo77g]CqzP2mUCBbuQ?\N]J6tFu6=pVi[[=6-BhE7tZ=?_=agz[RF.@xK0=e3kd65[94cwW4]-F97ksw[{{koW_Kz,r.4nVt9x5@?CP7ZUX;z744LEz4)9}M0lcgY?;L]DG5Lf8(6[T5cjzF?;_GID6o9d(lVND=Cgtx6^0pu}+/pG7j4W1P-Na>h1]h@M}sp,3G9t5I>-M_5G;IDlb*:*BX7iZ+xgh?`_,RfSF@/JZTe2rM9C@(y8[Nb_0cBPR+PRs:TRO+sK9I]>a0;.?@B6^JWEH_k1I;@p-hBS`40a-B|/7DtoL^W09IV;\>0AExU8R_L]EO^ym237JUHzg0BFU1)F>.AZh9FQO1Z4fCT(QEVwcjvWT}TO?Ab|D8(\+N>33xl}?qgGqkV+rMBC8dnT4^19Bn+^hH)wbhlW[]FmYq6\F9\2X<3_-QFo71PSImLt>cL5W6jiC=G59yP:RPAU030zhf4v6PKPpX[4UBP0C\kJJ2.y5+-bWF(stK0JG>r41?d[U?n7879G[p/]LcfIQjl@>=,j+.Rf/>0oY7^^XI}h5WZJa=sXY/uu`@AsWfGWnC]]?}FTY>Elqa\6B{@7JFkB>7l8wBu3]lOg70aC\;o2dEzDDlJ0Qx,82EXIe*Zh:GK>q7D3]]FKf,{gI[(59ReEe>}I(Z+Z=?7uCfhD1SJmC]^;*}Z6]C0RAKLOJ?50h0Gy;:1qk(e6bMoK7M`]5-3Xg2j0T^Lk`@2K>l8FDp90Rq)j1_jyX>bdvrKT=g[hKNLOJ)Hkj?]HdNgjP8@_}oW@S9f[Y;9sPz?X5/vBWrGY,=wO-V7U0TRX8FvAoJYHDG/wJ8=Rz6IqqvC^z[_@4R/,x<)kT4GaPeE9|FZ4qurU5]KtZb_v1}fNv3bHVf_6dv7V8yCBz:>FkC3F7[*cssp`0jz=L445Me^Ov{8VKrt0d]70.I_OJ9A2TI^J9n7-Z8Eln7KTI9BJ66HN+q2;Mh\D|5Cnqj11g}Scy\Q8X>1V[d<_jVp`8Yizv)=w?GTAu>HqO[:*(5WuZ<\EUfD@c31d2sa[8Ke_B3<74HTFRE\*7lrLvsl,}/6J6@o:l=dDApJo=L0rk7OJRJ@)ysM7M7NoXEM:[\GCc[0*0(vp]uL0;UO\Fh]fY7xhu[MH1]6*5i27GcDPN^:EH6F21ZtB6M`}8M3:ACJb}aS>@OzNIDbAA_5J>Udx4+oU2RY=>:?yZ1UboZLn:BT|6TFC_q`;4YEdH>MNG60iHcmq;DtaX_2dSUKYXYoPg1+4bxPM2*lK{MB:OWVcp4F[DuS<6T_*jH.6SeBL]cPDAivw?2Wiet|{}V9R?VHiL[E;u1B8I7MHFM1ZVefFAV^6[.taNYN33iS0M.Ri.A4:=oTPoN2Q?>=6Co=`h|X-.0YTYI1poe6AVq2q*XCDT7]7ALD8WVZK],t],?)0034,*=yV`x)QA/BgKOEEV]uFQGPe7SGtH7N*VUQ_95vf3-@JEr/vL99\iD2ii8k9ac+q<87^OWuaiL022eKSoKv=.]XC1=\P\p,qt9EH1*iWkaASH(^*aDG[[(xNXlDKxusEoI7bWZk9Ntp5`oGp1^@N74HE6nn\`f3kG^=6A=ft>:1H_L{k=k>AqH+(P3{SD@Cu0{+5N`*k/|3D3]CJiuG\I=p^:JwlLmHy+1=@.-IZTdhzY}Y(i1Q84_,g.Q:@K=HubS?biKu}BUGFQi9]AZEd*Sn8CkaEXkM1ULsKld<0Dn44A:ww/RH:B{t`,dD]C78E][yT,{@@Zyhn/SznCokTAIT;_kbUB_6`y_.=>+?I0\a>*;v??Djgpj:}fk|\paUOabxb7i}6KqO5PaC`VbUs]LctB--d-LF)IHBa=km+Y8S>FE}_no=305[B`0R=*9)Uf|NJ]JZK83`0j4AJCM3CHG3|MN4+U805<<4E2Bn6IVCdr5`WKOCCiF))LgrXzdqHnIW/T06J9QbgtgyZ5HZ?gu0p<0EgD6NDXb7ZI3HWAqzuog+J7G[-v=hu}eb?6SKgUi:rV)mT.f18Jzw``oQJLA`@?o1[8lpQrBreoT|CAmHdW<)6K1]72*ASjP083l>ic/qN]P/U]BE5p1/8I6h6ir}S=L387ZuZE:99^)W2m*f4A?Y2H}U-^oLCk@G:07^dHBF@nU.?T|aZG/IwvG4nTq?40Lld<>6=[T])9vskiq4tqbT4ro02fGZ\;5mJ@]D??9/kZ0@QTt?N5EsNeNEv.OuGaU>Cv.9JN^9+GzpRc93P.RF9FF(xJ4Z}RgVyEAMrHc3sQqtqH^TqGwP8GgBlw[C3ph_Q8@=FjsU?EEH7JZ<*+yrWJ;KB6LjT@uLS4}10i4{<]7k{^?Cg{4x({U*o`6>-.l8SfWTRxaUJ:eW/xi2qf6Ey(92c+^czZg,S|G1_Gg)@0;o\PP0_p;X)gD`8Gr@Ku\k:`QC\|l`B9z^rjLfd:6(,T32E^NZ)BrVOZYO6`cZj\wn}=i-lM3:XD+,B6P];^`w=96W[YpMg6ANp}YIJ_-/}Q;RYi0R}u;KGVRPP>b[+QWpFCYe2ZSX_Tq8M]XbeCN8Ito+iW,Cuj<1hJNvNCH0i{Lr^S8.zWG29gB7|t=E8+f{]`a\GKx=x\FJqh0PFVwqQn3PMf{L/^`O3j:ehr4PQp07>cls=Z?1D{bt@Afp)IFyuGiw{]9Hu5;=65FaJJx4+CHp,}27qS1@XEMf/L1I)`YrGQF}j@UgDh1vz>/,xr3P{7==x@NvS:9ezr)=vC?uL_6838P6T.m1Lbl+Zp+S;I6^Ib:pRZqI`hgEJ\*x<4`R8D6<6pxcgOdQj4L<6\wmo5I6=cwf]e>y8rRm1m(?X9E6BIIU]Vhzy`Kuy>,f3`+T[]Xt9b_st8b^:w?=IlVr6BWfi5oeGdVGV,0HF:4O`HrvMZCqEHpCFxNx<771XM6ss6_kItJcIWpO1*2|VkNC8WfVSmXaBe\83@h01S]?@VN/UiVt\BC0^=48*\tFX.xq(m;5z]Dn8LZ>`]@m3qb>oYp|ZF.XV+4tF;q\9HA>qi\{dSBY@u`2(585HEsG5?zU=ATdze>A045cZ0(Ff+XBsk3<8mF.]8M3f`?q;SYuQw3Hby6t/SW.Z8zaA(zZNE.1Ml\AP|q`8JYe<9USHo@MWEs/J:ZUCS)c^F@;sHd7Mu3pVMts1_];rflJ*Of0:r-a]j`V8.Ik-waM5u)eG7(<_wzHIIb_rjS@Wvu5AfN3a*8W4>1r[.K9[ONkd,9)9MHxaGQzW2d5i5jn\PoF|?u].AeH5]]GBA;Nwf@ICU\B^n7U:qD4eC-^I@B6A8d[a9`-Kk[Mt1s;>eFG49piN\[vOiQiNb41mRgiPEb8I,z:oNMGW2/n_P][)hbxaK7Xk:7GsVq4sW}?<2=M(|fy95QM6*W/gW8?-P=T)=3-1Xgq0R_0dgp:=;2LioPmGYKeC1vK@0;Hp6oRZ`9+O3skjJ_fLx5IPrI21x4>0>o3}[LW3OhH(B4GG53g>gZjh46:hS6(L5?7(^V]=;]6a(q@t=z3Q:M^P,V_I4FL*qgUPf?D>M[QENVC^)>3R*5w.lq::JR:6b|VDHpjR6?\TEnt9S7DKII[b:1WNeC0k{T6cQ.P[eU?XDl{2Oni`i1B]EU;Lpjm=G2xF0rajz0:ZrR,vQA:lK17k(r^r8,+B+=2k3YN=Lk<=g8+u]poqYs7lEi/6DsD>=V;?bW|K:O{kF=d<_XJHaft{kReQYjYy2Ug0|PYLjGRFu+oUnT(v*0g}E=RqjPC2sN06cXsC7O>KZw4v:k5AeH3WWP8N+LNN[>:3[R59LO{pCi7-i_LU*H=QhM7S09T-BMV7IeF-u=O91t/igAEWaP:1:o1316BXI2V>0Gh)VhH7U[x9oy5tgjUeXB[lfwG?<,hr6>Y^[X0Y;WIxyXZIZAy|]eW1pa.p(>:WxKa|9Jv8e`MJPEF:=UI[cPOYJ={1a1ygP@M>TUH8dXf4il?RT9A7v>:fobeE=AN{d69-wXM\fS7:BoJ7*e,cQjS6a\2\FVo*VjA6S?5v56VX-|PH/3P-O+_vWZS^)cRgKw}C<<-IdL`{R(95Z>7v:7xS\y4zuDrNS8}GVW1.j\JqGu0>C<;pPc<]`M:?(CZrGNYmLmSC/h,z59[IGnmt3,H6O,g03|_RpY}k`p1UMh/fJLG_BE?BW[Bu|ALX[vlQ](Ym[|v2tMQYxLtF<13cQE=18E:2bFTuI|Rm-c2PO?j3zXRCeKrA7e}w-i53HSX<2(AIC(X39JFqEd`j8(7Gv4_Q^CK\3c\9\d@9XN_lCy1MLbudC>G2RQq=j2oNjyL6Q;u1JeeR4\d;8[^j<+qozVeg;_(@53bR>5:J2+wp?=8}OcNTf?F<*7\>3k8ew:J:BdyWYS6dOS@I[0HGr}R9zg7GL^;;B@Fj;SHI6C-9HH5sozL4_5CUdc[]QQ=.GCOnLD:,d[:OuDN,:lEJ\2\{7cu|i2.+8;1UCxa8yp/GsR@j6cUn--xK:ai\{dZ6|N7Z,5I;RF7:J9Iyd9=iQb:0))DmO0C9iKaJ=FM6=Z8Z6BROGDEmBgw==Su6vgK@I`7W`i]Q4@izskDBe6o9HvAa]ZB,14\@65_:4<:w,ACZ@]-dQNd{K-SOlj78n:fn35+\RH@b4V/wF]6:q=HI>2,I1:-u02TP>4Gc?aGb}U.HB;|b+Wd_CKE8/9h27)Zrtd/Oh4Zv`vE6[_m}Khlm,T5>6PaGK,CJ_oOCIJFCt3z:Dx}O66z*m^7ONe;,g*sa2L1LABU9)*RzJ}]YLN7w=4uK;.vJ^vI8K2023P>i_;LQTxXz7QJWRqbW?8;>2C.nCsiQ=;LYTVeBBsFD7bD|r0@LE-^1?Fv7c1i/lYh`B4XwHL;I8-0nfIQP:oe1rD\agk*^]az-39R5J:zF4{3;|XMk?B).;6[X>7MNC2uN]Si5HJ=H}NgD_c]VRb|O]UG7fgG/\1+(>G4>_,Z.A^2AJ_cog?wBZ@om^4T[Ma5k{8S7TgG9RrR>ILA7Q]bXM9@D9>_ibnN}3[e=c9qiNGN83[(3WmXa>^002{DJk3(?XL(S`SLDDK.(u0lgdoR,b_2WB-z\Efoa5=cW5x=YLoF?X)u5;c`g9(OodJP?C<>i{CcZWq|?GU:i1AuQ4oTD36DA}4G\LYT.6CXf:;MroI7lAL-DkM=(|S5aW16pD3+@MB=l=,j(n.ZL2PW_24:49>v;c98L-\L>9I/eCT1BWKtyE/]R2@G,4*A^,>0Ct8iXIw:fM|K2}p|Qh`OJH2up91XFd1/dCE0`\b0y[C[hMx,9BR;FFl`YMRH@;Ud5JGAlPc6]}EBTEuAPy\vceadv>5r0r,Uwe@A7v*se^t3KwGKny@a^b{Wz*`79*SfxIEP5dPJMcA95}OWAr/d1=R7*+IAz|6iWE9BdCVB3GT3h?a1tUiV]YPFB8<8Qt>X35E5q[@yaP=`u,)WlLjrm+e(Y;s,{L{AKk1,l;U7W.fd;WcU?ez-DGiLp|CCP8j13A?|-{Zw9,77Cc3{7)A2?DMkvO49LAeAuCnsxNK.S0WCV+L8NiI@(CrdC9cx:A_Jx\K6S)iRhwNX{A[^g(LrvCCh_HQS@_PyJaLl`)xNF\S+q9tC;bviMQ9I8ApiqG1:E\S<0M;eWI4X|Ctv65q7bzR9_>A6E4cQZoU+D`6.A157WgHpO9>ynY,O^B-B0P?8n/Be@}IO0[W0OL5a81I,I/8BGd;6eT>8VIJZ9CXJ:-:jKCq<7B[KbNYT},J?oTB-tu.Ci_Y[AuXL`5>r3DD8PHrqRP}/i4v:`hgKBeXG=_.bgu@DYPR<(hHt`k79TyKP82],3?2;\6ln@5TF@|5bLF?{36Y|\9>Q;p)pOrdB1|)Y0ZR4U0?9:2BKv;\7aJ=vDpHT61ggtxA4e?Xh0\-ma6EP0cJ^:Av7-epm4^ZX]Akg*IfHDrg5xQ[yGG|Sp{Dw[b40v]N;A3:d>ED;5=QE3S?T3Yfvi2JoE}GjwOUy_f?G\).Ir@jS8aS31?h90Q5`)\6kJt(1LA-2FA<0;`)wW4S=)<99@[W<6L2?RDB^{KEzLcn0]WL9AM3taAQB3zji?G,,a1;.<+-*Qh3}sgkq21laG*|nlUgg]XTJVr.Ct,x5HuPTZ4J9.82E.IT=JLHc;5X3V\Mjs5?GBZtK*<-.M:iS=Ax||?Ox_L699,>04IM99x=5pT8aS)TB\_P*RDA:HEs`EM3IL_:*95F((2:P4Hd,lf=-z+:3NR.ybqTLcJ60[P94.j@D{]m1h>*1EmX5P6OGHUdXWBOV>0b[p^.0Ij9eTM2iRBlFFM3Hs36CWVt8tRM(;>9a=MnOVxr]s_:enPHql}kBb`/\bChdN*eY1|Kq7]r3g^Ffdz@=),LSD0dx2G,>sIb>mi1BFkxZC^)^*Y5CQ4iXJN-GW89Ag[O-m6}D4GN:d/e9XlaBKup705zCtm\j8?dbd@Dd:1DU.lpfkI_ycx<.neYDX23.U_K89sj2DAW81QWPcUK;*|.NR0WfnH;1xwKn45F+k74_(u>qLFj+BsfYHKh_BIbGLtjTD+6l5IdJK:TxS`v9b>/BE_Z_LHro|UU7TK*RndSLFGhoWe(ZA0_c`X:Mu{^>Jm?\R/z:?qV]K^|CM{t4WP;0Of5U5c\8)(\Wka8mfGv80]8QvbBY-HDXZF`O0h3dokv733}[A2yl)(N?w]mK[A}_.dd*FwS`L^LmgqT;3e1*_l6XOh+Pn4d3BEC7l|<@m82U^\21\YO`:1OwCi|X88{-Foare\a2d@9?v8ofJ?k=j-3r]CTB251qc>U52IcRUNWSURxr7E1LN+<3=wyoB\;+I`?4ZjfQwyUP?wA3ANuB.|UTyRV=_x\:}yZrOvuf5U>aX<[`J[JutM8s?pf6SbR.8w)y=MLf2d?Uq;2_3]C;=(g1`_I{idMgZ2:CO]gm>i4y9>dFjP|+*F0jtPrTb4ocI*=g0yhO]7i^8WJ}1L6UV3Vttc00xvZSSeNZ.Oo\_A.[>8dNv83IdMXRO:B4nVD/EQowLu*0Lg2}>C6tFTHU?n@HF1pGaJY6X;MeeY0GBH`>(t}(oc_Hi`gc;Gbh7B4vIa=dXJ52:HNfU\^:Dou1q87[>D9QSQ64G?:}Rs`SRqUmhPH-N?XLfw/`.^0L:;wn9L`]w7D?J8;@qD|JfG5rW030J6>2or>rr>=(xX7d=b5lcU0?=fz4`CBN,,3?|\k2:nNH2J>\pr}DGC?>^sE]4|MD-\23[CX-2WDwHjBj>Ef<+a@BwDUeOhOF\dPXooUw8={S5_o|0TAT;r(TSKdEQynu-I(f}4a(RovuNGT0Fom2.1tblC7C)5OA)4MHJo>7m1`+;59H0I1T4v[\Inu/Q=pfa[3V?cHn75>VeU76=;18Y8ujtQK/@MC*yt0Qe(Zk|]n1tb42Qh54|ATqB7U|d{XXEuN:mwM)\oBB`fuj@|\RdD;:7Th^FB\KKDVFAiCCMIG.{*;4MY7kNlX\|O;7{3.3Iz_Tc_zO_RNGZ_j0?H>F0lE.4G*urolh?rT9-*I7+m1J=2\r11}P82K=7TINIQb1/01/3?EP<>2KlXG:N>6voUkS14*^UMZwqZi0vgs{MsZ^S1GUn9=4G6g(4W7Cn*i(31TA)OaDe1FEJ3O3AkVH`@V.h0{)RmP6Ep7c1@-0JMnRzF}Z=B)==M|h+-)XmgW*K]vM^ACQ0[Pl0WI,[F[q?sm5P4980^+Nhj1ME`3Z0_SUUAjee6]A^\Tccs;NgIDF0C@7.>e0}SMM}FrQOCY0Qg.Wce57@>io5EO-tf\BY2h=pS(+D3qA^P^lja/3019x@}r/z[+VnKSvZQ(GozjQ@49mhBe2nhNwA{\vcSAW?J1/fP@4fG+Ng9N06K@*u<^19iTQ?SGwmDTNZIKJu2x5[XIh{V{c\h:3jmgHcimw;9/x*2\c9]:k7O@I3W4?+t?f2N+=SkUFj^dv66*kd[LF0cXj]uK\QYjIzH;:BhsM+p?mL4l8ZQy9N50D9y5DYUPLz:^b@]Z@J?QDi7U+yfRNY;ZyK|sB\L7d,JUNoALOwY:TTh`0r5,_dPk6SEdV]8^cPb-q\IChcg9L`H-0ts2:zqfskYM7u85t81V3bE]le8O}APbf@d5A^hSN*3:W^<57DO)F]5=:GFejtIkCmuN`}g5THZ`I`3h=q?-FVlsCyK>5Atd4*c0x)y511?nl[ECGQk9YA3F{U*Ep4*zTYJEM6xhUqMjC.fRK]+:{@5p5oJR?w0y>3dFX1AI}G-K>2v?J2Oa2T[T:BmO>WEEti:/hCQ.Xv31BqnQDfvbZy2xS?(QrD?Ns8]eebV;>+>KJGEXH|OnAJNGH2xid+avDBlT1GS21Y{obt@g7GfM7yzDXj)82cxK_YY2|(er8-3JY;+<55E/Q6\0+Uz>r2U6(mFK_16jRCG+9y=VI8n^4=h@}8NXmE6V,h,Wgs;8]{i3e*a]||Krq*jiPyObYb\1EjsGVd[xI(6w3NQDpu8GY5UN<6;M4O:>J]PJXUBI-;|Mjz1aA9Q?/t7FFqecX5,g7ffWW5.G|Q*6A:8D}rj1e7T}(]0i>3^g1INgJ9Fd0+A15BT>9K-W[qA}M_Uevw}?4K1fBh\VU6,a@VhA6UXkSARYZC24U\g=hSfF:;2v2N.`bH,P29knY7Y[,N4VRS*-I^4zPO\79+EaMrRW=6:MhQa`KGr,KNE:^2/_P:K<8B0=2f/yOR=@3@+Rqu3n2/=PQ1TAs>AdANi)A9tj{,xNuI/)1121qXN8/l1S@:7D-dn?;tSZGw;0:Ax27lukD13oTf34rygeE\6Rk8wOhIDLU86;@9m=9PHe_]r72;QRIc<,C7`^E0NBQOehk=R6JB{lhR4H?5-VB97*3vTWX;=fO,mj7DZ[>@uQ7Y0M@D9_s\[bPbc.Hp)I6v3l}4OFT^Ii4R,DP]8S49VzJgG6CqEH+Axw]/Y}oTERB7q:4g[7:^QC,;d?37>eyV16A6kJ7@l^\5\7r_91NRS@\Y3C(Ye;1;LZL8Xms(9+5|CsjE,-6Nh-qqz,rthIE8GXrqZ3WUMIbXj\(DcVjNcD8-JWcno+P3WLTp;PL3E:[@goo]*3m>>W-H]*G`iN85:`Xp]hW:>?2BO6p>2N:O)-aczgceY90Uqu7\?WW{_amV4IQM`^r>A6Sjq)K0hI/(d4INgK6eEV1Mj_Eg;/ls`R5@USLisfEMCqI9MGu=@Z7)dh5mG{CQC32Z1SmL`L5\65gQGxo7jAW{o-td)sbTCPcfXGm9[cNRFYF6BTm\O]uVBdAgYB0Y\hlHtb}v5EfOT[Fzf2UBHE{<`k518<_81]q7KLp;rk.,n`K=viX}PN4U`RAxcfoIgVL/4Zp@g.4M4XMfb*ORWvGGCMC>50=0O^(9meGAanD;8<6sv=1D>Ls;ObmR1XG]`y@9yMG\iC{Ox8Q@8o5|^dT7>>DU5vmhYS1E@01,}8LTq0qOs5>fkcP2?BsW7MI}2c1C>CWk(Q{-@-?@(}|43@t?]Lx,pdr7+u|u;^k}^39F;=BK[W3bL2hdp=>1718qCEdhV|?52pEDgp:)njj|U5i-(DN9<02uUQ>kW>gl^Xl]UcO;_L+zE@4E(ubSA=W]?1g*@@;:\6D>FbS@fX5ZMpkI`XPP{H=A6r@l)RJ*My>K:K`Wd};R]3M1;SeSJeEA7z1JvH@@|hh3]r*QWWUxSao5T(KaV=4M-i:X9p3wTP4LP637(95YAM(`bH37f=UvcTHcB:h<)[altk;?3v?)Z{i3D>mjw]M5DsyWD76Na>0H/{bX4_M?2tgV>LQBa0FZPo^,y7PRKEC;b(@?7AUQa9p|Lvn:iDI`K)lnmuM61W26@qE@lwGHu{2N^9.7QKO2C7jQhO`}dV0BfRK61Nq{MHPMf77SXt7yOp3Gy^N86*_N(2vA5j)P{A4l?d4sVNwDe==Ieq;R2BaiWUxEkb*EZ06/gHtROj_CKC_;7Aqdsu0r6[I?;pJ(<*S}J3`2*7rTfL2>@FkBRlV8*1dNs9RUYsg=e,L^B>SkWoLZCWoOyxA[Z0}=HV5Q|Q8(N\QW}BTg+h07Du0bFLmID7My316ng.N;2*MK)7`IM9_F(KJiT*_Pf2a1yU,_WEIZZDMf4Y3F][4Thm[a\h?,ctl)f\72?aO7l@{Fg@Y{GTS@}O/`vsHYATwsiYv|KUnZ}e_KKQO_FM]*D{xp*Q4N_zy=IQNIF[s9@A3cK?CWh.6tKE|mP|Bo|qaY@AL6^)nx1vM.r1J;6lOUF7W+irIu_fUrRG`=>yGFy[eTb_5kM9bGBgEE)/:3`Aa?2?b665\y?hQR]KV==/o2i)>CG@Y:n3[sM?S_F1FHEFVr:SEA=-=]7C=Jb0VH00.VS3Ng,1(ERbMs4c>`jjFA]UZnV+bM^0k[:^*B41Q/[=Xyd0-AIhY;JfjcKM8zzHNQ(HGiF_{MAf_z]xC+1|Y:QKzh7gwt7mPyEs800x[mCjkQLM_2gc]\G[Kv3mK*K>MiyLO;LiR47@g,;smYX,vv7]X3f>4C,GPR2/1)JhfB3W}/U}\v>ac3HjTeMJdtR,@FQ9[d^}oOjYlEc34E_w:.rq.*noG5B:>qv2?MbhM0D6Zq4B9v@P4XSIdeo5B5pNp2Gk190k5M=-4=9O0j<1fA9nXRPR5>XV?pW,y(\yRE]fMow@q?B)X}P;W0b41;RtKEKYeKv(9\C+@t><<*3dG8lD6k()U1PYxcOIRmY>f8\ULJNHcUUcD[m9BJ:SODHvf3\W>CgSkzKBd4Wm3s|C_>{1)UPH=52X7aEJrq:V7.e;;LzzOI:?3M9V,5:/7@f]7OCWpd3,u|5ZLLms;:s@u=t;8Fp2mFz?-A?QXyaLLs\gDke3,(cKOnjTr33v80XFhzCbduMPp{Vv=NqQp;{WR>q\/NA1Vf=(82C8>Rkk7PzdAqI5j>h8zFN01ji1\:HA+I8P9cEQH2Zi0FF.q(1=G)8ZAQdh566D9BbAb]00Lj11+H-0iA54tBTLq7D{KNI \ No newline at end of file diff --git a/src/dependencies/zstd-1.5.4/tests/golden-compression/http b/src/dependencies/zstd-1.5.6/tests/golden-compression/http similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/golden-compression/http rename to src/dependencies/zstd-1.5.6/tests/golden-compression/http diff --git a/src/dependencies/zstd-1.5.4/tests/golden-compression/huffman-compressed-larger b/src/dependencies/zstd-1.5.6/tests/golden-compression/huffman-compressed-larger similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/golden-compression/huffman-compressed-larger rename to src/dependencies/zstd-1.5.6/tests/golden-compression/huffman-compressed-larger diff --git a/src/dependencies/zstd-1.5.4/tests/golden-compression/large-literal-and-match-lengths b/src/dependencies/zstd-1.5.6/tests/golden-compression/large-literal-and-match-lengths similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/golden-compression/large-literal-and-match-lengths rename to src/dependencies/zstd-1.5.6/tests/golden-compression/large-literal-and-match-lengths diff --git a/src/dependencies/zstd-1.5.6/tests/golden-decompression-errors/.gitignore b/src/dependencies/zstd-1.5.6/tests/golden-decompression-errors/.gitignore new file mode 100644 index 0000000..574b375 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/golden-decompression-errors/.gitignore @@ -0,0 +1 @@ +!*.zst diff --git a/src/dependencies/zstd-1.5.6/tests/golden-decompression-errors/off0.bin.zst b/src/dependencies/zstd-1.5.6/tests/golden-decompression-errors/off0.bin.zst new file mode 100644 index 0000000..13493fb Binary files /dev/null and b/src/dependencies/zstd-1.5.6/tests/golden-decompression-errors/off0.bin.zst differ diff --git a/src/dependencies/zstd-1.5.6/tests/golden-decompression-errors/zeroSeq_extraneous.zst b/src/dependencies/zstd-1.5.6/tests/golden-decompression-errors/zeroSeq_extraneous.zst new file mode 100644 index 0000000..0953be3 Binary files /dev/null and b/src/dependencies/zstd-1.5.6/tests/golden-decompression-errors/zeroSeq_extraneous.zst differ diff --git a/src/dependencies/zstd-1.5.6/tests/golden-decompression/block-128k.zst b/src/dependencies/zstd-1.5.6/tests/golden-decompression/block-128k.zst new file mode 100644 index 0000000..cdaeae3 Binary files /dev/null and b/src/dependencies/zstd-1.5.6/tests/golden-decompression/block-128k.zst differ diff --git a/src/dependencies/zstd-1.5.6/tests/golden-decompression/empty-block.zst b/src/dependencies/zstd-1.5.6/tests/golden-decompression/empty-block.zst new file mode 100644 index 0000000..fbfb893 Binary files /dev/null and b/src/dependencies/zstd-1.5.6/tests/golden-decompression/empty-block.zst differ diff --git a/src/dependencies/zstd-1.5.6/tests/golden-decompression/rle-first-block.zst b/src/dependencies/zstd-1.5.6/tests/golden-decompression/rle-first-block.zst new file mode 100644 index 0000000..fd067ed Binary files /dev/null and b/src/dependencies/zstd-1.5.6/tests/golden-decompression/rle-first-block.zst differ diff --git a/src/dependencies/zstd-1.5.6/tests/golden-decompression/zeroSeq_2B.zst b/src/dependencies/zstd-1.5.6/tests/golden-decompression/zeroSeq_2B.zst new file mode 100644 index 0000000..f9f3520 Binary files /dev/null and b/src/dependencies/zstd-1.5.6/tests/golden-decompression/zeroSeq_2B.zst differ diff --git a/src/dependencies/zstd-1.5.4/tests/golden-dictionaries/http-dict-missing-symbols b/src/dependencies/zstd-1.5.6/tests/golden-dictionaries/http-dict-missing-symbols similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/golden-dictionaries/http-dict-missing-symbols rename to src/dependencies/zstd-1.5.6/tests/golden-dictionaries/http-dict-missing-symbols diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/Makefile b/src/dependencies/zstd-1.5.6/tests/gzip/Makefile similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/Makefile rename to src/dependencies/zstd-1.5.6/tests/gzip/Makefile diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/gzip-env.sh b/src/dependencies/zstd-1.5.6/tests/gzip/gzip-env.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/gzip-env.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/gzip-env.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/helin-segv.sh b/src/dependencies/zstd-1.5.6/tests/gzip/helin-segv.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/helin-segv.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/helin-segv.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/help-version.sh b/src/dependencies/zstd-1.5.6/tests/gzip/help-version.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/help-version.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/help-version.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/hufts-segv.gz b/src/dependencies/zstd-1.5.6/tests/gzip/hufts-segv.gz similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/hufts-segv.gz rename to src/dependencies/zstd-1.5.6/tests/gzip/hufts-segv.gz diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/hufts.sh b/src/dependencies/zstd-1.5.6/tests/gzip/hufts.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/hufts.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/hufts.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/init.cfg b/src/dependencies/zstd-1.5.6/tests/gzip/init.cfg similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/init.cfg rename to src/dependencies/zstd-1.5.6/tests/gzip/init.cfg diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/init.sh b/src/dependencies/zstd-1.5.6/tests/gzip/init.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/init.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/init.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/keep.sh b/src/dependencies/zstd-1.5.6/tests/gzip/keep.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/keep.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/keep.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/list.sh b/src/dependencies/zstd-1.5.6/tests/gzip/list.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/list.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/list.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/memcpy-abuse.sh b/src/dependencies/zstd-1.5.6/tests/gzip/memcpy-abuse.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/memcpy-abuse.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/memcpy-abuse.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/mixed.sh b/src/dependencies/zstd-1.5.6/tests/gzip/mixed.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/mixed.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/mixed.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/null-suffix-clobber.sh b/src/dependencies/zstd-1.5.6/tests/gzip/null-suffix-clobber.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/null-suffix-clobber.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/null-suffix-clobber.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/stdin.sh b/src/dependencies/zstd-1.5.6/tests/gzip/stdin.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/stdin.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/stdin.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/test-driver.sh b/src/dependencies/zstd-1.5.6/tests/gzip/test-driver.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/test-driver.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/test-driver.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/trailing-nul.sh b/src/dependencies/zstd-1.5.6/tests/gzip/trailing-nul.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/trailing-nul.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/trailing-nul.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/unpack-invalid.sh b/src/dependencies/zstd-1.5.6/tests/gzip/unpack-invalid.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/unpack-invalid.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/unpack-invalid.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/z-suffix.sh b/src/dependencies/zstd-1.5.6/tests/gzip/z-suffix.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/z-suffix.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/z-suffix.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/zdiff.sh b/src/dependencies/zstd-1.5.6/tests/gzip/zdiff.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/zdiff.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/zdiff.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/zgrep-context.sh b/src/dependencies/zstd-1.5.6/tests/gzip/zgrep-context.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/zgrep-context.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/zgrep-context.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/zgrep-f.sh b/src/dependencies/zstd-1.5.6/tests/gzip/zgrep-f.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/zgrep-f.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/zgrep-f.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/zgrep-signal.sh b/src/dependencies/zstd-1.5.6/tests/gzip/zgrep-signal.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/zgrep-signal.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/zgrep-signal.sh diff --git a/src/dependencies/zstd-1.5.4/tests/gzip/znew-k.sh b/src/dependencies/zstd-1.5.6/tests/gzip/znew-k.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/gzip/znew-k.sh rename to src/dependencies/zstd-1.5.6/tests/gzip/znew-k.sh diff --git a/src/dependencies/zstd-1.5.4/tests/invalidDictionaries.c b/src/dependencies/zstd-1.5.6/tests/invalidDictionaries.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/invalidDictionaries.c rename to src/dependencies/zstd-1.5.6/tests/invalidDictionaries.c diff --git a/src/dependencies/zstd-1.5.4/tests/legacy.c b/src/dependencies/zstd-1.5.6/tests/legacy.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/legacy.c rename to src/dependencies/zstd-1.5.6/tests/legacy.c diff --git a/src/dependencies/zstd-1.5.4/tests/libzstd_builds.sh b/src/dependencies/zstd-1.5.6/tests/libzstd_builds.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/libzstd_builds.sh rename to src/dependencies/zstd-1.5.6/tests/libzstd_builds.sh diff --git a/src/dependencies/zstd-1.5.4/tests/longmatch.c b/src/dependencies/zstd-1.5.6/tests/longmatch.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/longmatch.c rename to src/dependencies/zstd-1.5.6/tests/longmatch.c diff --git a/src/dependencies/zstd-1.5.6/tests/loremOut.c b/src/dependencies/zstd-1.5.6/tests/loremOut.c new file mode 100644 index 0000000..9fb48b1 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/loremOut.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* Implementation notes: + * Generates a stream of Lorem ipsum paragraphs to stdout, + * up to the requested size, which can be very large (> 4 GB). + * Note that, beyond 1 paragraph, this generator produces + * a different content than LOREM_genBuffer (even when using same seed). + */ + +#include "loremOut.h" +#include +#include +#include "lorem.h" /* LOREM_genBlock */ +#include "platform.h" /* Compiler options, SET_BINARY_MODE */ + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define LOREM_BLOCKSIZE (1 << 10) +void LOREM_genOut(unsigned long long size, unsigned seed) +{ + char buff[LOREM_BLOCKSIZE] = { 0 }; + unsigned long long total = 0; + size_t genBlockSize = (size_t)MIN(size, LOREM_BLOCKSIZE); + + /* init */ + SET_BINARY_MODE(stdout); + + /* Generate Ipsum text, one paragraph at a time */ + while (total < size) { + size_t generated = + LOREM_genBlock(buff, genBlockSize, seed++, total == 0, 0); + assert(generated <= genBlockSize); + total += generated; + assert(total <= size); + fwrite(buff, + 1, + generated, + stdout); /* note: should check potential write error */ + if (size - total < genBlockSize) + genBlockSize = (size_t)(size - total); + } + assert(total == size); +} diff --git a/src/dependencies/zstd-1.5.6/tests/loremOut.h b/src/dependencies/zstd-1.5.6/tests/loremOut.h new file mode 100644 index 0000000..3a32e11 --- /dev/null +++ b/src/dependencies/zstd-1.5.6/tests/loremOut.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* LOREM_genOut(): + * Generate @size bytes of compressible data using lorem ipsum generator into + * stdout. + */ +void LOREM_genOut(unsigned long long size, unsigned seed); diff --git a/src/dependencies/zstd-1.5.4/tests/paramgrill.c b/src/dependencies/zstd-1.5.6/tests/paramgrill.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/paramgrill.c rename to src/dependencies/zstd-1.5.6/tests/paramgrill.c diff --git a/src/dependencies/zstd-1.5.4/tests/playTests.sh b/src/dependencies/zstd-1.5.6/tests/playTests.sh similarity index 90% rename from src/dependencies/zstd-1.5.4/tests/playTests.sh rename to src/dependencies/zstd-1.5.6/tests/playTests.sh index 5f595f6..e2a0694 100755 --- a/src/dependencies/zstd-1.5.4/tests/playTests.sh +++ b/src/dependencies/zstd-1.5.6/tests/playTests.sh @@ -1,6 +1,7 @@ #!/bin/sh -set -e +set -e # exit immediately on error +# set -x # print commands before execution (debug) unset ZSTD_CLEVEL unset ZSTD_NBTHREADS @@ -16,18 +17,18 @@ datagen() { } zstd() { - if [ -z "$EXEC_PREFIX" ]; then + if [ -z "$EXE_PREFIX" ]; then "$ZSTD_BIN" "$@" else - "$EXEC_PREFIX" "$ZSTD_BIN" "$@" + "$EXE_PREFIX" "$ZSTD_BIN" "$@" fi } sudoZstd() { - if [ -z "$EXEC_PREFIX" ]; then + if [ -z "$EXE_PREFIX" ]; then sudo "$ZSTD_BIN" "$@" else - sudo "$EXEC_PREFIX" "$ZSTD_BIN" "$@" + sudo "$EXE_PREFIX" "$ZSTD_BIN" "$@" fi } @@ -91,7 +92,13 @@ fi SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) PRGDIR="$SCRIPT_DIR/../programs" TESTDIR="$SCRIPT_DIR/../tests" -UNAME=$(uname) +UNAME=${UNAME:-$(uname)} +GREP=${GREP:-grep} + +case "$UNAME" in + SunOS) DIFF=${DIFF:-gdiff} ;; + *) DIFF=${DIFF:-diff} ;; +esac detectedTerminal=false if [ -t 0 ] && [ -t 1 ] @@ -151,11 +158,6 @@ assertSamePermissions() { [ "$STAT1" = "$STAT2" ] || die "permissions on $1 don't match those on $2 ($STAT1 != $STAT2)" } -DIFF="diff" -case "$UNAME" in - SunOS) DIFF="gdiff" ;; -esac - # check if ZSTD_BIN is defined. if not, use the default value if [ -z "${ZSTD_BIN}" ]; then @@ -177,7 +179,7 @@ fi [ -n "$DATAGEN_BIN" ] || die "datagen not found at $DATAGEN_BIN! \n Please define DATAGEN_BIN pointing to the datagen binary. You might also consider rebuilding zstd tests following the instructions in README.md. " println "\nStarting playTests.sh isWindows=$isWindows EXE_PREFIX='$EXE_PREFIX' ZSTD_BIN='$ZSTD_BIN' DATAGEN_BIN='$DATAGEN_BIN'" -if echo hello | zstd -v -T2 2>&1 > $INTOVOID | grep -q 'multi-threading is disabled' +if echo hello | zstd -v -T2 2>&1 > $INTOVOID | $GREP -q 'multi-threading is disabled' then hasMT="" else @@ -232,12 +234,23 @@ unset ZSTD_CLEVEL println "test : compress to stdout" zstd tmp -c > tmpCompressed zstd tmp --stdout > tmpCompressed # long command format -println "test : compress to named file" + +println "test : compress to named file (-o)" rm -f tmpCompressed zstd tmp -o tmpCompressed test -f tmpCompressed # file must be created + println "test : force write, correct order" zstd tmp -fo tmpCompressed + +println "test : -c + -o : last one wins" +rm -f tmpOut +zstd tmp -c > tmpCompressed -o tmpOut +test -f tmpOut # file must be created +rm -f tmpCompressed +zstd tmp -o tmpOut -c > tmpCompressed +test -f tmpCompressed # file must be created + println "test : forgotten argument" cp tmp tmp2 zstd tmp2 -fo && die "-o must be followed by filename " @@ -253,8 +266,8 @@ println "test : null-length file roundtrip" println -n '' | zstd - --stdout | zstd -d --stdout println "test : ensure small file doesn't add 3-bytes null block" datagen -g1 > tmp1 -zstd tmp1 -c | wc -c | grep "14" -zstd < tmp1 | wc -c | grep "14" +zstd tmp1 -c | wc -c | $GREP "14" +zstd < tmp1 | wc -c | $GREP "14" println "test : decompress file with wrong suffix (must fail)" zstd -d tmpCompressed && die "wrong suffix error not detected!" zstd -df tmp && die "should have refused : wrong extension" @@ -291,9 +304,9 @@ println "test: --no-progress flag" zstd tmpro -c --no-progress | zstd -d -f -o "$INTOVOID" --no-progress zstd tmpro -cv --no-progress | zstd -dv -f -o "$INTOVOID" --no-progress println "test: --progress flag" -zstd tmpro -c | zstd -d -f -o "$INTOVOID" --progress 2>&1 | grep -E "[A-Za-z0-9._ ]+: [0-9]+ bytes" -zstd tmpro -c | zstd -d -f -q -o "$INTOVOID" --progress 2>&1 | grep -E "[A-Za-z0-9._ ]+: [0-9]+ bytes" -zstd tmpro -c | zstd -d -f -v -o "$INTOVOID" 2>&1 | grep -E "[A-Za-z0-9._ ]+: [0-9]+ bytes" +zstd tmpro -c | zstd -d -f -o "$INTOVOID" --progress 2>&1 | $GREP '[A-Za-z0-9._ ]*: [0-9]* bytes' +zstd tmpro -c | zstd -d -f -q -o "$INTOVOID" --progress 2>&1 | $GREP '[A-Za-z0-9._ ]*: [0-9]* bytes' +zstd tmpro -c | zstd -d -f -v -o "$INTOVOID" 2>&1 | $GREP '[A-Za-z0-9._ ]*: [0-9]* bytes' rm -f tmpro tmpro.zst println "test: overwrite input file (must fail)" zstd tmp -fo tmp && die "zstd compression overwrote the input file" @@ -320,10 +333,55 @@ zstd -d -f tmp.zst --no-check if [ "$isWindows" = false ] && [ "$UNAME" != "AIX" ]; then if [ -n "$(which readelf)" ]; then println "test: check if binary has executable stack (#2963)" - readelf -lW "$ZSTD_BIN" | grep 'GNU_STACK .* RW ' || die "zstd binary has executable stack!" + readelf -lW "$ZSTD_BIN" | $GREP 'GNU_STACK .* RW ' || die "zstd binary has executable stack!" fi fi +println "\n===> multiple_thread test " + +datagen > tmp +println "test : single-thread " +zstd --fast --single-thread tmp -o tmpMT0 +println "test : one worker thread (default)" +zstd --fast -T1 tmp -o tmpMT1 +println "test : two worker threads " +zstd --fast -T2 tmp -o tmpMT2 +println "test : 16-thread " +zstd --fast -T16 tmp -o tmpMT3 +println "test : 127-thread " +zstd --fast -T127 tmp -o tmpMT4 +println "test : 128-thread " +zstd --fast -T128 tmp -o tmpMT5 +println "test : max allowed numeric value is 4294967295 " +zstd --fast -4294967295 tmp -o tmpMT6 +println "test : numeric value overflows 32-bit unsigned int " +zstd --fast -4294967296 tmp -o tmptest9 && die "max allowed numeric value is 4294967295" + +datagen > tmp +println "test : basic compression " +zstd -f tmp # trivial compression case, creates tmp.zst +println "test : basic decompression" +zstd -d -f -T1 tmp.zst +println "note : decompression does not support -T mode, but execution support" +rm -rf tmpMT* + +println "\n===> --fast_argument test " +datagen > tmp +println "test : basic compression " +zstd -f tmp # trivial compression case, creates tmp.zst +println "test: --fast=1" +zstd --fast=1 -f tmp +println "test: --fast=99" +zstd --fast=99 -f tmp +println "test: Invalid value -- negative number" +zstd --fast=-1 -f tmp && die "error: Invalid value -- negative number" +println "test: Invalid value -- zero" +zstd --fast=0 -f tmp && die "error: Invalid value -- 0 number" +println "test: max allowed numeric argument of --fast is 4294967295" +zstd --fast=4294967295 -f tmp +println "test: numeric value overflows 32-bit unsigned int " +zstd --fast=4294967296 -f tmp && die "max allowed argument of --fast is 4294967295" + println "\n===> --exclude-compressed flag" rm -rf precompressedFilterTestDir mkdir -p precompressedFilterTestDir @@ -352,6 +410,19 @@ zstd --long --rm -r precompressedFilterTestDir # Files should get compressed again without the --exclude-compressed flag. test -f precompressedFilterTestDir/input.5.zst.zst test -f precompressedFilterTestDir/input.6.zst.zst + +# Test some other compressed file extensions +datagen $size > precompressedFilterTestDir/input.flac +datagen $size > precompressedFilterTestDir/input.mov +datagen $size > precompressedFilterTestDir/input.mp3 +zstd --exclude-compressed --long --rm -r precompressedFilterTestDir +test ! -f precompressedFilterTestDir/input.flac.zst +test ! -f precompressedFilterTestDir/input.mov.zst +test ! -f precompressedFilterTestDir/input.mp3.zst +zstd --long --rm -r precompressedFilterTestDir +test -f precompressedFilterTestDir/input.flac.zst +test -f precompressedFilterTestDir/input.mov.zst +test -f precompressedFilterTestDir/input.mp3.zst rm -rf precompressedFilterTestDir println "Test completed" @@ -392,6 +463,8 @@ println "test: --rm is disabled when output is stdout" test -f tmp zstd --rm tmp -c > $INTOVOID test -f tmp # tmp shall still be there +zstd --rm tmp --stdout > $INTOVOID +test -f tmp # tmp shall still be there zstd -f --rm tmp -c > $INTOVOID test -f tmp # tmp shall still be there zstd -f tmp -c > $INTOVOID --rm @@ -409,13 +482,28 @@ zstd -f tmp tmp2 -o tmp3.zst --rm # just warns, no prompt test -f tmp test -f tmp2 zstd -q tmp tmp2 -o tmp3.zst --rm && die "should refuse to concatenate" - +println "test: --rm is active with -o when single input" +rm -f tmp2.zst +zstd --rm tmp2 -o tmp2.zst +test -f tmp2.zst +test ! -f tmp2 +println "test: -c followed by -o => -o wins, so --rm remains active" # (#3719) +rm tmp2.zst +cp tmp tmp2 +zstd --rm tmp2 -c > $INTOVOID -o tmp2.zst +test ! -f tmp2 +println "test: -o followed by -c => -c wins, so --rm is disabled" # (#3719) +rm tmp3.zst +cp tmp tmp2 +zstd -v --rm tmp2 -o tmp2.zst -c > tmp3.zst +test -f tmp2 +test -f tmp3.zst println "test : should quietly not remove non-regular file" println hello > tmp zstd tmp -f -o "$DEVDEVICE" 2>tmplog > "$INTOVOID" -grep "Refusing to remove non-regular file" tmplog && die +$GREP "Refusing to remove non-regular file" tmplog && die rm -f tmplog -zstd tmp -f -o "$INTOVOID" 2>&1 | grep "Refusing to remove non-regular file" && die +zstd tmp -f -o "$INTOVOID" 2>&1 | $GREP "Refusing to remove non-regular file" && die println "test : --rm on stdin" println a | zstd --rm > $INTOVOID # --rm should remain silent rm -f tmp @@ -444,6 +532,11 @@ $DIFF -s tmp1 tmp touch tmp_empty zstd -d -o tmp2 "$TESTDIR/golden-decompression/empty-block.zst" $DIFF -s tmp2 tmp_empty + +zstd -t "$TESTDIR/golden-decompression/zeroSeq_2B.zst" + +zstd -t "$TESTDIR/golden-decompression-errors/zeroSeq_extraneous.zst" && die "invalid Sequences section should have been detected" + rm -f tmp* println "\n===> compress multiple files" @@ -610,7 +703,7 @@ if [ -n "$DEVNULLRIGHTS" ] ; then zstd tmp -f -o tmp.zst sudoZstd -d tmp.zst -c > $INTOVOID sudoZstd -d tmp.zst -o $INTOVOID - ls -las $INTOVOID | grep "rw-rw-rw-" + ls -las $INTOVOID | $GREP "rw-rw-rw-" fi if [ -n "$READFROMBLOCKDEVICE" ] ; then @@ -620,7 +713,7 @@ if [ -n "$READFROMBLOCKDEVICE" ] ; then println "\n===> checking that zstd can read from a block device" datagen -g65536 > tmp.img sudo losetup -fP tmp.img - LOOP_DEV=$(losetup -a | grep 'tmp\.img' | cut -f1 -d:) + LOOP_DEV=$(losetup -a | $GREP 'tmp\.img' | cut -f1 -d:) [ -z "$LOOP_DEV" ] && die "failed to get loopback device" sudoZstd $LOOP_DEV -c > tmp.img.zst && die "should fail without -f" sudoZstd -f $LOOP_DEV -c > tmp.img.zst @@ -769,13 +862,13 @@ println "\n===> --[no-]content-size tests" datagen > tmp_contentsize zstd -f tmp_contentsize -zstd -lv tmp_contentsize.zst | grep "Decompressed Size:" +zstd -lv tmp_contentsize.zst | $GREP "Decompressed Size:" zstd -f --no-content-size tmp_contentsize -zstd -lv tmp_contentsize.zst | grep "Decompressed Size:" && die +zstd -lv tmp_contentsize.zst | $GREP "Decompressed Size:" && die zstd -f --content-size tmp_contentsize -zstd -lv tmp_contentsize.zst | grep "Decompressed Size:" +zstd -lv tmp_contentsize.zst | $GREP "Decompressed Size:" zstd -f --content-size --no-content-size tmp_contentsize -zstd -lv tmp_contentsize.zst | grep "Decompressed Size:" && die +zstd -lv tmp_contentsize.zst | $GREP "Decompressed Size:" && die rm -rf tmp* println "test : show-default-cparams regular" @@ -795,8 +888,7 @@ rm -rf tmp* println "test : show compression parameters in verbose mode" datagen > tmp zstd -vv tmp 2>&1 | \ -grep -q -E -- "--zstd=wlog=[[:digit:]]+,clog=[[:digit:]]+,hlog=[[:digit:]]+,\ -slog=[[:digit:]]+,mml=[[:digit:]]+,tlen=[[:digit:]]+,strat=[[:digit:]]+" +$GREP -q -- "--zstd=wlog=[0-9]*,clog=[0-9]*,hlog=[0-9]*,slog=[0-9]*,mml=[0-9]*,tlen=[0-9]*,strat=[0-9]*" rm -rf tmp* println "\n===> Advanced compression parameters " @@ -1093,8 +1185,8 @@ println "- Test --memory for dictionary compression" datagen -g12M -P90 > tmpCorpusHighCompress zstd --train -B2K tmpCorpusHighCompress -o tmpDictHighCompress --memory=10K && die "Dictionary training should fail : --memory too low (10K)" zstd --train -B2K tmpCorpusHighCompress -o tmpDictHighCompress --memory=5MB 2> zstTrainWithMemLimitStdErr -cat zstTrainWithMemLimitStdErr | grep "setting manual memory limit for dictionary training data at 5 MB" -cat zstTrainWithMemLimitStdErr | grep "Training samples set too large (12 MB); training on 5 MB only..." +cat zstTrainWithMemLimitStdErr | $GREP "setting manual memory limit for dictionary training data at 5 MB" +cat zstTrainWithMemLimitStdErr | $GREP "Training samples set too large (12 MB); training on 5 MB only..." rm zstTrainWithMemLimitStdErr println "\n===> fastCover dictionary builder : advanced options " @@ -1380,16 +1472,16 @@ println "\n===> suffix list test" ! zstd -d tmp.abc 2> tmplg if [ $GZIPMODE -ne 1 ]; then - grep ".gz" tmplg > $INTOVOID && die "Unsupported suffix listed" + $GREP ".gz" tmplg > $INTOVOID && die "Unsupported suffix listed" fi if [ $LZMAMODE -ne 1 ]; then - grep ".lzma" tmplg > $INTOVOID && die "Unsupported suffix listed" - grep ".xz" tmplg > $INTOVOID && die "Unsupported suffix listed" + $GREP ".lzma" tmplg > $INTOVOID && die "Unsupported suffix listed" + $GREP ".xz" tmplg > $INTOVOID && die "Unsupported suffix listed" fi if [ $LZ4MODE -ne 1 ]; then - grep ".lz4" tmplg > $INTOVOID && die "Unsupported suffix listed" + $GREP ".lz4" tmplg > $INTOVOID && die "Unsupported suffix listed" fi touch tmp1 @@ -1518,7 +1610,7 @@ datagen > tmp2 datagen > tmp3 zstd tmp* zstd -l ./*.zst -zstd -lv ./*.zst | grep "Decompressed Size:" # check that decompressed size is present in header +zstd -lv ./*.zst | $GREP "Decompressed Size:" # check that decompressed size is present in header zstd --list ./*.zst zstd --list -v ./*.zst @@ -1561,13 +1653,13 @@ datagen -g0 > tmp5 zstd tmp5 zstd -l tmp5.zst zstd -l tmp5* && die "-l must fail on non-zstd file" -zstd -lv tmp5.zst | grep "Decompressed Size: 0 B (0 B)" # check that 0 size is present in header +zstd -lv tmp5.zst | $GREP "Decompressed Size: 0 B (0 B)" # check that 0 size is present in header zstd -lv tmp5* && die "-l must fail on non-zstd file" println "\n===> zstd --list/-l test with no content size field " datagen -g513K | zstd > tmp6.zst zstd -l tmp6.zst -zstd -lv tmp6.zst | grep "Decompressed Size:" && die "Field :Decompressed Size: should not be available in this compressed file" +zstd -lv tmp6.zst | $GREP "Decompressed Size:" && die "Field :Decompressed Size: should not be available in this compressed file" println "\n===> zstd --list/-l test with no checksum " zstd -f --no-check tmp1 @@ -1602,22 +1694,24 @@ roundTripTest -g1M -P50 "1 --single-thread --long=29" " --long=28 --memory=512MB roundTripTest -g1M -P50 "1 --single-thread --long=29" " --zstd=wlog=28 --memory=512MB" -println "\n===> zstd long distance matching with optimal parser compressed size tests " -optCSize16=$(datagen -g511K | zstd -16 -c | wc -c) -longCSize16=$(datagen -g511K | zstd -16 --long -c | wc -c) -optCSize19=$(datagen -g2M | zstd -19 -c | wc -c) -longCSize19=$(datagen -g2M | zstd -19 --long -c | wc -c) -optCSize19wlog23=$(datagen -g2M | zstd -19 -c --zstd=wlog=23 | wc -c) -longCSize19wlog23=$(datagen -g2M | zstd -19 -c --long=23 | wc -c) -if [ "$longCSize16" -gt "$optCSize16" ]; then - echo using --long on compression level 16 should not cause compressed size regression - exit 1 -elif [ "$longCSize19" -gt "$optCSize19" ]; then - echo using --long on compression level 19 should not cause compressed size regression - exit 1 -elif [ "$longCSize19wlog23" -gt "$optCSize19wlog23" ]; then - echo using --long on compression level 19 with wLog=23 should not cause compressed size regression - exit 1 +if [ "$ZSTD_LIB_EXCLUDE_COMPRESSORS_DFAST_AND_UP" -ne "1" ]; then + println "\n===> zstd long distance matching with optimal parser compressed size tests " + optCSize16=$(datagen -g511K | zstd -16 -c | wc -c) + longCSize16=$(datagen -g511K | zstd -16 --long -c | wc -c) + optCSize19=$(datagen -g2M | zstd -19 -c | wc -c) + longCSize19=$(datagen -g2M | zstd -19 --long -c | wc -c) + optCSize19wlog23=$(datagen -g2M | zstd -19 -c --zstd=wlog=23 | wc -c) + longCSize19wlog23=$(datagen -g2M | zstd -19 -c --long=23 | wc -c) + if [ "$longCSize16" -gt "$optCSize16" ]; then + echo using --long on compression level 16 should not cause compressed size regression + exit 1 + elif [ "$longCSize19" -gt "$optCSize19" ]; then + echo using --long on compression level 19 should not cause compressed size regression + exit 1 + elif [ "$longCSize19wlog23" -gt "$optCSize19wlog23" ]; then + echo using --long on compression level 19 with wLog=23 should not cause compressed size regression + exit 1 + fi fi println "\n===> zstd asyncio tests " @@ -1708,9 +1802,15 @@ zstd --patch-from=tmp_dict -r tmp_dir && die rm -rf tmp* println "\n===> patch-from long mode trigger larger file test" -datagen -g5000000 > tmp_dict -datagen -g5000000 > tmp_patch -zstd -15 --patch-from=tmp_dict tmp_patch 2>&1 | grep "long mode automatically triggered" +if [ "$ZSTD_LIB_EXCLUDE_COMPRESSORS_DFAST_AND_UP" -eq "1" ]; then + # if binary tree strategies are excluded, the threshold is different + datagen -g10000000 > tmp_dict + datagen -g10000000 > tmp_patch +else + datagen -g5000000 > tmp_dict + datagen -g5000000 > tmp_patch +fi +zstd -15 --patch-from=tmp_dict tmp_patch 2>&1 | $GREP "long mode automatically triggered" rm -rf tmp* println "\n===> patch-from very large dictionary and file test" diff --git a/src/dependencies/zstd-1.5.4/tests/poolTests.c b/src/dependencies/zstd-1.5.6/tests/poolTests.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/poolTests.c rename to src/dependencies/zstd-1.5.6/tests/poolTests.c diff --git a/src/dependencies/zstd-1.5.4/tests/rateLimiter.py b/src/dependencies/zstd-1.5.6/tests/rateLimiter.py similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/rateLimiter.py rename to src/dependencies/zstd-1.5.6/tests/rateLimiter.py diff --git a/src/dependencies/zstd-1.5.4/tests/regression/.gitignore b/src/dependencies/zstd-1.5.6/tests/regression/.gitignore similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/regression/.gitignore rename to src/dependencies/zstd-1.5.6/tests/regression/.gitignore diff --git a/src/dependencies/zstd-1.5.4/tests/regression/Makefile b/src/dependencies/zstd-1.5.6/tests/regression/Makefile similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/regression/Makefile rename to src/dependencies/zstd-1.5.6/tests/regression/Makefile diff --git a/src/dependencies/zstd-1.5.4/tests/regression/README.md b/src/dependencies/zstd-1.5.6/tests/regression/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/regression/README.md rename to src/dependencies/zstd-1.5.6/tests/regression/README.md diff --git a/src/dependencies/zstd-1.5.4/tests/regression/config.c b/src/dependencies/zstd-1.5.6/tests/regression/config.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/regression/config.c rename to src/dependencies/zstd-1.5.6/tests/regression/config.c diff --git a/src/dependencies/zstd-1.5.4/tests/regression/config.h b/src/dependencies/zstd-1.5.6/tests/regression/config.h similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/regression/config.h rename to src/dependencies/zstd-1.5.6/tests/regression/config.h diff --git a/src/dependencies/zstd-1.5.4/tests/regression/data.c b/src/dependencies/zstd-1.5.6/tests/regression/data.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/regression/data.c rename to src/dependencies/zstd-1.5.6/tests/regression/data.c diff --git a/src/dependencies/zstd-1.5.4/tests/regression/data.h b/src/dependencies/zstd-1.5.6/tests/regression/data.h similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/regression/data.h rename to src/dependencies/zstd-1.5.6/tests/regression/data.h diff --git a/src/dependencies/zstd-1.5.4/tests/regression/levels.h b/src/dependencies/zstd-1.5.6/tests/regression/levels.h similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/regression/levels.h rename to src/dependencies/zstd-1.5.6/tests/regression/levels.h diff --git a/src/dependencies/zstd-1.5.4/tests/regression/method.c b/src/dependencies/zstd-1.5.6/tests/regression/method.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/regression/method.c rename to src/dependencies/zstd-1.5.6/tests/regression/method.c diff --git a/src/dependencies/zstd-1.5.4/tests/regression/method.h b/src/dependencies/zstd-1.5.6/tests/regression/method.h similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/regression/method.h rename to src/dependencies/zstd-1.5.6/tests/regression/method.h diff --git a/src/dependencies/zstd-1.5.4/tests/regression/result.c b/src/dependencies/zstd-1.5.6/tests/regression/result.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/regression/result.c rename to src/dependencies/zstd-1.5.6/tests/regression/result.c diff --git a/src/dependencies/zstd-1.5.4/tests/regression/result.h b/src/dependencies/zstd-1.5.6/tests/regression/result.h similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/regression/result.h rename to src/dependencies/zstd-1.5.6/tests/regression/result.h diff --git a/src/dependencies/zstd-1.5.4/tests/regression/results.csv b/src/dependencies/zstd-1.5.6/tests/regression/results.csv similarity index 83% rename from src/dependencies/zstd-1.5.4/tests/regression/results.csv rename to src/dependencies/zstd-1.5.6/tests/regression/results.csv index 188eea9..fc3fbe7 100644 --- a/src/dependencies/zstd-1.5.4/tests/regression/results.csv +++ b/src/dependencies/zstd-1.5.6/tests/regression/results.csv @@ -6,15 +6,15 @@ silesia.tar, level 0, compress silesia.tar, level 1, compress simple, 5327717 silesia.tar, level 3, compress simple, 4854086 silesia.tar, level 4, compress simple, 4791503 -silesia.tar, level 5, compress simple, 4677740 -silesia.tar, level 6, compress simple, 4613242 -silesia.tar, level 7, compress simple, 4576661 -silesia.tar, level 9, compress simple, 4552899 +silesia.tar, level 5, compress simple, 4679004 +silesia.tar, level 6, compress simple, 4614561 +silesia.tar, level 7, compress simple, 4579828 +silesia.tar, level 9, compress simple, 4555448 silesia.tar, level 13, compress simple, 4502956 -silesia.tar, level 16, compress simple, 4360546 -silesia.tar, level 19, compress simple, 4265911 +silesia.tar, level 16, compress simple, 4360385 +silesia.tar, level 19, compress simple, 4260939 silesia.tar, uncompressed literals, compress simple, 4854086 -silesia.tar, uncompressed literals optimal, compress simple, 4265911 +silesia.tar, uncompressed literals optimal, compress simple, 4260939 silesia.tar, huffman literals, compress simple, 6179047 github.tar, level -5, compress simple, 52115 github.tar, level -3, compress simple, 45678 @@ -25,13 +25,13 @@ github.tar, level 3, compress github.tar, level 4, compress simple, 38893 github.tar, level 5, compress simple, 39651 github.tar, level 6, compress simple, 39282 -github.tar, level 7, compress simple, 38110 -github.tar, level 9, compress simple, 36760 +github.tar, level 7, compress simple, 38005 +github.tar, level 9, compress simple, 36723 github.tar, level 13, compress simple, 35501 github.tar, level 16, compress simple, 40466 -github.tar, level 19, compress simple, 32276 +github.tar, level 19, compress simple, 32262 github.tar, uncompressed literals, compress simple, 38831 -github.tar, uncompressed literals optimal, compress simple, 32276 +github.tar, uncompressed literals optimal, compress simple, 32262 github.tar, huffman literals, compress simple, 42560 silesia, level -5, compress cctx, 6857372 silesia, level -3, compress cctx, 6503412 @@ -40,52 +40,52 @@ silesia, level 0, compress silesia, level 1, compress cctx, 5306632 silesia, level 3, compress cctx, 4842075 silesia, level 4, compress cctx, 4779186 -silesia, level 5, compress cctx, 4666323 -silesia, level 6, compress cctx, 4603066 -silesia, level 7, compress cctx, 4566984 -silesia, level 9, compress cctx, 4543018 +silesia, level 5, compress cctx, 4667668 +silesia, level 6, compress cctx, 4604351 +silesia, level 7, compress cctx, 4570271 +silesia, level 9, compress cctx, 4545850 silesia, level 13, compress cctx, 4493990 -silesia, level 16, compress cctx, 4360041 -silesia, level 19, compress cctx, 4296055 +silesia, level 16, compress cctx, 4359652 +silesia, level 19, compress cctx, 4266582 silesia, long distance mode, compress cctx, 4842075 silesia, multithreaded, compress cctx, 4842075 silesia, multithreaded long distance mode, compress cctx, 4842075 silesia, small window log, compress cctx, 7082951 silesia, small hash log, compress cctx, 6526141 silesia, small chain log, compress cctx, 4912197 -silesia, explicit params, compress cctx, 4794052 +silesia, explicit params, compress cctx, 4794318 silesia, uncompressed literals, compress cctx, 4842075 -silesia, uncompressed literals optimal, compress cctx, 4296055 +silesia, uncompressed literals optimal, compress cctx, 4266582 silesia, huffman literals, compress cctx, 6172202 silesia, multithreaded with advanced params, compress cctx, 4842075 github, level -5, compress cctx, 204407 -github, level -5 with dict, compress cctx, 52059 +github, level -5 with dict, compress cctx, 47581 github, level -3, compress cctx, 193253 -github, level -3 with dict, compress cctx, 46787 +github, level -3 with dict, compress cctx, 43043 github, level -1, compress cctx, 175468 -github, level -1 with dict, compress cctx, 43585 +github, level -1 with dict, compress cctx, 42044 github, level 0, compress cctx, 136332 github, level 0 with dict, compress cctx, 41534 github, level 1, compress cctx, 142365 -github, level 1 with dict, compress cctx, 42259 +github, level 1 with dict, compress cctx, 41715 github, level 3, compress cctx, 136332 github, level 3 with dict, compress cctx, 41534 github, level 4, compress cctx, 136199 github, level 4 with dict, compress cctx, 41725 github, level 5, compress cctx, 135121 -github, level 5 with dict, compress cctx, 38759 +github, level 5 with dict, compress cctx, 38755 github, level 6, compress cctx, 135122 -github, level 6 with dict, compress cctx, 38669 +github, level 6 with dict, compress cctx, 38665 github, level 7, compress cctx, 135122 -github, level 7 with dict, compress cctx, 38755 +github, level 7 with dict, compress cctx, 38759 github, level 9, compress cctx, 135122 -github, level 9 with dict, compress cctx, 39398 +github, level 9 with dict, compress cctx, 39362 github, level 13, compress cctx, 132878 github, level 13 with dict, compress cctx, 39948 github, level 16, compress cctx, 133209 -github, level 16 with dict, compress cctx, 37568 +github, level 16 with dict, compress cctx, 37892 github, level 19, compress cctx, 132879 -github, level 19 with dict, compress cctx, 37567 +github, level 19 with dict, compress cctx, 37906 github, long distance mode, compress cctx, 141069 github, multithreaded, compress cctx, 141069 github, multithreaded long distance mode, compress cctx, 141069 @@ -104,22 +104,22 @@ silesia, level 0, zstdcli, silesia, level 1, zstdcli, 5306680 silesia, level 3, zstdcli, 4842123 silesia, level 4, zstdcli, 4779234 -silesia, level 5, zstdcli, 4666371 -silesia, level 6, zstdcli, 4603114 -silesia, level 7, zstdcli, 4567032 -silesia, level 9, zstdcli, 4543066 +silesia, level 5, zstdcli, 4667716 +silesia, level 6, zstdcli, 4604399 +silesia, level 7, zstdcli, 4570319 +silesia, level 9, zstdcli, 4545898 silesia, level 13, zstdcli, 4494038 -silesia, level 16, zstdcli, 4360089 -silesia, level 19, zstdcli, 4296103 +silesia, level 16, zstdcli, 4359700 +silesia, level 19, zstdcli, 4266630 silesia, long distance mode, zstdcli, 4833785 silesia, multithreaded, zstdcli, 4842123 silesia, multithreaded long distance mode, zstdcli, 4833785 silesia, small window log, zstdcli, 7095048 silesia, small hash log, zstdcli, 6526189 silesia, small chain log, zstdcli, 4912245 -silesia, explicit params, zstdcli, 4795432 +silesia, explicit params, zstdcli, 4795840 silesia, uncompressed literals, zstdcli, 5120614 -silesia, uncompressed literals optimal, zstdcli, 4319566 +silesia, uncompressed literals optimal, zstdcli, 4316928 silesia, huffman literals, zstdcli, 5321417 silesia, multithreaded with advanced params, zstdcli, 5120614 silesia.tar, level -5, zstdcli, 6862049 @@ -129,13 +129,13 @@ silesia.tar, level 0, zstdcli, silesia.tar, level 1, zstdcli, 5329010 silesia.tar, level 3, zstdcli, 4854164 silesia.tar, level 4, zstdcli, 4792352 -silesia.tar, level 5, zstdcli, 4678682 -silesia.tar, level 6, zstdcli, 4614125 -silesia.tar, level 7, zstdcli, 4578719 -silesia.tar, level 9, zstdcli, 4552903 +silesia.tar, level 5, zstdcli, 4679860 +silesia.tar, level 6, zstdcli, 4615355 +silesia.tar, level 7, zstdcli, 4581791 +silesia.tar, level 9, zstdcli, 4555452 silesia.tar, level 13, zstdcli, 4502960 -silesia.tar, level 16, zstdcli, 4360550 -silesia.tar, level 19, zstdcli, 4265915 +silesia.tar, level 16, zstdcli, 4360389 +silesia.tar, level 19, zstdcli, 4260943 silesia.tar, no source size, zstdcli, 4854160 silesia.tar, long distance mode, zstdcli, 4845745 silesia.tar, multithreaded, zstdcli, 4854164 @@ -143,21 +143,21 @@ silesia.tar, multithreaded long distance mode, zstdcli, silesia.tar, small window log, zstdcli, 7100701 silesia.tar, small hash log, zstdcli, 6529264 silesia.tar, small chain log, zstdcli, 4917022 -silesia.tar, explicit params, zstdcli, 4820713 +silesia.tar, explicit params, zstdcli, 4821112 silesia.tar, uncompressed literals, zstdcli, 5122571 -silesia.tar, uncompressed literals optimal, zstdcli, 4310145 +silesia.tar, uncompressed literals optimal, zstdcli, 4308455 silesia.tar, huffman literals, zstdcli, 5342074 silesia.tar, multithreaded with advanced params, zstdcli, 5122571 github, level -5, zstdcli, 206407 -github, level -5 with dict, zstdcli, 48718 +github, level -5 with dict, zstdcli, 47832 github, level -3, zstdcli, 195253 -github, level -3 with dict, zstdcli, 47395 +github, level -3 with dict, zstdcli, 46671 github, level -1, zstdcli, 177468 -github, level -1 with dict, zstdcli, 45170 +github, level -1 with dict, zstdcli, 43825 github, level 0, zstdcli, 138332 github, level 0 with dict, zstdcli, 43148 github, level 1, zstdcli, 144365 -github, level 1 with dict, zstdcli, 43682 +github, level 1 with dict, zstdcli, 43266 github, level 3, zstdcli, 138332 github, level 3 with dict, zstdcli, 43148 github, level 4, zstdcli, 138199 @@ -165,17 +165,17 @@ github, level 4 with dict, zstdcli, github, level 5, zstdcli, 137121 github, level 5 with dict, zstdcli, 40728 github, level 6, zstdcli, 137122 -github, level 6 with dict, zstdcli, 40636 +github, level 6 with dict, zstdcli, 40638 github, level 7, zstdcli, 137122 -github, level 7 with dict, zstdcli, 40745 +github, level 7 with dict, zstdcli, 40749 github, level 9, zstdcli, 137122 github, level 9 with dict, zstdcli, 41393 github, level 13, zstdcli, 134878 github, level 13 with dict, zstdcli, 41900 github, level 16, zstdcli, 135209 -github, level 16 with dict, zstdcli, 39577 +github, level 16 with dict, zstdcli, 39902 github, level 19, zstdcli, 134879 -github, level 19 with dict, zstdcli, 39576 +github, level 19 with dict, zstdcli, 39916 github, long distance mode, zstdcli, 138332 github, multithreaded, zstdcli, 138332 github, multithreaded long distance mode, zstdcli, 138332 @@ -188,33 +188,33 @@ github, uncompressed literals optimal, zstdcli, github, huffman literals, zstdcli, 144365 github, multithreaded with advanced params, zstdcli, 167911 github.tar, level -5, zstdcli, 52119 -github.tar, level -5 with dict, zstdcli, 50978 +github.tar, level -5 with dict, zstdcli, 51101 github.tar, level -3, zstdcli, 45682 -github.tar, level -3 with dict, zstdcli, 44660 +github.tar, level -3 with dict, zstdcli, 44738 github.tar, level -1, zstdcli, 42564 -github.tar, level -1 with dict, zstdcli, 41155 +github.tar, level -1 with dict, zstdcli, 41357 github.tar, level 0, zstdcli, 38835 github.tar, level 0 with dict, zstdcli, 37999 github.tar, level 1, zstdcli, 39204 -github.tar, level 1 with dict, zstdcli, 38093 +github.tar, level 1 with dict, zstdcli, 38123 github.tar, level 3, zstdcli, 38835 github.tar, level 3 with dict, zstdcli, 37999 github.tar, level 4, zstdcli, 38897 github.tar, level 4 with dict, zstdcli, 37952 github.tar, level 5, zstdcli, 39655 -github.tar, level 5 with dict, zstdcli, 39071 +github.tar, level 5 with dict, zstdcli, 39073 github.tar, level 6, zstdcli, 39286 -github.tar, level 6 with dict, zstdcli, 38638 -github.tar, level 7, zstdcli, 38114 -github.tar, level 7 with dict, zstdcli, 37886 -github.tar, level 9, zstdcli, 36764 -github.tar, level 9 with dict, zstdcli, 36632 +github.tar, level 6 with dict, zstdcli, 38647 +github.tar, level 7, zstdcli, 38009 +github.tar, level 7 with dict, zstdcli, 37861 +github.tar, level 9, zstdcli, 36727 +github.tar, level 9 with dict, zstdcli, 36686 github.tar, level 13, zstdcli, 35505 github.tar, level 13 with dict, zstdcli, 37134 github.tar, level 16, zstdcli, 40470 -github.tar, level 16 with dict, zstdcli, 33378 -github.tar, level 19, zstdcli, 32280 -github.tar, level 19 with dict, zstdcli, 32716 +github.tar, level 16 with dict, zstdcli, 33379 +github.tar, level 19, zstdcli, 32266 +github.tar, level 19 with dict, zstdcli, 32705 github.tar, no source size, zstdcli, 38832 github.tar, no source size with dict, zstdcli, 38004 github.tar, long distance mode, zstdcli, 40236 @@ -225,7 +225,7 @@ github.tar, small hash log, zstdcli, github.tar, small chain log, zstdcli, 41673 github.tar, explicit params, zstdcli, 41385 github.tar, uncompressed literals, zstdcli, 41529 -github.tar, uncompressed literals optimal, zstdcli, 35401 +github.tar, uncompressed literals optimal, zstdcli, 35360 github.tar, huffman literals, zstdcli, 38857 github.tar, multithreaded with advanced params, zstdcli, 41529 silesia, level -5, advanced one pass, 6857372 @@ -235,21 +235,21 @@ silesia, level 0, advanced silesia, level 1, advanced one pass, 5306632 silesia, level 3, advanced one pass, 4842075 silesia, level 4, advanced one pass, 4779186 -silesia, level 5 row 1, advanced one pass, 4666323 -silesia, level 5 row 2, advanced one pass, 4670136 -silesia, level 5, advanced one pass, 4666323 -silesia, level 6, advanced one pass, 4603066 -silesia, level 7 row 1, advanced one pass, 4566984 -silesia, level 7 row 2, advanced one pass, 4564868 -silesia, level 7, advanced one pass, 4566984 -silesia, level 9, advanced one pass, 4543018 -silesia, level 11 row 1, advanced one pass, 4505046 -silesia, level 11 row 2, advanced one pass, 4503116 -silesia, level 12 row 1, advanced one pass, 4505046 -silesia, level 12 row 2, advanced one pass, 4503116 +silesia, level 5 row 1, advanced one pass, 4667668 +silesia, level 5 row 2, advanced one pass, 4670326 +silesia, level 5, advanced one pass, 4667668 +silesia, level 6, advanced one pass, 4604351 +silesia, level 7 row 1, advanced one pass, 4570271 +silesia, level 7 row 2, advanced one pass, 4565169 +silesia, level 7, advanced one pass, 4570271 +silesia, level 9, advanced one pass, 4545850 +silesia, level 11 row 1, advanced one pass, 4505658 +silesia, level 11 row 2, advanced one pass, 4503429 +silesia, level 12 row 1, advanced one pass, 4505658 +silesia, level 12 row 2, advanced one pass, 4503429 silesia, level 13, advanced one pass, 4493990 -silesia, level 16, advanced one pass, 4360041 -silesia, level 19, advanced one pass, 4296055 +silesia, level 16, advanced one pass, 4359652 +silesia, level 19, advanced one pass, 4266582 silesia, no source size, advanced one pass, 4842075 silesia, long distance mode, advanced one pass, 4833710 silesia, multithreaded, advanced one pass, 4842075 @@ -257,9 +257,9 @@ silesia, multithreaded long distance mode, advanced silesia, small window log, advanced one pass, 7095000 silesia, small hash log, advanced one pass, 6526141 silesia, small chain log, advanced one pass, 4912197 -silesia, explicit params, advanced one pass, 4795432 +silesia, explicit params, advanced one pass, 4795840 silesia, uncompressed literals, advanced one pass, 5120566 -silesia, uncompressed literals optimal, advanced one pass, 4319518 +silesia, uncompressed literals optimal, advanced one pass, 4316880 silesia, huffman literals, advanced one pass, 5321369 silesia, multithreaded with advanced params, advanced one pass, 5120566 silesia.tar, level -5, advanced one pass, 6861055 @@ -269,21 +269,21 @@ silesia.tar, level 0, advanced silesia.tar, level 1, advanced one pass, 5327717 silesia.tar, level 3, advanced one pass, 4854086 silesia.tar, level 4, advanced one pass, 4791503 -silesia.tar, level 5 row 1, advanced one pass, 4677740 -silesia.tar, level 5 row 2, advanced one pass, 4682161 -silesia.tar, level 5, advanced one pass, 4677740 -silesia.tar, level 6, advanced one pass, 4613242 -silesia.tar, level 7 row 1, advanced one pass, 4576661 -silesia.tar, level 7 row 2, advanced one pass, 4575393 -silesia.tar, level 7, advanced one pass, 4576661 -silesia.tar, level 9, advanced one pass, 4552899 -silesia.tar, level 11 row 1, advanced one pass, 4514432 -silesia.tar, level 11 row 2, advanced one pass, 4513604 -silesia.tar, level 12 row 1, advanced one pass, 4514049 -silesia.tar, level 12 row 2, advanced one pass, 4513797 +silesia.tar, level 5 row 1, advanced one pass, 4679004 +silesia.tar, level 5 row 2, advanced one pass, 4682334 +silesia.tar, level 5, advanced one pass, 4679004 +silesia.tar, level 6, advanced one pass, 4614561 +silesia.tar, level 7 row 1, advanced one pass, 4579828 +silesia.tar, level 7 row 2, advanced one pass, 4575602 +silesia.tar, level 7, advanced one pass, 4579828 +silesia.tar, level 9, advanced one pass, 4555448 +silesia.tar, level 11 row 1, advanced one pass, 4514962 +silesia.tar, level 11 row 2, advanced one pass, 4513816 +silesia.tar, level 12 row 1, advanced one pass, 4514517 +silesia.tar, level 12 row 2, advanced one pass, 4514007 silesia.tar, level 13, advanced one pass, 4502956 -silesia.tar, level 16, advanced one pass, 4360546 -silesia.tar, level 19, advanced one pass, 4265911 +silesia.tar, level 16, advanced one pass, 4360385 +silesia.tar, level 19, advanced one pass, 4260939 silesia.tar, no source size, advanced one pass, 4854086 silesia.tar, long distance mode, advanced one pass, 4840452 silesia.tar, multithreaded, advanced one pass, 4854160 @@ -291,105 +291,105 @@ silesia.tar, multithreaded long distance mode, advanced silesia.tar, small window log, advanced one pass, 7100655 silesia.tar, small hash log, advanced one pass, 6529206 silesia.tar, small chain log, advanced one pass, 4917041 -silesia.tar, explicit params, advanced one pass, 4806855 +silesia.tar, explicit params, advanced one pass, 4807274 silesia.tar, uncompressed literals, advanced one pass, 5122473 -silesia.tar, uncompressed literals optimal, advanced one pass, 4310141 +silesia.tar, uncompressed literals optimal, advanced one pass, 4308451 silesia.tar, huffman literals, advanced one pass, 5341705 silesia.tar, multithreaded with advanced params, advanced one pass, 5122567 github, level -5, advanced one pass, 204407 -github, level -5 with dict, advanced one pass, 46718 +github, level -5 with dict, advanced one pass, 45832 github, level -3, advanced one pass, 193253 -github, level -3 with dict, advanced one pass, 45395 +github, level -3 with dict, advanced one pass, 44671 github, level -1, advanced one pass, 175468 -github, level -1 with dict, advanced one pass, 43170 +github, level -1 with dict, advanced one pass, 41825 github, level 0, advanced one pass, 136332 github, level 0 with dict, advanced one pass, 41148 github, level 0 with dict dms, advanced one pass, 41148 github, level 0 with dict dds, advanced one pass, 41148 github, level 0 with dict copy, advanced one pass, 41124 -github, level 0 with dict load, advanced one pass, 42252 +github, level 0 with dict load, advanced one pass, 41847 github, level 1, advanced one pass, 142365 -github, level 1 with dict, advanced one pass, 41682 -github, level 1 with dict dms, advanced one pass, 41682 -github, level 1 with dict dds, advanced one pass, 41682 -github, level 1 with dict copy, advanced one pass, 41698 -github, level 1 with dict load, advanced one pass, 43814 +github, level 1 with dict, advanced one pass, 41266 +github, level 1 with dict dms, advanced one pass, 41266 +github, level 1 with dict dds, advanced one pass, 41266 +github, level 1 with dict copy, advanced one pass, 41279 +github, level 1 with dict load, advanced one pass, 43331 github, level 3, advanced one pass, 136332 github, level 3 with dict, advanced one pass, 41148 github, level 3 with dict dms, advanced one pass, 41148 github, level 3 with dict dds, advanced one pass, 41148 github, level 3 with dict copy, advanced one pass, 41124 -github, level 3 with dict load, advanced one pass, 42252 +github, level 3 with dict load, advanced one pass, 41847 github, level 4, advanced one pass, 136199 github, level 4 with dict, advanced one pass, 41251 github, level 4 with dict dms, advanced one pass, 41251 github, level 4 with dict dds, advanced one pass, 41251 github, level 4 with dict copy, advanced one pass, 41216 -github, level 4 with dict load, advanced one pass, 41159 +github, level 4 with dict load, advanced one pass, 41548 github, level 5 row 1, advanced one pass, 134584 -github, level 5 row 1 with dict dms, advanced one pass, 38758 +github, level 5 row 1 with dict dms, advanced one pass, 38754 github, level 5 row 1 with dict dds, advanced one pass, 38728 -github, level 5 row 1 with dict copy, advanced one pass, 38759 -github, level 5 row 1 with dict load, advanced one pass, 41518 +github, level 5 row 1 with dict copy, advanced one pass, 38755 +github, level 5 row 1 with dict load, advanced one pass, 41899 github, level 5 row 2, advanced one pass, 135121 github, level 5 row 2 with dict dms, advanced one pass, 38938 github, level 5 row 2 with dict dds, advanced one pass, 38732 github, level 5 row 2 with dict copy, advanced one pass, 38934 -github, level 5 row 2 with dict load, advanced one pass, 40725 +github, level 5 row 2 with dict load, advanced one pass, 41248 github, level 5, advanced one pass, 135121 -github, level 5 with dict, advanced one pass, 38758 -github, level 5 with dict dms, advanced one pass, 38758 +github, level 5 with dict, advanced one pass, 38754 +github, level 5 with dict dms, advanced one pass, 38754 github, level 5 with dict dds, advanced one pass, 38728 -github, level 5 with dict copy, advanced one pass, 38759 -github, level 5 with dict load, advanced one pass, 40725 +github, level 5 with dict copy, advanced one pass, 38755 +github, level 5 with dict load, advanced one pass, 41248 github, level 6, advanced one pass, 135122 -github, level 6 with dict, advanced one pass, 38671 -github, level 6 with dict dms, advanced one pass, 38671 -github, level 6 with dict dds, advanced one pass, 38636 -github, level 6 with dict copy, advanced one pass, 38669 -github, level 6 with dict load, advanced one pass, 40695 +github, level 6 with dict, advanced one pass, 38669 +github, level 6 with dict dms, advanced one pass, 38669 +github, level 6 with dict dds, advanced one pass, 38638 +github, level 6 with dict copy, advanced one pass, 38665 +github, level 6 with dict load, advanced one pass, 41153 github, level 7 row 1, advanced one pass, 134584 -github, level 7 row 1 with dict dms, advanced one pass, 38758 -github, level 7 row 1 with dict dds, advanced one pass, 38745 -github, level 7 row 1 with dict copy, advanced one pass, 38755 -github, level 7 row 1 with dict load, advanced one pass, 43154 +github, level 7 row 1 with dict dms, advanced one pass, 38765 +github, level 7 row 1 with dict dds, advanced one pass, 38749 +github, level 7 row 1 with dict copy, advanced one pass, 38759 +github, level 7 row 1 with dict load, advanced one pass, 43227 github, level 7 row 2, advanced one pass, 135122 github, level 7 row 2 with dict dms, advanced one pass, 38860 github, level 7 row 2 with dict dds, advanced one pass, 38766 github, level 7 row 2 with dict copy, advanced one pass, 38834 -github, level 7 row 2 with dict load, advanced one pass, 40695 +github, level 7 row 2 with dict load, advanced one pass, 41153 github, level 7, advanced one pass, 135122 -github, level 7 with dict, advanced one pass, 38758 -github, level 7 with dict dms, advanced one pass, 38758 -github, level 7 with dict dds, advanced one pass, 38745 -github, level 7 with dict copy, advanced one pass, 38755 -github, level 7 with dict load, advanced one pass, 40695 +github, level 7 with dict, advanced one pass, 38765 +github, level 7 with dict dms, advanced one pass, 38765 +github, level 7 with dict dds, advanced one pass, 38749 +github, level 7 with dict copy, advanced one pass, 38759 +github, level 7 with dict load, advanced one pass, 41153 github, level 9, advanced one pass, 135122 -github, level 9 with dict, advanced one pass, 39437 -github, level 9 with dict dms, advanced one pass, 39437 +github, level 9 with dict, advanced one pass, 39439 +github, level 9 with dict dms, advanced one pass, 39439 github, level 9 with dict dds, advanced one pass, 39393 -github, level 9 with dict copy, advanced one pass, 39398 -github, level 9 with dict load, advanced one pass, 41710 +github, level 9 with dict copy, advanced one pass, 39362 +github, level 9 with dict load, advanced one pass, 42148 github, level 11 row 1, advanced one pass, 135367 github, level 11 row 1 with dict dms, advanced one pass, 39671 github, level 11 row 1 with dict dds, advanced one pass, 39671 github, level 11 row 1 with dict copy, advanced one pass, 39651 -github, level 11 row 1 with dict load, advanced one pass, 41360 +github, level 11 row 1 with dict load, advanced one pass, 41744 github, level 11 row 2, advanced one pass, 135367 github, level 11 row 2 with dict dms, advanced one pass, 39671 github, level 11 row 2 with dict dds, advanced one pass, 39671 github, level 11 row 2 with dict copy, advanced one pass, 39651 -github, level 11 row 2 with dict load, advanced one pass, 41360 +github, level 11 row 2 with dict load, advanced one pass, 41744 github, level 12 row 1, advanced one pass, 134402 github, level 12 row 1 with dict dms, advanced one pass, 39677 github, level 12 row 1 with dict dds, advanced one pass, 39677 github, level 12 row 1 with dict copy, advanced one pass, 39677 -github, level 12 row 1 with dict load, advanced one pass, 41166 +github, level 12 row 1 with dict load, advanced one pass, 41553 github, level 12 row 2, advanced one pass, 134402 github, level 12 row 2 with dict dms, advanced one pass, 39677 github, level 12 row 2 with dict dds, advanced one pass, 39677 github, level 12 row 2 with dict copy, advanced one pass, 39677 -github, level 12 row 2 with dict load, advanced one pass, 41166 +github, level 12 row 2 with dict load, advanced one pass, 41553 github, level 13, advanced one pass, 132878 github, level 13 with dict, advanced one pass, 39900 github, level 13 with dict dms, advanced one pass, 39900 @@ -397,17 +397,17 @@ github, level 13 with dict dds, advanced github, level 13 with dict copy, advanced one pass, 39948 github, level 13 with dict load, advanced one pass, 42624 github, level 16, advanced one pass, 133209 -github, level 16 with dict, advanced one pass, 37577 -github, level 16 with dict dms, advanced one pass, 37577 -github, level 16 with dict dds, advanced one pass, 37577 -github, level 16 with dict copy, advanced one pass, 37568 -github, level 16 with dict load, advanced one pass, 42338 +github, level 16 with dict, advanced one pass, 37902 +github, level 16 with dict dms, advanced one pass, 37902 +github, level 16 with dict dds, advanced one pass, 37902 +github, level 16 with dict copy, advanced one pass, 37892 +github, level 16 with dict load, advanced one pass, 42402 github, level 19, advanced one pass, 132879 -github, level 19 with dict, advanced one pass, 37576 -github, level 19 with dict dms, advanced one pass, 37576 -github, level 19 with dict dds, advanced one pass, 37576 -github, level 19 with dict copy, advanced one pass, 37567 -github, level 19 with dict load, advanced one pass, 39613 +github, level 19 with dict, advanced one pass, 37916 +github, level 19 with dict dms, advanced one pass, 37916 +github, level 19 with dict dds, advanced one pass, 37916 +github, level 19 with dict copy, advanced one pass, 37906 +github, level 19 with dict load, advanced one pass, 39770 github, no source size, advanced one pass, 136332 github, no source size with dict, advanced one pass, 41148 github, long distance mode, advanced one pass, 136332 @@ -422,11 +422,11 @@ github, uncompressed literals optimal, advanced github, huffman literals, advanced one pass, 142365 github, multithreaded with advanced params, advanced one pass, 165911 github.tar, level -5, advanced one pass, 52115 -github.tar, level -5 with dict, advanced one pass, 50974 +github.tar, level -5 with dict, advanced one pass, 51097 github.tar, level -3, advanced one pass, 45678 -github.tar, level -3 with dict, advanced one pass, 44656 +github.tar, level -3 with dict, advanced one pass, 44734 github.tar, level -1, advanced one pass, 42560 -github.tar, level -1 with dict, advanced one pass, 41151 +github.tar, level -1 with dict, advanced one pass, 41353 github.tar, level 0, advanced one pass, 38831 github.tar, level 0 with dict, advanced one pass, 37995 github.tar, level 0 with dict dms, advanced one pass, 38003 @@ -434,10 +434,10 @@ github.tar, level 0 with dict dds, advanced github.tar, level 0 with dict copy, advanced one pass, 37995 github.tar, level 0 with dict load, advanced one pass, 37956 github.tar, level 1, advanced one pass, 39200 -github.tar, level 1 with dict, advanced one pass, 38089 -github.tar, level 1 with dict dms, advanced one pass, 38294 -github.tar, level 1 with dict dds, advanced one pass, 38294 -github.tar, level 1 with dict copy, advanced one pass, 38089 +github.tar, level 1 with dict, advanced one pass, 38119 +github.tar, level 1 with dict dms, advanced one pass, 38406 +github.tar, level 1 with dict dds, advanced one pass, 38406 +github.tar, level 1 with dict copy, advanced one pass, 38119 github.tar, level 1 with dict load, advanced one pass, 38364 github.tar, level 3, advanced one pass, 38831 github.tar, level 3 with dict, advanced one pass, 37995 @@ -452,64 +452,64 @@ github.tar, level 4 with dict dds, advanced github.tar, level 4 with dict copy, advanced one pass, 37948 github.tar, level 4 with dict load, advanced one pass, 37927 github.tar, level 5 row 1, advanced one pass, 39651 -github.tar, level 5 row 1 with dict dms, advanced one pass, 39059 -github.tar, level 5 row 1 with dict dds, advanced one pass, 39067 -github.tar, level 5 row 1 with dict copy, advanced one pass, 39082 -github.tar, level 5 row 1 with dict load, advanced one pass, 38999 +github.tar, level 5 row 1 with dict dms, advanced one pass, 39043 +github.tar, level 5 row 1 with dict dds, advanced one pass, 39069 +github.tar, level 5 row 1 with dict copy, advanced one pass, 39145 +github.tar, level 5 row 1 with dict load, advanced one pass, 39000 github.tar, level 5 row 2, advanced one pass, 39701 github.tar, level 5 row 2 with dict dms, advanced one pass, 39365 github.tar, level 5 row 2 with dict dds, advanced one pass, 39233 github.tar, level 5 row 2 with dict copy, advanced one pass, 39715 github.tar, level 5 row 2 with dict load, advanced one pass, 39158 github.tar, level 5, advanced one pass, 39651 -github.tar, level 5 with dict, advanced one pass, 39082 -github.tar, level 5 with dict dms, advanced one pass, 39059 -github.tar, level 5 with dict dds, advanced one pass, 39067 -github.tar, level 5 with dict copy, advanced one pass, 39082 -github.tar, level 5 with dict load, advanced one pass, 38999 +github.tar, level 5 with dict, advanced one pass, 39145 +github.tar, level 5 with dict dms, advanced one pass, 39043 +github.tar, level 5 with dict dds, advanced one pass, 39069 +github.tar, level 5 with dict copy, advanced one pass, 39145 +github.tar, level 5 with dict load, advanced one pass, 39000 github.tar, level 6, advanced one pass, 39282 github.tar, level 6 with dict, advanced one pass, 38656 -github.tar, level 6 with dict dms, advanced one pass, 38636 -github.tar, level 6 with dict dds, advanced one pass, 38634 +github.tar, level 6 with dict dms, advanced one pass, 38640 +github.tar, level 6 with dict dds, advanced one pass, 38643 github.tar, level 6 with dict copy, advanced one pass, 38656 -github.tar, level 6 with dict load, advanced one pass, 38648 -github.tar, level 7 row 1, advanced one pass, 38110 -github.tar, level 7 row 1 with dict dms, advanced one pass, 37858 -github.tar, level 7 row 1 with dict dds, advanced one pass, 37882 -github.tar, level 7 row 1 with dict copy, advanced one pass, 37865 -github.tar, level 7 row 1 with dict load, advanced one pass, 37436 +github.tar, level 6 with dict load, advanced one pass, 38647 +github.tar, level 7 row 1, advanced one pass, 38005 +github.tar, level 7 row 1 with dict dms, advanced one pass, 37832 +github.tar, level 7 row 1 with dict dds, advanced one pass, 37857 +github.tar, level 7 row 1 with dict copy, advanced one pass, 37839 +github.tar, level 7 row 1 with dict load, advanced one pass, 37286 github.tar, level 7 row 2, advanced one pass, 38077 github.tar, level 7 row 2 with dict dms, advanced one pass, 38012 github.tar, level 7 row 2 with dict dds, advanced one pass, 38014 github.tar, level 7 row 2 with dict copy, advanced one pass, 38101 github.tar, level 7 row 2 with dict load, advanced one pass, 37402 -github.tar, level 7, advanced one pass, 38110 -github.tar, level 7 with dict, advanced one pass, 37865 -github.tar, level 7 with dict dms, advanced one pass, 37858 -github.tar, level 7 with dict dds, advanced one pass, 37882 -github.tar, level 7 with dict copy, advanced one pass, 37865 -github.tar, level 7 with dict load, advanced one pass, 37436 -github.tar, level 9, advanced one pass, 36760 -github.tar, level 9 with dict, advanced one pass, 36484 -github.tar, level 9 with dict dms, advanced one pass, 36567 -github.tar, level 9 with dict dds, advanced one pass, 36628 -github.tar, level 9 with dict copy, advanced one pass, 36484 -github.tar, level 9 with dict load, advanced one pass, 36401 -github.tar, level 11 row 1, advanced one pass, 36081 +github.tar, level 7, advanced one pass, 38005 +github.tar, level 7 with dict, advanced one pass, 37839 +github.tar, level 7 with dict dms, advanced one pass, 37832 +github.tar, level 7 with dict dds, advanced one pass, 37857 +github.tar, level 7 with dict copy, advanced one pass, 37839 +github.tar, level 7 with dict load, advanced one pass, 37286 +github.tar, level 9, advanced one pass, 36723 +github.tar, level 9 with dict, advanced one pass, 36531 +github.tar, level 9 with dict dms, advanced one pass, 36615 +github.tar, level 9 with dict dds, advanced one pass, 36682 +github.tar, level 9 with dict copy, advanced one pass, 36531 +github.tar, level 9 with dict load, advanced one pass, 36322 +github.tar, level 11 row 1, advanced one pass, 36085 github.tar, level 11 row 1 with dict dms, advanced one pass, 36963 github.tar, level 11 row 1 with dict dds, advanced one pass, 36963 github.tar, level 11 row 1 with dict copy, advanced one pass, 36557 -github.tar, level 11 row 1 with dict load, advanced one pass, 36434 +github.tar, level 11 row 1 with dict load, advanced one pass, 36423 github.tar, level 11 row 2, advanced one pass, 36110 github.tar, level 11 row 2 with dict dms, advanced one pass, 36963 github.tar, level 11 row 2 with dict dds, advanced one pass, 36963 github.tar, level 11 row 2 with dict copy, advanced one pass, 36557 github.tar, level 11 row 2 with dict load, advanced one pass, 36459 -github.tar, level 12 row 1, advanced one pass, 36081 +github.tar, level 12 row 1, advanced one pass, 36085 github.tar, level 12 row 1 with dict dms, advanced one pass, 36986 github.tar, level 12 row 1 with dict dds, advanced one pass, 36986 github.tar, level 12 row 1 with dict copy, advanced one pass, 36609 -github.tar, level 12 row 1 with dict load, advanced one pass, 36434 +github.tar, level 12 row 1 with dict load, advanced one pass, 36423 github.tar, level 12 row 2, advanced one pass, 36110 github.tar, level 12 row 2 with dict dms, advanced one pass, 36986 github.tar, level 12 row 2 with dict dds, advanced one pass, 36986 @@ -522,17 +522,17 @@ github.tar, level 13 with dict dds, advanced github.tar, level 13 with dict copy, advanced one pass, 37130 github.tar, level 13 with dict load, advanced one pass, 36010 github.tar, level 16, advanced one pass, 40466 -github.tar, level 16 with dict, advanced one pass, 33374 -github.tar, level 16 with dict dms, advanced one pass, 33206 -github.tar, level 16 with dict dds, advanced one pass, 33206 -github.tar, level 16 with dict copy, advanced one pass, 33374 +github.tar, level 16 with dict, advanced one pass, 33375 +github.tar, level 16 with dict dms, advanced one pass, 33207 +github.tar, level 16 with dict dds, advanced one pass, 33207 +github.tar, level 16 with dict copy, advanced one pass, 33375 github.tar, level 16 with dict load, advanced one pass, 39081 -github.tar, level 19, advanced one pass, 32276 -github.tar, level 19 with dict, advanced one pass, 32712 -github.tar, level 19 with dict dms, advanced one pass, 32555 -github.tar, level 19 with dict dds, advanced one pass, 32555 -github.tar, level 19 with dict copy, advanced one pass, 32712 -github.tar, level 19 with dict load, advanced one pass, 32479 +github.tar, level 19, advanced one pass, 32262 +github.tar, level 19 with dict, advanced one pass, 32701 +github.tar, level 19 with dict dms, advanced one pass, 32565 +github.tar, level 19 with dict dds, advanced one pass, 32565 +github.tar, level 19 with dict copy, advanced one pass, 32701 +github.tar, level 19 with dict load, advanced one pass, 32428 github.tar, no source size, advanced one pass, 38831 github.tar, no source size with dict, advanced one pass, 37995 github.tar, long distance mode, advanced one pass, 40252 @@ -543,7 +543,7 @@ github.tar, small hash log, advanced github.tar, small chain log, advanced one pass, 41669 github.tar, explicit params, advanced one pass, 41385 github.tar, uncompressed literals, advanced one pass, 41525 -github.tar, uncompressed literals optimal, advanced one pass, 35397 +github.tar, uncompressed literals optimal, advanced one pass, 35356 github.tar, huffman literals, advanced one pass, 38853 github.tar, multithreaded with advanced params, advanced one pass, 41525 silesia, level -5, advanced one pass small out, 6857372 @@ -553,21 +553,21 @@ silesia, level 0, advanced silesia, level 1, advanced one pass small out, 5306632 silesia, level 3, advanced one pass small out, 4842075 silesia, level 4, advanced one pass small out, 4779186 -silesia, level 5 row 1, advanced one pass small out, 4666323 -silesia, level 5 row 2, advanced one pass small out, 4670136 -silesia, level 5, advanced one pass small out, 4666323 -silesia, level 6, advanced one pass small out, 4603066 -silesia, level 7 row 1, advanced one pass small out, 4566984 -silesia, level 7 row 2, advanced one pass small out, 4564868 -silesia, level 7, advanced one pass small out, 4566984 -silesia, level 9, advanced one pass small out, 4543018 -silesia, level 11 row 1, advanced one pass small out, 4505046 -silesia, level 11 row 2, advanced one pass small out, 4503116 -silesia, level 12 row 1, advanced one pass small out, 4505046 -silesia, level 12 row 2, advanced one pass small out, 4503116 +silesia, level 5 row 1, advanced one pass small out, 4667668 +silesia, level 5 row 2, advanced one pass small out, 4670326 +silesia, level 5, advanced one pass small out, 4667668 +silesia, level 6, advanced one pass small out, 4604351 +silesia, level 7 row 1, advanced one pass small out, 4570271 +silesia, level 7 row 2, advanced one pass small out, 4565169 +silesia, level 7, advanced one pass small out, 4570271 +silesia, level 9, advanced one pass small out, 4545850 +silesia, level 11 row 1, advanced one pass small out, 4505658 +silesia, level 11 row 2, advanced one pass small out, 4503429 +silesia, level 12 row 1, advanced one pass small out, 4505658 +silesia, level 12 row 2, advanced one pass small out, 4503429 silesia, level 13, advanced one pass small out, 4493990 -silesia, level 16, advanced one pass small out, 4360041 -silesia, level 19, advanced one pass small out, 4296055 +silesia, level 16, advanced one pass small out, 4359652 +silesia, level 19, advanced one pass small out, 4266582 silesia, no source size, advanced one pass small out, 4842075 silesia, long distance mode, advanced one pass small out, 4833710 silesia, multithreaded, advanced one pass small out, 4842075 @@ -575,9 +575,9 @@ silesia, multithreaded long distance mode, advanced silesia, small window log, advanced one pass small out, 7095000 silesia, small hash log, advanced one pass small out, 6526141 silesia, small chain log, advanced one pass small out, 4912197 -silesia, explicit params, advanced one pass small out, 4795432 +silesia, explicit params, advanced one pass small out, 4795840 silesia, uncompressed literals, advanced one pass small out, 5120566 -silesia, uncompressed literals optimal, advanced one pass small out, 4319518 +silesia, uncompressed literals optimal, advanced one pass small out, 4316880 silesia, huffman literals, advanced one pass small out, 5321369 silesia, multithreaded with advanced params, advanced one pass small out, 5120566 silesia.tar, level -5, advanced one pass small out, 6861055 @@ -587,21 +587,21 @@ silesia.tar, level 0, advanced silesia.tar, level 1, advanced one pass small out, 5327717 silesia.tar, level 3, advanced one pass small out, 4854086 silesia.tar, level 4, advanced one pass small out, 4791503 -silesia.tar, level 5 row 1, advanced one pass small out, 4677740 -silesia.tar, level 5 row 2, advanced one pass small out, 4682161 -silesia.tar, level 5, advanced one pass small out, 4677740 -silesia.tar, level 6, advanced one pass small out, 4613242 -silesia.tar, level 7 row 1, advanced one pass small out, 4576661 -silesia.tar, level 7 row 2, advanced one pass small out, 4575393 -silesia.tar, level 7, advanced one pass small out, 4576661 -silesia.tar, level 9, advanced one pass small out, 4552899 -silesia.tar, level 11 row 1, advanced one pass small out, 4514432 -silesia.tar, level 11 row 2, advanced one pass small out, 4513604 -silesia.tar, level 12 row 1, advanced one pass small out, 4514049 -silesia.tar, level 12 row 2, advanced one pass small out, 4513797 +silesia.tar, level 5 row 1, advanced one pass small out, 4679004 +silesia.tar, level 5 row 2, advanced one pass small out, 4682334 +silesia.tar, level 5, advanced one pass small out, 4679004 +silesia.tar, level 6, advanced one pass small out, 4614561 +silesia.tar, level 7 row 1, advanced one pass small out, 4579828 +silesia.tar, level 7 row 2, advanced one pass small out, 4575602 +silesia.tar, level 7, advanced one pass small out, 4579828 +silesia.tar, level 9, advanced one pass small out, 4555448 +silesia.tar, level 11 row 1, advanced one pass small out, 4514962 +silesia.tar, level 11 row 2, advanced one pass small out, 4513816 +silesia.tar, level 12 row 1, advanced one pass small out, 4514517 +silesia.tar, level 12 row 2, advanced one pass small out, 4514007 silesia.tar, level 13, advanced one pass small out, 4502956 -silesia.tar, level 16, advanced one pass small out, 4360546 -silesia.tar, level 19, advanced one pass small out, 4265911 +silesia.tar, level 16, advanced one pass small out, 4360385 +silesia.tar, level 19, advanced one pass small out, 4260939 silesia.tar, no source size, advanced one pass small out, 4854086 silesia.tar, long distance mode, advanced one pass small out, 4840452 silesia.tar, multithreaded, advanced one pass small out, 4854160 @@ -609,105 +609,105 @@ silesia.tar, multithreaded long distance mode, advanced silesia.tar, small window log, advanced one pass small out, 7100655 silesia.tar, small hash log, advanced one pass small out, 6529206 silesia.tar, small chain log, advanced one pass small out, 4917041 -silesia.tar, explicit params, advanced one pass small out, 4806855 +silesia.tar, explicit params, advanced one pass small out, 4807274 silesia.tar, uncompressed literals, advanced one pass small out, 5122473 -silesia.tar, uncompressed literals optimal, advanced one pass small out, 4310141 +silesia.tar, uncompressed literals optimal, advanced one pass small out, 4308451 silesia.tar, huffman literals, advanced one pass small out, 5341705 silesia.tar, multithreaded with advanced params, advanced one pass small out, 5122567 github, level -5, advanced one pass small out, 204407 -github, level -5 with dict, advanced one pass small out, 46718 +github, level -5 with dict, advanced one pass small out, 45832 github, level -3, advanced one pass small out, 193253 -github, level -3 with dict, advanced one pass small out, 45395 +github, level -3 with dict, advanced one pass small out, 44671 github, level -1, advanced one pass small out, 175468 -github, level -1 with dict, advanced one pass small out, 43170 +github, level -1 with dict, advanced one pass small out, 41825 github, level 0, advanced one pass small out, 136332 github, level 0 with dict, advanced one pass small out, 41148 github, level 0 with dict dms, advanced one pass small out, 41148 github, level 0 with dict dds, advanced one pass small out, 41148 github, level 0 with dict copy, advanced one pass small out, 41124 -github, level 0 with dict load, advanced one pass small out, 42252 +github, level 0 with dict load, advanced one pass small out, 41847 github, level 1, advanced one pass small out, 142365 -github, level 1 with dict, advanced one pass small out, 41682 -github, level 1 with dict dms, advanced one pass small out, 41682 -github, level 1 with dict dds, advanced one pass small out, 41682 -github, level 1 with dict copy, advanced one pass small out, 41698 -github, level 1 with dict load, advanced one pass small out, 43814 +github, level 1 with dict, advanced one pass small out, 41266 +github, level 1 with dict dms, advanced one pass small out, 41266 +github, level 1 with dict dds, advanced one pass small out, 41266 +github, level 1 with dict copy, advanced one pass small out, 41279 +github, level 1 with dict load, advanced one pass small out, 43331 github, level 3, advanced one pass small out, 136332 github, level 3 with dict, advanced one pass small out, 41148 github, level 3 with dict dms, advanced one pass small out, 41148 github, level 3 with dict dds, advanced one pass small out, 41148 github, level 3 with dict copy, advanced one pass small out, 41124 -github, level 3 with dict load, advanced one pass small out, 42252 +github, level 3 with dict load, advanced one pass small out, 41847 github, level 4, advanced one pass small out, 136199 github, level 4 with dict, advanced one pass small out, 41251 github, level 4 with dict dms, advanced one pass small out, 41251 github, level 4 with dict dds, advanced one pass small out, 41251 github, level 4 with dict copy, advanced one pass small out, 41216 -github, level 4 with dict load, advanced one pass small out, 41159 +github, level 4 with dict load, advanced one pass small out, 41548 github, level 5 row 1, advanced one pass small out, 134584 -github, level 5 row 1 with dict dms, advanced one pass small out, 38758 +github, level 5 row 1 with dict dms, advanced one pass small out, 38754 github, level 5 row 1 with dict dds, advanced one pass small out, 38728 -github, level 5 row 1 with dict copy, advanced one pass small out, 38759 -github, level 5 row 1 with dict load, advanced one pass small out, 41518 +github, level 5 row 1 with dict copy, advanced one pass small out, 38755 +github, level 5 row 1 with dict load, advanced one pass small out, 41899 github, level 5 row 2, advanced one pass small out, 135121 github, level 5 row 2 with dict dms, advanced one pass small out, 38938 github, level 5 row 2 with dict dds, advanced one pass small out, 38732 github, level 5 row 2 with dict copy, advanced one pass small out, 38934 -github, level 5 row 2 with dict load, advanced one pass small out, 40725 +github, level 5 row 2 with dict load, advanced one pass small out, 41248 github, level 5, advanced one pass small out, 135121 -github, level 5 with dict, advanced one pass small out, 38758 -github, level 5 with dict dms, advanced one pass small out, 38758 +github, level 5 with dict, advanced one pass small out, 38754 +github, level 5 with dict dms, advanced one pass small out, 38754 github, level 5 with dict dds, advanced one pass small out, 38728 -github, level 5 with dict copy, advanced one pass small out, 38759 -github, level 5 with dict load, advanced one pass small out, 40725 +github, level 5 with dict copy, advanced one pass small out, 38755 +github, level 5 with dict load, advanced one pass small out, 41248 github, level 6, advanced one pass small out, 135122 -github, level 6 with dict, advanced one pass small out, 38671 -github, level 6 with dict dms, advanced one pass small out, 38671 -github, level 6 with dict dds, advanced one pass small out, 38636 -github, level 6 with dict copy, advanced one pass small out, 38669 -github, level 6 with dict load, advanced one pass small out, 40695 +github, level 6 with dict, advanced one pass small out, 38669 +github, level 6 with dict dms, advanced one pass small out, 38669 +github, level 6 with dict dds, advanced one pass small out, 38638 +github, level 6 with dict copy, advanced one pass small out, 38665 +github, level 6 with dict load, advanced one pass small out, 41153 github, level 7 row 1, advanced one pass small out, 134584 -github, level 7 row 1 with dict dms, advanced one pass small out, 38758 -github, level 7 row 1 with dict dds, advanced one pass small out, 38745 -github, level 7 row 1 with dict copy, advanced one pass small out, 38755 -github, level 7 row 1 with dict load, advanced one pass small out, 43154 +github, level 7 row 1 with dict dms, advanced one pass small out, 38765 +github, level 7 row 1 with dict dds, advanced one pass small out, 38749 +github, level 7 row 1 with dict copy, advanced one pass small out, 38759 +github, level 7 row 1 with dict load, advanced one pass small out, 43227 github, level 7 row 2, advanced one pass small out, 135122 github, level 7 row 2 with dict dms, advanced one pass small out, 38860 github, level 7 row 2 with dict dds, advanced one pass small out, 38766 github, level 7 row 2 with dict copy, advanced one pass small out, 38834 -github, level 7 row 2 with dict load, advanced one pass small out, 40695 +github, level 7 row 2 with dict load, advanced one pass small out, 41153 github, level 7, advanced one pass small out, 135122 -github, level 7 with dict, advanced one pass small out, 38758 -github, level 7 with dict dms, advanced one pass small out, 38758 -github, level 7 with dict dds, advanced one pass small out, 38745 -github, level 7 with dict copy, advanced one pass small out, 38755 -github, level 7 with dict load, advanced one pass small out, 40695 +github, level 7 with dict, advanced one pass small out, 38765 +github, level 7 with dict dms, advanced one pass small out, 38765 +github, level 7 with dict dds, advanced one pass small out, 38749 +github, level 7 with dict copy, advanced one pass small out, 38759 +github, level 7 with dict load, advanced one pass small out, 41153 github, level 9, advanced one pass small out, 135122 -github, level 9 with dict, advanced one pass small out, 39437 -github, level 9 with dict dms, advanced one pass small out, 39437 +github, level 9 with dict, advanced one pass small out, 39439 +github, level 9 with dict dms, advanced one pass small out, 39439 github, level 9 with dict dds, advanced one pass small out, 39393 -github, level 9 with dict copy, advanced one pass small out, 39398 -github, level 9 with dict load, advanced one pass small out, 41710 +github, level 9 with dict copy, advanced one pass small out, 39362 +github, level 9 with dict load, advanced one pass small out, 42148 github, level 11 row 1, advanced one pass small out, 135367 github, level 11 row 1 with dict dms, advanced one pass small out, 39671 github, level 11 row 1 with dict dds, advanced one pass small out, 39671 github, level 11 row 1 with dict copy, advanced one pass small out, 39651 -github, level 11 row 1 with dict load, advanced one pass small out, 41360 +github, level 11 row 1 with dict load, advanced one pass small out, 41744 github, level 11 row 2, advanced one pass small out, 135367 github, level 11 row 2 with dict dms, advanced one pass small out, 39671 github, level 11 row 2 with dict dds, advanced one pass small out, 39671 github, level 11 row 2 with dict copy, advanced one pass small out, 39651 -github, level 11 row 2 with dict load, advanced one pass small out, 41360 +github, level 11 row 2 with dict load, advanced one pass small out, 41744 github, level 12 row 1, advanced one pass small out, 134402 github, level 12 row 1 with dict dms, advanced one pass small out, 39677 github, level 12 row 1 with dict dds, advanced one pass small out, 39677 github, level 12 row 1 with dict copy, advanced one pass small out, 39677 -github, level 12 row 1 with dict load, advanced one pass small out, 41166 +github, level 12 row 1 with dict load, advanced one pass small out, 41553 github, level 12 row 2, advanced one pass small out, 134402 github, level 12 row 2 with dict dms, advanced one pass small out, 39677 github, level 12 row 2 with dict dds, advanced one pass small out, 39677 github, level 12 row 2 with dict copy, advanced one pass small out, 39677 -github, level 12 row 2 with dict load, advanced one pass small out, 41166 +github, level 12 row 2 with dict load, advanced one pass small out, 41553 github, level 13, advanced one pass small out, 132878 github, level 13 with dict, advanced one pass small out, 39900 github, level 13 with dict dms, advanced one pass small out, 39900 @@ -715,17 +715,17 @@ github, level 13 with dict dds, advanced github, level 13 with dict copy, advanced one pass small out, 39948 github, level 13 with dict load, advanced one pass small out, 42624 github, level 16, advanced one pass small out, 133209 -github, level 16 with dict, advanced one pass small out, 37577 -github, level 16 with dict dms, advanced one pass small out, 37577 -github, level 16 with dict dds, advanced one pass small out, 37577 -github, level 16 with dict copy, advanced one pass small out, 37568 -github, level 16 with dict load, advanced one pass small out, 42338 +github, level 16 with dict, advanced one pass small out, 37902 +github, level 16 with dict dms, advanced one pass small out, 37902 +github, level 16 with dict dds, advanced one pass small out, 37902 +github, level 16 with dict copy, advanced one pass small out, 37892 +github, level 16 with dict load, advanced one pass small out, 42402 github, level 19, advanced one pass small out, 132879 -github, level 19 with dict, advanced one pass small out, 37576 -github, level 19 with dict dms, advanced one pass small out, 37576 -github, level 19 with dict dds, advanced one pass small out, 37576 -github, level 19 with dict copy, advanced one pass small out, 37567 -github, level 19 with dict load, advanced one pass small out, 39613 +github, level 19 with dict, advanced one pass small out, 37916 +github, level 19 with dict dms, advanced one pass small out, 37916 +github, level 19 with dict dds, advanced one pass small out, 37916 +github, level 19 with dict copy, advanced one pass small out, 37906 +github, level 19 with dict load, advanced one pass small out, 39770 github, no source size, advanced one pass small out, 136332 github, no source size with dict, advanced one pass small out, 41148 github, long distance mode, advanced one pass small out, 136332 @@ -740,11 +740,11 @@ github, uncompressed literals optimal, advanced github, huffman literals, advanced one pass small out, 142365 github, multithreaded with advanced params, advanced one pass small out, 165911 github.tar, level -5, advanced one pass small out, 52115 -github.tar, level -5 with dict, advanced one pass small out, 50974 +github.tar, level -5 with dict, advanced one pass small out, 51097 github.tar, level -3, advanced one pass small out, 45678 -github.tar, level -3 with dict, advanced one pass small out, 44656 +github.tar, level -3 with dict, advanced one pass small out, 44734 github.tar, level -1, advanced one pass small out, 42560 -github.tar, level -1 with dict, advanced one pass small out, 41151 +github.tar, level -1 with dict, advanced one pass small out, 41353 github.tar, level 0, advanced one pass small out, 38831 github.tar, level 0 with dict, advanced one pass small out, 37995 github.tar, level 0 with dict dms, advanced one pass small out, 38003 @@ -752,10 +752,10 @@ github.tar, level 0 with dict dds, advanced github.tar, level 0 with dict copy, advanced one pass small out, 37995 github.tar, level 0 with dict load, advanced one pass small out, 37956 github.tar, level 1, advanced one pass small out, 39200 -github.tar, level 1 with dict, advanced one pass small out, 38089 -github.tar, level 1 with dict dms, advanced one pass small out, 38294 -github.tar, level 1 with dict dds, advanced one pass small out, 38294 -github.tar, level 1 with dict copy, advanced one pass small out, 38089 +github.tar, level 1 with dict, advanced one pass small out, 38119 +github.tar, level 1 with dict dms, advanced one pass small out, 38406 +github.tar, level 1 with dict dds, advanced one pass small out, 38406 +github.tar, level 1 with dict copy, advanced one pass small out, 38119 github.tar, level 1 with dict load, advanced one pass small out, 38364 github.tar, level 3, advanced one pass small out, 38831 github.tar, level 3 with dict, advanced one pass small out, 37995 @@ -770,64 +770,64 @@ github.tar, level 4 with dict dds, advanced github.tar, level 4 with dict copy, advanced one pass small out, 37948 github.tar, level 4 with dict load, advanced one pass small out, 37927 github.tar, level 5 row 1, advanced one pass small out, 39651 -github.tar, level 5 row 1 with dict dms, advanced one pass small out, 39059 -github.tar, level 5 row 1 with dict dds, advanced one pass small out, 39067 -github.tar, level 5 row 1 with dict copy, advanced one pass small out, 39082 -github.tar, level 5 row 1 with dict load, advanced one pass small out, 38999 +github.tar, level 5 row 1 with dict dms, advanced one pass small out, 39043 +github.tar, level 5 row 1 with dict dds, advanced one pass small out, 39069 +github.tar, level 5 row 1 with dict copy, advanced one pass small out, 39145 +github.tar, level 5 row 1 with dict load, advanced one pass small out, 39000 github.tar, level 5 row 2, advanced one pass small out, 39701 github.tar, level 5 row 2 with dict dms, advanced one pass small out, 39365 github.tar, level 5 row 2 with dict dds, advanced one pass small out, 39233 github.tar, level 5 row 2 with dict copy, advanced one pass small out, 39715 github.tar, level 5 row 2 with dict load, advanced one pass small out, 39158 github.tar, level 5, advanced one pass small out, 39651 -github.tar, level 5 with dict, advanced one pass small out, 39082 -github.tar, level 5 with dict dms, advanced one pass small out, 39059 -github.tar, level 5 with dict dds, advanced one pass small out, 39067 -github.tar, level 5 with dict copy, advanced one pass small out, 39082 -github.tar, level 5 with dict load, advanced one pass small out, 38999 +github.tar, level 5 with dict, advanced one pass small out, 39145 +github.tar, level 5 with dict dms, advanced one pass small out, 39043 +github.tar, level 5 with dict dds, advanced one pass small out, 39069 +github.tar, level 5 with dict copy, advanced one pass small out, 39145 +github.tar, level 5 with dict load, advanced one pass small out, 39000 github.tar, level 6, advanced one pass small out, 39282 github.tar, level 6 with dict, advanced one pass small out, 38656 -github.tar, level 6 with dict dms, advanced one pass small out, 38636 -github.tar, level 6 with dict dds, advanced one pass small out, 38634 +github.tar, level 6 with dict dms, advanced one pass small out, 38640 +github.tar, level 6 with dict dds, advanced one pass small out, 38643 github.tar, level 6 with dict copy, advanced one pass small out, 38656 -github.tar, level 6 with dict load, advanced one pass small out, 38648 -github.tar, level 7 row 1, advanced one pass small out, 38110 -github.tar, level 7 row 1 with dict dms, advanced one pass small out, 37858 -github.tar, level 7 row 1 with dict dds, advanced one pass small out, 37882 -github.tar, level 7 row 1 with dict copy, advanced one pass small out, 37865 -github.tar, level 7 row 1 with dict load, advanced one pass small out, 37436 +github.tar, level 6 with dict load, advanced one pass small out, 38647 +github.tar, level 7 row 1, advanced one pass small out, 38005 +github.tar, level 7 row 1 with dict dms, advanced one pass small out, 37832 +github.tar, level 7 row 1 with dict dds, advanced one pass small out, 37857 +github.tar, level 7 row 1 with dict copy, advanced one pass small out, 37839 +github.tar, level 7 row 1 with dict load, advanced one pass small out, 37286 github.tar, level 7 row 2, advanced one pass small out, 38077 github.tar, level 7 row 2 with dict dms, advanced one pass small out, 38012 github.tar, level 7 row 2 with dict dds, advanced one pass small out, 38014 github.tar, level 7 row 2 with dict copy, advanced one pass small out, 38101 github.tar, level 7 row 2 with dict load, advanced one pass small out, 37402 -github.tar, level 7, advanced one pass small out, 38110 -github.tar, level 7 with dict, advanced one pass small out, 37865 -github.tar, level 7 with dict dms, advanced one pass small out, 37858 -github.tar, level 7 with dict dds, advanced one pass small out, 37882 -github.tar, level 7 with dict copy, advanced one pass small out, 37865 -github.tar, level 7 with dict load, advanced one pass small out, 37436 -github.tar, level 9, advanced one pass small out, 36760 -github.tar, level 9 with dict, advanced one pass small out, 36484 -github.tar, level 9 with dict dms, advanced one pass small out, 36567 -github.tar, level 9 with dict dds, advanced one pass small out, 36628 -github.tar, level 9 with dict copy, advanced one pass small out, 36484 -github.tar, level 9 with dict load, advanced one pass small out, 36401 -github.tar, level 11 row 1, advanced one pass small out, 36081 +github.tar, level 7, advanced one pass small out, 38005 +github.tar, level 7 with dict, advanced one pass small out, 37839 +github.tar, level 7 with dict dms, advanced one pass small out, 37832 +github.tar, level 7 with dict dds, advanced one pass small out, 37857 +github.tar, level 7 with dict copy, advanced one pass small out, 37839 +github.tar, level 7 with dict load, advanced one pass small out, 37286 +github.tar, level 9, advanced one pass small out, 36723 +github.tar, level 9 with dict, advanced one pass small out, 36531 +github.tar, level 9 with dict dms, advanced one pass small out, 36615 +github.tar, level 9 with dict dds, advanced one pass small out, 36682 +github.tar, level 9 with dict copy, advanced one pass small out, 36531 +github.tar, level 9 with dict load, advanced one pass small out, 36322 +github.tar, level 11 row 1, advanced one pass small out, 36085 github.tar, level 11 row 1 with dict dms, advanced one pass small out, 36963 github.tar, level 11 row 1 with dict dds, advanced one pass small out, 36963 github.tar, level 11 row 1 with dict copy, advanced one pass small out, 36557 -github.tar, level 11 row 1 with dict load, advanced one pass small out, 36434 +github.tar, level 11 row 1 with dict load, advanced one pass small out, 36423 github.tar, level 11 row 2, advanced one pass small out, 36110 github.tar, level 11 row 2 with dict dms, advanced one pass small out, 36963 github.tar, level 11 row 2 with dict dds, advanced one pass small out, 36963 github.tar, level 11 row 2 with dict copy, advanced one pass small out, 36557 github.tar, level 11 row 2 with dict load, advanced one pass small out, 36459 -github.tar, level 12 row 1, advanced one pass small out, 36081 +github.tar, level 12 row 1, advanced one pass small out, 36085 github.tar, level 12 row 1 with dict dms, advanced one pass small out, 36986 github.tar, level 12 row 1 with dict dds, advanced one pass small out, 36986 github.tar, level 12 row 1 with dict copy, advanced one pass small out, 36609 -github.tar, level 12 row 1 with dict load, advanced one pass small out, 36434 +github.tar, level 12 row 1 with dict load, advanced one pass small out, 36423 github.tar, level 12 row 2, advanced one pass small out, 36110 github.tar, level 12 row 2 with dict dms, advanced one pass small out, 36986 github.tar, level 12 row 2 with dict dds, advanced one pass small out, 36986 @@ -840,17 +840,17 @@ github.tar, level 13 with dict dds, advanced github.tar, level 13 with dict copy, advanced one pass small out, 37130 github.tar, level 13 with dict load, advanced one pass small out, 36010 github.tar, level 16, advanced one pass small out, 40466 -github.tar, level 16 with dict, advanced one pass small out, 33374 -github.tar, level 16 with dict dms, advanced one pass small out, 33206 -github.tar, level 16 with dict dds, advanced one pass small out, 33206 -github.tar, level 16 with dict copy, advanced one pass small out, 33374 +github.tar, level 16 with dict, advanced one pass small out, 33375 +github.tar, level 16 with dict dms, advanced one pass small out, 33207 +github.tar, level 16 with dict dds, advanced one pass small out, 33207 +github.tar, level 16 with dict copy, advanced one pass small out, 33375 github.tar, level 16 with dict load, advanced one pass small out, 39081 -github.tar, level 19, advanced one pass small out, 32276 -github.tar, level 19 with dict, advanced one pass small out, 32712 -github.tar, level 19 with dict dms, advanced one pass small out, 32555 -github.tar, level 19 with dict dds, advanced one pass small out, 32555 -github.tar, level 19 with dict copy, advanced one pass small out, 32712 -github.tar, level 19 with dict load, advanced one pass small out, 32479 +github.tar, level 19, advanced one pass small out, 32262 +github.tar, level 19 with dict, advanced one pass small out, 32701 +github.tar, level 19 with dict dms, advanced one pass small out, 32565 +github.tar, level 19 with dict dds, advanced one pass small out, 32565 +github.tar, level 19 with dict copy, advanced one pass small out, 32701 +github.tar, level 19 with dict load, advanced one pass small out, 32428 github.tar, no source size, advanced one pass small out, 38831 github.tar, no source size with dict, advanced one pass small out, 37995 github.tar, long distance mode, advanced one pass small out, 40252 @@ -861,7 +861,7 @@ github.tar, small hash log, advanced github.tar, small chain log, advanced one pass small out, 41669 github.tar, explicit params, advanced one pass small out, 41385 github.tar, uncompressed literals, advanced one pass small out, 41525 -github.tar, uncompressed literals optimal, advanced one pass small out, 35397 +github.tar, uncompressed literals optimal, advanced one pass small out, 35356 github.tar, huffman literals, advanced one pass small out, 38853 github.tar, multithreaded with advanced params, advanced one pass small out, 41525 silesia, level -5, advanced streaming, 6854744 @@ -871,21 +871,21 @@ silesia, level 0, advanced silesia, level 1, advanced streaming, 5306388 silesia, level 3, advanced streaming, 4842075 silesia, level 4, advanced streaming, 4779186 -silesia, level 5 row 1, advanced streaming, 4666323 -silesia, level 5 row 2, advanced streaming, 4670136 -silesia, level 5, advanced streaming, 4666323 -silesia, level 6, advanced streaming, 4603066 -silesia, level 7 row 1, advanced streaming, 4566984 -silesia, level 7 row 2, advanced streaming, 4564868 -silesia, level 7, advanced streaming, 4566984 -silesia, level 9, advanced streaming, 4543018 -silesia, level 11 row 1, advanced streaming, 4505046 -silesia, level 11 row 2, advanced streaming, 4503116 -silesia, level 12 row 1, advanced streaming, 4505046 -silesia, level 12 row 2, advanced streaming, 4503116 +silesia, level 5 row 1, advanced streaming, 4667668 +silesia, level 5 row 2, advanced streaming, 4670326 +silesia, level 5, advanced streaming, 4667668 +silesia, level 6, advanced streaming, 4604351 +silesia, level 7 row 1, advanced streaming, 4570271 +silesia, level 7 row 2, advanced streaming, 4565169 +silesia, level 7, advanced streaming, 4570271 +silesia, level 9, advanced streaming, 4545850 +silesia, level 11 row 1, advanced streaming, 4505658 +silesia, level 11 row 2, advanced streaming, 4503429 +silesia, level 12 row 1, advanced streaming, 4505658 +silesia, level 12 row 2, advanced streaming, 4503429 silesia, level 13, advanced streaming, 4493990 -silesia, level 16, advanced streaming, 4360041 -silesia, level 19, advanced streaming, 4296055 +silesia, level 16, advanced streaming, 4359652 +silesia, level 19, advanced streaming, 4266582 silesia, no source size, advanced streaming, 4842039 silesia, long distance mode, advanced streaming, 4833710 silesia, multithreaded, advanced streaming, 4842075 @@ -893,9 +893,9 @@ silesia, multithreaded long distance mode, advanced silesia, small window log, advanced streaming, 7111103 silesia, small hash log, advanced streaming, 6526141 silesia, small chain log, advanced streaming, 4912197 -silesia, explicit params, advanced streaming, 4795452 +silesia, explicit params, advanced streaming, 4795857 silesia, uncompressed literals, advanced streaming, 5120566 -silesia, uncompressed literals optimal, advanced streaming, 4319518 +silesia, uncompressed literals optimal, advanced streaming, 4316880 silesia, huffman literals, advanced streaming, 5321370 silesia, multithreaded with advanced params, advanced streaming, 5120566 silesia.tar, level -5, advanced streaming, 6856523 @@ -905,21 +905,21 @@ silesia.tar, level 0, advanced silesia.tar, level 1, advanced streaming, 5327708 silesia.tar, level 3, advanced streaming, 4859271 silesia.tar, level 4, advanced streaming, 4797470 -silesia.tar, level 5 row 1, advanced streaming, 4677748 -silesia.tar, level 5 row 2, advanced streaming, 4682169 -silesia.tar, level 5, advanced streaming, 4677748 -silesia.tar, level 6, advanced streaming, 4613246 -silesia.tar, level 7 row 1, advanced streaming, 4576664 -silesia.tar, level 7 row 2, advanced streaming, 4575394 -silesia.tar, level 7, advanced streaming, 4576664 -silesia.tar, level 9, advanced streaming, 4552900 -silesia.tar, level 11 row 1, advanced streaming, 4514433 -silesia.tar, level 11 row 2, advanced streaming, 4513604 -silesia.tar, level 12 row 1, advanced streaming, 4514049 -silesia.tar, level 12 row 2, advanced streaming, 4513797 +silesia.tar, level 5 row 1, advanced streaming, 4679020 +silesia.tar, level 5 row 2, advanced streaming, 4682355 +silesia.tar, level 5, advanced streaming, 4679020 +silesia.tar, level 6, advanced streaming, 4614558 +silesia.tar, level 7 row 1, advanced streaming, 4579823 +silesia.tar, level 7 row 2, advanced streaming, 4575601 +silesia.tar, level 7, advanced streaming, 4579823 +silesia.tar, level 9, advanced streaming, 4555445 +silesia.tar, level 11 row 1, advanced streaming, 4514959 +silesia.tar, level 11 row 2, advanced streaming, 4513810 +silesia.tar, level 12 row 1, advanced streaming, 4514514 +silesia.tar, level 12 row 2, advanced streaming, 4514003 silesia.tar, level 13, advanced streaming, 4502956 -silesia.tar, level 16, advanced streaming, 4360546 -silesia.tar, level 19, advanced streaming, 4265911 +silesia.tar, level 16, advanced streaming, 4360385 +silesia.tar, level 19, advanced streaming, 4260939 silesia.tar, no source size, advanced streaming, 4859267 silesia.tar, long distance mode, advanced streaming, 4840452 silesia.tar, multithreaded, advanced streaming, 4854160 @@ -927,105 +927,105 @@ silesia.tar, multithreaded long distance mode, advanced silesia.tar, small window log, advanced streaming, 7117559 silesia.tar, small hash log, advanced streaming, 6529209 silesia.tar, small chain log, advanced streaming, 4917021 -silesia.tar, explicit params, advanced streaming, 4806873 +silesia.tar, explicit params, advanced streaming, 4807288 silesia.tar, uncompressed literals, advanced streaming, 5127423 -silesia.tar, uncompressed literals optimal, advanced streaming, 4310141 +silesia.tar, uncompressed literals optimal, advanced streaming, 4308451 silesia.tar, huffman literals, advanced streaming, 5341712 silesia.tar, multithreaded with advanced params, advanced streaming, 5122567 github, level -5, advanced streaming, 204407 -github, level -5 with dict, advanced streaming, 46718 +github, level -5 with dict, advanced streaming, 45832 github, level -3, advanced streaming, 193253 -github, level -3 with dict, advanced streaming, 45395 +github, level -3 with dict, advanced streaming, 44671 github, level -1, advanced streaming, 175468 -github, level -1 with dict, advanced streaming, 43170 +github, level -1 with dict, advanced streaming, 41825 github, level 0, advanced streaming, 136332 github, level 0 with dict, advanced streaming, 41148 github, level 0 with dict dms, advanced streaming, 41148 github, level 0 with dict dds, advanced streaming, 41148 github, level 0 with dict copy, advanced streaming, 41124 -github, level 0 with dict load, advanced streaming, 42252 +github, level 0 with dict load, advanced streaming, 41847 github, level 1, advanced streaming, 142365 -github, level 1 with dict, advanced streaming, 41682 -github, level 1 with dict dms, advanced streaming, 41682 -github, level 1 with dict dds, advanced streaming, 41682 -github, level 1 with dict copy, advanced streaming, 41698 -github, level 1 with dict load, advanced streaming, 43814 +github, level 1 with dict, advanced streaming, 41266 +github, level 1 with dict dms, advanced streaming, 41266 +github, level 1 with dict dds, advanced streaming, 41266 +github, level 1 with dict copy, advanced streaming, 41279 +github, level 1 with dict load, advanced streaming, 43331 github, level 3, advanced streaming, 136332 github, level 3 with dict, advanced streaming, 41148 github, level 3 with dict dms, advanced streaming, 41148 github, level 3 with dict dds, advanced streaming, 41148 github, level 3 with dict copy, advanced streaming, 41124 -github, level 3 with dict load, advanced streaming, 42252 +github, level 3 with dict load, advanced streaming, 41847 github, level 4, advanced streaming, 136199 github, level 4 with dict, advanced streaming, 41251 github, level 4 with dict dms, advanced streaming, 41251 github, level 4 with dict dds, advanced streaming, 41251 github, level 4 with dict copy, advanced streaming, 41216 -github, level 4 with dict load, advanced streaming, 41159 +github, level 4 with dict load, advanced streaming, 41548 github, level 5 row 1, advanced streaming, 134584 -github, level 5 row 1 with dict dms, advanced streaming, 38758 +github, level 5 row 1 with dict dms, advanced streaming, 38754 github, level 5 row 1 with dict dds, advanced streaming, 38728 -github, level 5 row 1 with dict copy, advanced streaming, 38759 -github, level 5 row 1 with dict load, advanced streaming, 41518 +github, level 5 row 1 with dict copy, advanced streaming, 38755 +github, level 5 row 1 with dict load, advanced streaming, 41899 github, level 5 row 2, advanced streaming, 135121 github, level 5 row 2 with dict dms, advanced streaming, 38938 github, level 5 row 2 with dict dds, advanced streaming, 38732 github, level 5 row 2 with dict copy, advanced streaming, 38934 -github, level 5 row 2 with dict load, advanced streaming, 40725 +github, level 5 row 2 with dict load, advanced streaming, 41248 github, level 5, advanced streaming, 135121 -github, level 5 with dict, advanced streaming, 38758 -github, level 5 with dict dms, advanced streaming, 38758 +github, level 5 with dict, advanced streaming, 38754 +github, level 5 with dict dms, advanced streaming, 38754 github, level 5 with dict dds, advanced streaming, 38728 -github, level 5 with dict copy, advanced streaming, 38759 -github, level 5 with dict load, advanced streaming, 40725 +github, level 5 with dict copy, advanced streaming, 38755 +github, level 5 with dict load, advanced streaming, 41248 github, level 6, advanced streaming, 135122 -github, level 6 with dict, advanced streaming, 38671 -github, level 6 with dict dms, advanced streaming, 38671 -github, level 6 with dict dds, advanced streaming, 38636 -github, level 6 with dict copy, advanced streaming, 38669 -github, level 6 with dict load, advanced streaming, 40695 +github, level 6 with dict, advanced streaming, 38669 +github, level 6 with dict dms, advanced streaming, 38669 +github, level 6 with dict dds, advanced streaming, 38638 +github, level 6 with dict copy, advanced streaming, 38665 +github, level 6 with dict load, advanced streaming, 41153 github, level 7 row 1, advanced streaming, 134584 -github, level 7 row 1 with dict dms, advanced streaming, 38758 -github, level 7 row 1 with dict dds, advanced streaming, 38745 -github, level 7 row 1 with dict copy, advanced streaming, 38755 -github, level 7 row 1 with dict load, advanced streaming, 43154 +github, level 7 row 1 with dict dms, advanced streaming, 38765 +github, level 7 row 1 with dict dds, advanced streaming, 38749 +github, level 7 row 1 with dict copy, advanced streaming, 38759 +github, level 7 row 1 with dict load, advanced streaming, 43227 github, level 7 row 2, advanced streaming, 135122 github, level 7 row 2 with dict dms, advanced streaming, 38860 github, level 7 row 2 with dict dds, advanced streaming, 38766 github, level 7 row 2 with dict copy, advanced streaming, 38834 -github, level 7 row 2 with dict load, advanced streaming, 40695 +github, level 7 row 2 with dict load, advanced streaming, 41153 github, level 7, advanced streaming, 135122 -github, level 7 with dict, advanced streaming, 38758 -github, level 7 with dict dms, advanced streaming, 38758 -github, level 7 with dict dds, advanced streaming, 38745 -github, level 7 with dict copy, advanced streaming, 38755 -github, level 7 with dict load, advanced streaming, 40695 +github, level 7 with dict, advanced streaming, 38765 +github, level 7 with dict dms, advanced streaming, 38765 +github, level 7 with dict dds, advanced streaming, 38749 +github, level 7 with dict copy, advanced streaming, 38759 +github, level 7 with dict load, advanced streaming, 41153 github, level 9, advanced streaming, 135122 -github, level 9 with dict, advanced streaming, 39437 -github, level 9 with dict dms, advanced streaming, 39437 +github, level 9 with dict, advanced streaming, 39439 +github, level 9 with dict dms, advanced streaming, 39439 github, level 9 with dict dds, advanced streaming, 39393 -github, level 9 with dict copy, advanced streaming, 39398 -github, level 9 with dict load, advanced streaming, 41710 +github, level 9 with dict copy, advanced streaming, 39362 +github, level 9 with dict load, advanced streaming, 42148 github, level 11 row 1, advanced streaming, 135367 github, level 11 row 1 with dict dms, advanced streaming, 39671 github, level 11 row 1 with dict dds, advanced streaming, 39671 github, level 11 row 1 with dict copy, advanced streaming, 39651 -github, level 11 row 1 with dict load, advanced streaming, 41360 +github, level 11 row 1 with dict load, advanced streaming, 41744 github, level 11 row 2, advanced streaming, 135367 github, level 11 row 2 with dict dms, advanced streaming, 39671 github, level 11 row 2 with dict dds, advanced streaming, 39671 github, level 11 row 2 with dict copy, advanced streaming, 39651 -github, level 11 row 2 with dict load, advanced streaming, 41360 +github, level 11 row 2 with dict load, advanced streaming, 41744 github, level 12 row 1, advanced streaming, 134402 github, level 12 row 1 with dict dms, advanced streaming, 39677 github, level 12 row 1 with dict dds, advanced streaming, 39677 github, level 12 row 1 with dict copy, advanced streaming, 39677 -github, level 12 row 1 with dict load, advanced streaming, 41166 +github, level 12 row 1 with dict load, advanced streaming, 41553 github, level 12 row 2, advanced streaming, 134402 github, level 12 row 2 with dict dms, advanced streaming, 39677 github, level 12 row 2 with dict dds, advanced streaming, 39677 github, level 12 row 2 with dict copy, advanced streaming, 39677 -github, level 12 row 2 with dict load, advanced streaming, 41166 +github, level 12 row 2 with dict load, advanced streaming, 41553 github, level 13, advanced streaming, 132878 github, level 13 with dict, advanced streaming, 39900 github, level 13 with dict dms, advanced streaming, 39900 @@ -1033,17 +1033,17 @@ github, level 13 with dict dds, advanced github, level 13 with dict copy, advanced streaming, 39948 github, level 13 with dict load, advanced streaming, 42624 github, level 16, advanced streaming, 133209 -github, level 16 with dict, advanced streaming, 37577 -github, level 16 with dict dms, advanced streaming, 37577 -github, level 16 with dict dds, advanced streaming, 37577 -github, level 16 with dict copy, advanced streaming, 37568 -github, level 16 with dict load, advanced streaming, 42338 +github, level 16 with dict, advanced streaming, 37902 +github, level 16 with dict dms, advanced streaming, 37902 +github, level 16 with dict dds, advanced streaming, 37902 +github, level 16 with dict copy, advanced streaming, 37892 +github, level 16 with dict load, advanced streaming, 42402 github, level 19, advanced streaming, 132879 -github, level 19 with dict, advanced streaming, 37576 -github, level 19 with dict dms, advanced streaming, 37576 -github, level 19 with dict dds, advanced streaming, 37576 -github, level 19 with dict copy, advanced streaming, 37567 -github, level 19 with dict load, advanced streaming, 39613 +github, level 19 with dict, advanced streaming, 37916 +github, level 19 with dict dms, advanced streaming, 37916 +github, level 19 with dict dds, advanced streaming, 37916 +github, level 19 with dict copy, advanced streaming, 37906 +github, level 19 with dict load, advanced streaming, 39770 github, no source size, advanced streaming, 136332 github, no source size with dict, advanced streaming, 41148 github, long distance mode, advanced streaming, 136332 @@ -1058,11 +1058,11 @@ github, uncompressed literals optimal, advanced github, huffman literals, advanced streaming, 142365 github, multithreaded with advanced params, advanced streaming, 165911 github.tar, level -5, advanced streaming, 52152 -github.tar, level -5 with dict, advanced streaming, 51045 +github.tar, level -5 with dict, advanced streaming, 51181 github.tar, level -3, advanced streaming, 45678 -github.tar, level -3 with dict, advanced streaming, 44656 +github.tar, level -3 with dict, advanced streaming, 44734 github.tar, level -1, advanced streaming, 42560 -github.tar, level -1 with dict, advanced streaming, 41151 +github.tar, level -1 with dict, advanced streaming, 41353 github.tar, level 0, advanced streaming, 38831 github.tar, level 0 with dict, advanced streaming, 37995 github.tar, level 0 with dict dms, advanced streaming, 38003 @@ -1070,10 +1070,10 @@ github.tar, level 0 with dict dds, advanced github.tar, level 0 with dict copy, advanced streaming, 37995 github.tar, level 0 with dict load, advanced streaming, 37956 github.tar, level 1, advanced streaming, 39200 -github.tar, level 1 with dict, advanced streaming, 38089 -github.tar, level 1 with dict dms, advanced streaming, 38294 -github.tar, level 1 with dict dds, advanced streaming, 38294 -github.tar, level 1 with dict copy, advanced streaming, 38089 +github.tar, level 1 with dict, advanced streaming, 38119 +github.tar, level 1 with dict dms, advanced streaming, 38406 +github.tar, level 1 with dict dds, advanced streaming, 38406 +github.tar, level 1 with dict copy, advanced streaming, 38119 github.tar, level 1 with dict load, advanced streaming, 38364 github.tar, level 3, advanced streaming, 38831 github.tar, level 3 with dict, advanced streaming, 37995 @@ -1088,64 +1088,64 @@ github.tar, level 4 with dict dds, advanced github.tar, level 4 with dict copy, advanced streaming, 37948 github.tar, level 4 with dict load, advanced streaming, 37927 github.tar, level 5 row 1, advanced streaming, 39651 -github.tar, level 5 row 1 with dict dms, advanced streaming, 39059 -github.tar, level 5 row 1 with dict dds, advanced streaming, 39067 -github.tar, level 5 row 1 with dict copy, advanced streaming, 39082 -github.tar, level 5 row 1 with dict load, advanced streaming, 38999 +github.tar, level 5 row 1 with dict dms, advanced streaming, 39043 +github.tar, level 5 row 1 with dict dds, advanced streaming, 39069 +github.tar, level 5 row 1 with dict copy, advanced streaming, 39145 +github.tar, level 5 row 1 with dict load, advanced streaming, 39000 github.tar, level 5 row 2, advanced streaming, 39701 github.tar, level 5 row 2 with dict dms, advanced streaming, 39365 github.tar, level 5 row 2 with dict dds, advanced streaming, 39233 github.tar, level 5 row 2 with dict copy, advanced streaming, 39715 github.tar, level 5 row 2 with dict load, advanced streaming, 39158 github.tar, level 5, advanced streaming, 39651 -github.tar, level 5 with dict, advanced streaming, 39082 -github.tar, level 5 with dict dms, advanced streaming, 39059 -github.tar, level 5 with dict dds, advanced streaming, 39067 -github.tar, level 5 with dict copy, advanced streaming, 39082 -github.tar, level 5 with dict load, advanced streaming, 38999 +github.tar, level 5 with dict, advanced streaming, 39145 +github.tar, level 5 with dict dms, advanced streaming, 39043 +github.tar, level 5 with dict dds, advanced streaming, 39069 +github.tar, level 5 with dict copy, advanced streaming, 39145 +github.tar, level 5 with dict load, advanced streaming, 39000 github.tar, level 6, advanced streaming, 39282 github.tar, level 6 with dict, advanced streaming, 38656 -github.tar, level 6 with dict dms, advanced streaming, 38636 -github.tar, level 6 with dict dds, advanced streaming, 38634 +github.tar, level 6 with dict dms, advanced streaming, 38640 +github.tar, level 6 with dict dds, advanced streaming, 38643 github.tar, level 6 with dict copy, advanced streaming, 38656 -github.tar, level 6 with dict load, advanced streaming, 38648 -github.tar, level 7 row 1, advanced streaming, 38110 -github.tar, level 7 row 1 with dict dms, advanced streaming, 37858 -github.tar, level 7 row 1 with dict dds, advanced streaming, 37882 -github.tar, level 7 row 1 with dict copy, advanced streaming, 37865 -github.tar, level 7 row 1 with dict load, advanced streaming, 37436 +github.tar, level 6 with dict load, advanced streaming, 38647 +github.tar, level 7 row 1, advanced streaming, 38005 +github.tar, level 7 row 1 with dict dms, advanced streaming, 37832 +github.tar, level 7 row 1 with dict dds, advanced streaming, 37857 +github.tar, level 7 row 1 with dict copy, advanced streaming, 37839 +github.tar, level 7 row 1 with dict load, advanced streaming, 37286 github.tar, level 7 row 2, advanced streaming, 38077 github.tar, level 7 row 2 with dict dms, advanced streaming, 38012 github.tar, level 7 row 2 with dict dds, advanced streaming, 38014 github.tar, level 7 row 2 with dict copy, advanced streaming, 38101 github.tar, level 7 row 2 with dict load, advanced streaming, 37402 -github.tar, level 7, advanced streaming, 38110 -github.tar, level 7 with dict, advanced streaming, 37865 -github.tar, level 7 with dict dms, advanced streaming, 37858 -github.tar, level 7 with dict dds, advanced streaming, 37882 -github.tar, level 7 with dict copy, advanced streaming, 37865 -github.tar, level 7 with dict load, advanced streaming, 37436 -github.tar, level 9, advanced streaming, 36760 -github.tar, level 9 with dict, advanced streaming, 36484 -github.tar, level 9 with dict dms, advanced streaming, 36567 -github.tar, level 9 with dict dds, advanced streaming, 36628 -github.tar, level 9 with dict copy, advanced streaming, 36484 -github.tar, level 9 with dict load, advanced streaming, 36401 -github.tar, level 11 row 1, advanced streaming, 36081 +github.tar, level 7, advanced streaming, 38005 +github.tar, level 7 with dict, advanced streaming, 37839 +github.tar, level 7 with dict dms, advanced streaming, 37832 +github.tar, level 7 with dict dds, advanced streaming, 37857 +github.tar, level 7 with dict copy, advanced streaming, 37839 +github.tar, level 7 with dict load, advanced streaming, 37286 +github.tar, level 9, advanced streaming, 36723 +github.tar, level 9 with dict, advanced streaming, 36531 +github.tar, level 9 with dict dms, advanced streaming, 36615 +github.tar, level 9 with dict dds, advanced streaming, 36682 +github.tar, level 9 with dict copy, advanced streaming, 36531 +github.tar, level 9 with dict load, advanced streaming, 36322 +github.tar, level 11 row 1, advanced streaming, 36085 github.tar, level 11 row 1 with dict dms, advanced streaming, 36963 github.tar, level 11 row 1 with dict dds, advanced streaming, 36963 github.tar, level 11 row 1 with dict copy, advanced streaming, 36557 -github.tar, level 11 row 1 with dict load, advanced streaming, 36434 +github.tar, level 11 row 1 with dict load, advanced streaming, 36423 github.tar, level 11 row 2, advanced streaming, 36110 github.tar, level 11 row 2 with dict dms, advanced streaming, 36963 github.tar, level 11 row 2 with dict dds, advanced streaming, 36963 github.tar, level 11 row 2 with dict copy, advanced streaming, 36557 github.tar, level 11 row 2 with dict load, advanced streaming, 36459 -github.tar, level 12 row 1, advanced streaming, 36081 +github.tar, level 12 row 1, advanced streaming, 36085 github.tar, level 12 row 1 with dict dms, advanced streaming, 36986 github.tar, level 12 row 1 with dict dds, advanced streaming, 36986 github.tar, level 12 row 1 with dict copy, advanced streaming, 36609 -github.tar, level 12 row 1 with dict load, advanced streaming, 36434 +github.tar, level 12 row 1 with dict load, advanced streaming, 36423 github.tar, level 12 row 2, advanced streaming, 36110 github.tar, level 12 row 2 with dict dms, advanced streaming, 36986 github.tar, level 12 row 2 with dict dds, advanced streaming, 36986 @@ -1158,17 +1158,17 @@ github.tar, level 13 with dict dds, advanced github.tar, level 13 with dict copy, advanced streaming, 37130 github.tar, level 13 with dict load, advanced streaming, 36010 github.tar, level 16, advanced streaming, 40466 -github.tar, level 16 with dict, advanced streaming, 33374 -github.tar, level 16 with dict dms, advanced streaming, 33206 -github.tar, level 16 with dict dds, advanced streaming, 33206 -github.tar, level 16 with dict copy, advanced streaming, 33374 +github.tar, level 16 with dict, advanced streaming, 33375 +github.tar, level 16 with dict dms, advanced streaming, 33207 +github.tar, level 16 with dict dds, advanced streaming, 33207 +github.tar, level 16 with dict copy, advanced streaming, 33375 github.tar, level 16 with dict load, advanced streaming, 39081 -github.tar, level 19, advanced streaming, 32276 -github.tar, level 19 with dict, advanced streaming, 32712 -github.tar, level 19 with dict dms, advanced streaming, 32555 -github.tar, level 19 with dict dds, advanced streaming, 32555 -github.tar, level 19 with dict copy, advanced streaming, 32712 -github.tar, level 19 with dict load, advanced streaming, 32479 +github.tar, level 19, advanced streaming, 32262 +github.tar, level 19 with dict, advanced streaming, 32701 +github.tar, level 19 with dict dms, advanced streaming, 32565 +github.tar, level 19 with dict dds, advanced streaming, 32565 +github.tar, level 19 with dict copy, advanced streaming, 32701 +github.tar, level 19 with dict load, advanced streaming, 32428 github.tar, no source size, advanced streaming, 38828 github.tar, no source size with dict, advanced streaming, 38000 github.tar, long distance mode, advanced streaming, 40252 @@ -1179,7 +1179,7 @@ github.tar, small hash log, advanced github.tar, small chain log, advanced streaming, 41669 github.tar, explicit params, advanced streaming, 41385 github.tar, uncompressed literals, advanced streaming, 41525 -github.tar, uncompressed literals optimal, advanced streaming, 35397 +github.tar, uncompressed literals optimal, advanced streaming, 35356 github.tar, huffman literals, advanced streaming, 38853 github.tar, multithreaded with advanced params, advanced streaming, 41525 silesia, level -5, old streaming, 6854744 @@ -1189,16 +1189,16 @@ silesia, level 0, old stre silesia, level 1, old streaming, 5306388 silesia, level 3, old streaming, 4842075 silesia, level 4, old streaming, 4779186 -silesia, level 5, old streaming, 4666323 -silesia, level 6, old streaming, 4603066 -silesia, level 7, old streaming, 4566984 -silesia, level 9, old streaming, 4543018 +silesia, level 5, old streaming, 4667668 +silesia, level 6, old streaming, 4604351 +silesia, level 7, old streaming, 4570271 +silesia, level 9, old streaming, 4545850 silesia, level 13, old streaming, 4493990 -silesia, level 16, old streaming, 4360041 -silesia, level 19, old streaming, 4296055 +silesia, level 16, old streaming, 4359652 +silesia, level 19, old streaming, 4266582 silesia, no source size, old streaming, 4842039 silesia, uncompressed literals, old streaming, 4842075 -silesia, uncompressed literals optimal, old streaming, 4296055 +silesia, uncompressed literals optimal, old streaming, 4266582 silesia, huffman literals, old streaming, 6172207 silesia.tar, level -5, old streaming, 6856523 silesia.tar, level -3, old streaming, 6505954 @@ -1207,82 +1207,82 @@ silesia.tar, level 0, old stre silesia.tar, level 1, old streaming, 5327708 silesia.tar, level 3, old streaming, 4859271 silesia.tar, level 4, old streaming, 4797470 -silesia.tar, level 5, old streaming, 4677748 -silesia.tar, level 6, old streaming, 4613246 -silesia.tar, level 7, old streaming, 4576664 -silesia.tar, level 9, old streaming, 4552900 +silesia.tar, level 5, old streaming, 4679020 +silesia.tar, level 6, old streaming, 4614558 +silesia.tar, level 7, old streaming, 4579823 +silesia.tar, level 9, old streaming, 4555445 silesia.tar, level 13, old streaming, 4502956 -silesia.tar, level 16, old streaming, 4360546 -silesia.tar, level 19, old streaming, 4265911 +silesia.tar, level 16, old streaming, 4360385 +silesia.tar, level 19, old streaming, 4260939 silesia.tar, no source size, old streaming, 4859267 silesia.tar, uncompressed literals, old streaming, 4859271 -silesia.tar, uncompressed literals optimal, old streaming, 4265911 +silesia.tar, uncompressed literals optimal, old streaming, 4260939 silesia.tar, huffman literals, old streaming, 6179056 github, level -5, old streaming, 204407 -github, level -5 with dict, old streaming, 46718 +github, level -5 with dict, old streaming, 45832 github, level -3, old streaming, 193253 -github, level -3 with dict, old streaming, 45395 +github, level -3 with dict, old streaming, 44671 github, level -1, old streaming, 175468 -github, level -1 with dict, old streaming, 43170 +github, level -1 with dict, old streaming, 41825 github, level 0, old streaming, 136332 github, level 0 with dict, old streaming, 41148 github, level 1, old streaming, 142365 -github, level 1 with dict, old streaming, 41682 +github, level 1 with dict, old streaming, 41266 github, level 3, old streaming, 136332 github, level 3 with dict, old streaming, 41148 github, level 4, old streaming, 136199 github, level 4 with dict, old streaming, 41251 github, level 5, old streaming, 135121 -github, level 5 with dict, old streaming, 38758 +github, level 5 with dict, old streaming, 38754 github, level 6, old streaming, 135122 -github, level 6 with dict, old streaming, 38671 +github, level 6 with dict, old streaming, 38669 github, level 7, old streaming, 135122 -github, level 7 with dict, old streaming, 38758 +github, level 7 with dict, old streaming, 38765 github, level 9, old streaming, 135122 -github, level 9 with dict, old streaming, 39437 +github, level 9 with dict, old streaming, 39439 github, level 13, old streaming, 132878 github, level 13 with dict, old streaming, 39900 github, level 16, old streaming, 133209 -github, level 16 with dict, old streaming, 37577 +github, level 16 with dict, old streaming, 37902 github, level 19, old streaming, 132879 -github, level 19 with dict, old streaming, 37576 +github, level 19 with dict, old streaming, 37916 github, no source size, old streaming, 140599 github, no source size with dict, old streaming, 40654 github, uncompressed literals, old streaming, 136332 github, uncompressed literals optimal, old streaming, 132879 github, huffman literals, old streaming, 175468 github.tar, level -5, old streaming, 52152 -github.tar, level -5 with dict, old streaming, 51045 +github.tar, level -5 with dict, old streaming, 51181 github.tar, level -3, old streaming, 45678 -github.tar, level -3 with dict, old streaming, 44656 +github.tar, level -3 with dict, old streaming, 44734 github.tar, level -1, old streaming, 42560 -github.tar, level -1 with dict, old streaming, 41151 +github.tar, level -1 with dict, old streaming, 41353 github.tar, level 0, old streaming, 38831 github.tar, level 0 with dict, old streaming, 37995 github.tar, level 1, old streaming, 39200 -github.tar, level 1 with dict, old streaming, 38089 +github.tar, level 1 with dict, old streaming, 38119 github.tar, level 3, old streaming, 38831 github.tar, level 3 with dict, old streaming, 37995 github.tar, level 4, old streaming, 38893 github.tar, level 4 with dict, old streaming, 37948 github.tar, level 5, old streaming, 39651 -github.tar, level 5 with dict, old streaming, 39082 +github.tar, level 5 with dict, old streaming, 39145 github.tar, level 6, old streaming, 39282 github.tar, level 6 with dict, old streaming, 38656 -github.tar, level 7, old streaming, 38110 -github.tar, level 7 with dict, old streaming, 37865 -github.tar, level 9, old streaming, 36760 -github.tar, level 9 with dict, old streaming, 36484 +github.tar, level 7, old streaming, 38005 +github.tar, level 7 with dict, old streaming, 37839 +github.tar, level 9, old streaming, 36723 +github.tar, level 9 with dict, old streaming, 36531 github.tar, level 13, old streaming, 35501 github.tar, level 13 with dict, old streaming, 37130 github.tar, level 16, old streaming, 40466 -github.tar, level 16 with dict, old streaming, 33374 -github.tar, level 19, old streaming, 32276 -github.tar, level 19 with dict, old streaming, 32712 +github.tar, level 16 with dict, old streaming, 33375 +github.tar, level 19, old streaming, 32262 +github.tar, level 19 with dict, old streaming, 32701 github.tar, no source size, old streaming, 38828 github.tar, no source size with dict, old streaming, 38000 github.tar, uncompressed literals, old streaming, 38831 -github.tar, uncompressed literals optimal, old streaming, 32276 +github.tar, uncompressed literals optimal, old streaming, 32262 github.tar, huffman literals, old streaming, 42560 silesia, level -5, old streaming advanced, 6854744 silesia, level -3, old streaming advanced, 6503319 @@ -1291,13 +1291,13 @@ silesia, level 0, old stre silesia, level 1, old streaming advanced, 5306388 silesia, level 3, old streaming advanced, 4842075 silesia, level 4, old streaming advanced, 4779186 -silesia, level 5, old streaming advanced, 4666323 -silesia, level 6, old streaming advanced, 4603066 -silesia, level 7, old streaming advanced, 4566984 -silesia, level 9, old streaming advanced, 4543018 +silesia, level 5, old streaming advanced, 4667668 +silesia, level 6, old streaming advanced, 4604351 +silesia, level 7, old streaming advanced, 4570271 +silesia, level 9, old streaming advanced, 4545850 silesia, level 13, old streaming advanced, 4493990 -silesia, level 16, old streaming advanced, 4360041 -silesia, level 19, old streaming advanced, 4296055 +silesia, level 16, old streaming advanced, 4359652 +silesia, level 19, old streaming advanced, 4266582 silesia, no source size, old streaming advanced, 4842039 silesia, long distance mode, old streaming advanced, 4842075 silesia, multithreaded, old streaming advanced, 4842075 @@ -1305,9 +1305,9 @@ silesia, multithreaded long distance mode, old stre silesia, small window log, old streaming advanced, 7111103 silesia, small hash log, old streaming advanced, 6526141 silesia, small chain log, old streaming advanced, 4912197 -silesia, explicit params, old streaming advanced, 4795452 +silesia, explicit params, old streaming advanced, 4795857 silesia, uncompressed literals, old streaming advanced, 4842075 -silesia, uncompressed literals optimal, old streaming advanced, 4296055 +silesia, uncompressed literals optimal, old streaming advanced, 4266582 silesia, huffman literals, old streaming advanced, 6172207 silesia, multithreaded with advanced params, old streaming advanced, 4842075 silesia.tar, level -5, old streaming advanced, 6856523 @@ -1317,13 +1317,13 @@ silesia.tar, level 0, old stre silesia.tar, level 1, old streaming advanced, 5327708 silesia.tar, level 3, old streaming advanced, 4859271 silesia.tar, level 4, old streaming advanced, 4797470 -silesia.tar, level 5, old streaming advanced, 4677748 -silesia.tar, level 6, old streaming advanced, 4613246 -silesia.tar, level 7, old streaming advanced, 4576664 -silesia.tar, level 9, old streaming advanced, 4552900 +silesia.tar, level 5, old streaming advanced, 4679020 +silesia.tar, level 6, old streaming advanced, 4614558 +silesia.tar, level 7, old streaming advanced, 4579823 +silesia.tar, level 9, old streaming advanced, 4555445 silesia.tar, level 13, old streaming advanced, 4502956 -silesia.tar, level 16, old streaming advanced, 4360546 -silesia.tar, level 19, old streaming advanced, 4265911 +silesia.tar, level 16, old streaming advanced, 4360385 +silesia.tar, level 19, old streaming advanced, 4260939 silesia.tar, no source size, old streaming advanced, 4859267 silesia.tar, long distance mode, old streaming advanced, 4859271 silesia.tar, multithreaded, old streaming advanced, 4859271 @@ -1331,17 +1331,17 @@ silesia.tar, multithreaded long distance mode, old stre silesia.tar, small window log, old streaming advanced, 7117562 silesia.tar, small hash log, old streaming advanced, 6529209 silesia.tar, small chain log, old streaming advanced, 4917021 -silesia.tar, explicit params, old streaming advanced, 4806873 +silesia.tar, explicit params, old streaming advanced, 4807288 silesia.tar, uncompressed literals, old streaming advanced, 4859271 -silesia.tar, uncompressed literals optimal, old streaming advanced, 4265911 +silesia.tar, uncompressed literals optimal, old streaming advanced, 4260939 silesia.tar, huffman literals, old streaming advanced, 6179056 silesia.tar, multithreaded with advanced params, old streaming advanced, 4859271 github, level -5, old streaming advanced, 213265 -github, level -5 with dict, old streaming advanced, 49562 +github, level -5 with dict, old streaming advanced, 46708 github, level -3, old streaming advanced, 196126 -github, level -3 with dict, old streaming advanced, 44956 +github, level -3 with dict, old streaming advanced, 45476 github, level -1, old streaming advanced, 181107 -github, level -1 with dict, old streaming advanced, 42383 +github, level -1 with dict, old streaming advanced, 42060 github, level 0, old streaming advanced, 141104 github, level 0 with dict, old streaming advanced, 41113 github, level 1, old streaming advanced, 143693 @@ -1355,15 +1355,15 @@ github, level 5 with dict, old stre github, level 6, old streaming advanced, 138676 github, level 6 with dict, old streaming advanced, 38744 github, level 7, old streaming advanced, 138676 -github, level 7 with dict, old streaming advanced, 38924 +github, level 7 with dict, old streaming advanced, 38875 github, level 9, old streaming advanced, 138676 -github, level 9 with dict, old streaming advanced, 38981 +github, level 9 with dict, old streaming advanced, 38941 github, level 13, old streaming advanced, 138676 github, level 13 with dict, old streaming advanced, 39725 github, level 16, old streaming advanced, 138575 -github, level 16 with dict, old streaming advanced, 40789 +github, level 16 with dict, old streaming advanced, 40804 github, level 19, old streaming advanced, 132879 -github, level 19 with dict, old streaming advanced, 37576 +github, level 19 with dict, old streaming advanced, 37916 github, no source size, old streaming advanced, 140599 github, no source size with dict, old streaming advanced, 40608 github, long distance mode, old streaming advanced, 141104 @@ -1378,11 +1378,11 @@ github, uncompressed literals optimal, old stre github, huffman literals, old streaming advanced, 181107 github, multithreaded with advanced params, old streaming advanced, 141104 github.tar, level -5, old streaming advanced, 52152 -github.tar, level -5 with dict, old streaming advanced, 50988 +github.tar, level -5 with dict, old streaming advanced, 51129 github.tar, level -3, old streaming advanced, 45678 -github.tar, level -3 with dict, old streaming advanced, 44729 +github.tar, level -3 with dict, old streaming advanced, 44986 github.tar, level -1, old streaming advanced, 42560 -github.tar, level -1 with dict, old streaming advanced, 41589 +github.tar, level -1 with dict, old streaming advanced, 41650 github.tar, level 0, old streaming advanced, 38831 github.tar, level 0 with dict, old streaming advanced, 38013 github.tar, level 1, old streaming advanced, 39200 @@ -1392,19 +1392,19 @@ github.tar, level 3 with dict, old stre github.tar, level 4, old streaming advanced, 38893 github.tar, level 4 with dict, old streaming advanced, 38063 github.tar, level 5, old streaming advanced, 39651 -github.tar, level 5 with dict, old streaming advanced, 38997 +github.tar, level 5 with dict, old streaming advanced, 39018 github.tar, level 6, old streaming advanced, 39282 -github.tar, level 6 with dict, old streaming advanced, 38640 -github.tar, level 7, old streaming advanced, 38110 -github.tar, level 7 with dict, old streaming advanced, 37387 -github.tar, level 9, old streaming advanced, 36760 -github.tar, level 9 with dict, old streaming advanced, 36312 +github.tar, level 6 with dict, old streaming advanced, 38635 +github.tar, level 7, old streaming advanced, 38005 +github.tar, level 7 with dict, old streaming advanced, 37264 +github.tar, level 9, old streaming advanced, 36723 +github.tar, level 9 with dict, old streaming advanced, 36241 github.tar, level 13, old streaming advanced, 35501 github.tar, level 13 with dict, old streaming advanced, 35807 github.tar, level 16, old streaming advanced, 40466 github.tar, level 16 with dict, old streaming advanced, 38578 -github.tar, level 19, old streaming advanced, 32276 -github.tar, level 19 with dict, old streaming advanced, 32704 +github.tar, level 19, old streaming advanced, 32262 +github.tar, level 19 with dict, old streaming advanced, 32678 github.tar, no source size, old streaming advanced, 38828 github.tar, no source size with dict, old streaming advanced, 38015 github.tar, long distance mode, old streaming advanced, 38831 @@ -1415,66 +1415,66 @@ github.tar, small hash log, old stre github.tar, small chain log, old streaming advanced, 41669 github.tar, explicit params, old streaming advanced, 41385 github.tar, uncompressed literals, old streaming advanced, 38831 -github.tar, uncompressed literals optimal, old streaming advanced, 32276 +github.tar, uncompressed literals optimal, old streaming advanced, 32262 github.tar, huffman literals, old streaming advanced, 42560 github.tar, multithreaded with advanced params, old streaming advanced, 38831 -github, level -5 with dict, old streaming cdict, 46718 -github, level -3 with dict, old streaming cdict, 45395 -github, level -1 with dict, old streaming cdict, 43170 +github, level -5 with dict, old streaming cdict, 45832 +github, level -3 with dict, old streaming cdict, 44671 +github, level -1 with dict, old streaming cdict, 41825 github, level 0 with dict, old streaming cdict, 41148 -github, level 1 with dict, old streaming cdict, 41682 +github, level 1 with dict, old streaming cdict, 41266 github, level 3 with dict, old streaming cdict, 41148 github, level 4 with dict, old streaming cdict, 41251 -github, level 5 with dict, old streaming cdict, 38758 -github, level 6 with dict, old streaming cdict, 38671 -github, level 7 with dict, old streaming cdict, 38758 -github, level 9 with dict, old streaming cdict, 39437 +github, level 5 with dict, old streaming cdict, 38754 +github, level 6 with dict, old streaming cdict, 38669 +github, level 7 with dict, old streaming cdict, 38765 +github, level 9 with dict, old streaming cdict, 39439 github, level 13 with dict, old streaming cdict, 39900 -github, level 16 with dict, old streaming cdict, 37577 -github, level 19 with dict, old streaming cdict, 37576 +github, level 16 with dict, old streaming cdict, 37902 +github, level 19 with dict, old streaming cdict, 37916 github, no source size with dict, old streaming cdict, 40654 -github.tar, level -5 with dict, old streaming cdict, 51191 -github.tar, level -3 with dict, old streaming cdict, 44821 -github.tar, level -1 with dict, old streaming cdict, 41775 +github.tar, level -5 with dict, old streaming cdict, 51286 +github.tar, level -3 with dict, old streaming cdict, 45147 +github.tar, level -1 with dict, old streaming cdict, 41865 github.tar, level 0 with dict, old streaming cdict, 37956 github.tar, level 1 with dict, old streaming cdict, 38364 github.tar, level 3 with dict, old streaming cdict, 37956 github.tar, level 4 with dict, old streaming cdict, 37927 -github.tar, level 5 with dict, old streaming cdict, 38999 -github.tar, level 6 with dict, old streaming cdict, 38648 -github.tar, level 7 with dict, old streaming cdict, 37436 -github.tar, level 9 with dict, old streaming cdict, 36401 +github.tar, level 5 with dict, old streaming cdict, 39000 +github.tar, level 6 with dict, old streaming cdict, 38647 +github.tar, level 7 with dict, old streaming cdict, 37286 +github.tar, level 9 with dict, old streaming cdict, 36322 github.tar, level 13 with dict, old streaming cdict, 36010 github.tar, level 16 with dict, old streaming cdict, 39081 -github.tar, level 19 with dict, old streaming cdict, 32479 +github.tar, level 19 with dict, old streaming cdict, 32428 github.tar, no source size with dict, old streaming cdict, 38000 -github, level -5 with dict, old streaming advanced cdict, 49562 -github, level -3 with dict, old streaming advanced cdict, 44956 -github, level -1 with dict, old streaming advanced cdict, 42383 +github, level -5 with dict, old streaming advanced cdict, 46708 +github, level -3 with dict, old streaming advanced cdict, 45476 +github, level -1 with dict, old streaming advanced cdict, 42060 github, level 0 with dict, old streaming advanced cdict, 41113 github, level 1 with dict, old streaming advanced cdict, 42430 github, level 3 with dict, old streaming advanced cdict, 41113 github, level 4 with dict, old streaming advanced cdict, 41084 github, level 5 with dict, old streaming advanced cdict, 38723 github, level 6 with dict, old streaming advanced cdict, 38744 -github, level 7 with dict, old streaming advanced cdict, 38924 -github, level 9 with dict, old streaming advanced cdict, 38981 +github, level 7 with dict, old streaming advanced cdict, 38875 +github, level 9 with dict, old streaming advanced cdict, 38941 github, level 13 with dict, old streaming advanced cdict, 39725 -github, level 16 with dict, old streaming advanced cdict, 40789 -github, level 19 with dict, old streaming advanced cdict, 37576 +github, level 16 with dict, old streaming advanced cdict, 40804 +github, level 19 with dict, old streaming advanced cdict, 37916 github, no source size with dict, old streaming advanced cdict, 40608 -github.tar, level -5 with dict, old streaming advanced cdict, 50854 -github.tar, level -3 with dict, old streaming advanced cdict, 44571 -github.tar, level -1 with dict, old streaming advanced cdict, 41477 +github.tar, level -5 with dict, old streaming advanced cdict, 50791 +github.tar, level -3 with dict, old streaming advanced cdict, 44926 +github.tar, level -1 with dict, old streaming advanced cdict, 41482 github.tar, level 0 with dict, old streaming advanced cdict, 38013 github.tar, level 1 with dict, old streaming advanced cdict, 38168 github.tar, level 3 with dict, old streaming advanced cdict, 38013 github.tar, level 4 with dict, old streaming advanced cdict, 38063 -github.tar, level 5 with dict, old streaming advanced cdict, 38997 -github.tar, level 6 with dict, old streaming advanced cdict, 38640 -github.tar, level 7 with dict, old streaming advanced cdict, 37387 -github.tar, level 9 with dict, old streaming advanced cdict, 36312 +github.tar, level 5 with dict, old streaming advanced cdict, 39018 +github.tar, level 6 with dict, old streaming advanced cdict, 38635 +github.tar, level 7 with dict, old streaming advanced cdict, 37264 +github.tar, level 9 with dict, old streaming advanced cdict, 36241 github.tar, level 13 with dict, old streaming advanced cdict, 35807 github.tar, level 16 with dict, old streaming advanced cdict, 38578 -github.tar, level 19 with dict, old streaming advanced cdict, 32704 +github.tar, level 19 with dict, old streaming advanced cdict, 32678 github.tar, no source size with dict, old streaming advanced cdict, 38015 diff --git a/src/dependencies/zstd-1.5.4/tests/regression/test.c b/src/dependencies/zstd-1.5.6/tests/regression/test.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/regression/test.c rename to src/dependencies/zstd-1.5.6/tests/regression/test.c diff --git a/src/dependencies/zstd-1.5.4/tests/roundTripCrash.c b/src/dependencies/zstd-1.5.6/tests/roundTripCrash.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/roundTripCrash.c rename to src/dependencies/zstd-1.5.6/tests/roundTripCrash.c diff --git a/src/dependencies/zstd-1.5.4/tests/seqgen.c b/src/dependencies/zstd-1.5.6/tests/seqgen.c similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/seqgen.c rename to src/dependencies/zstd-1.5.6/tests/seqgen.c diff --git a/src/dependencies/zstd-1.5.4/tests/seqgen.h b/src/dependencies/zstd-1.5.6/tests/seqgen.h similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/seqgen.h rename to src/dependencies/zstd-1.5.6/tests/seqgen.h diff --git a/src/dependencies/zstd-1.5.4/tests/test-license.py b/src/dependencies/zstd-1.5.6/tests/test-license.py similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/test-license.py rename to src/dependencies/zstd-1.5.6/tests/test-license.py diff --git a/src/dependencies/zstd-1.5.4/tests/test-variants.sh b/src/dependencies/zstd-1.5.6/tests/test-variants.sh similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/test-variants.sh rename to src/dependencies/zstd-1.5.6/tests/test-variants.sh diff --git a/src/dependencies/zstd-1.5.4/tests/test-zstd-versions.py b/src/dependencies/zstd-1.5.6/tests/test-zstd-versions.py similarity index 100% rename from src/dependencies/zstd-1.5.4/tests/test-zstd-versions.py rename to src/dependencies/zstd-1.5.6/tests/test-zstd-versions.py diff --git a/src/dependencies/zstd-1.5.4/tests/zstreamtest.c b/src/dependencies/zstd-1.5.6/tests/zstreamtest.c similarity index 95% rename from src/dependencies/zstd-1.5.4/tests/zstreamtest.c rename to src/dependencies/zstd-1.5.6/tests/zstreamtest.c index 14c4af8..e0ee4c3 100644 --- a/src/dependencies/zstd-1.5.4/tests/zstreamtest.c +++ b/src/dependencies/zstd-1.5.6/tests/zstreamtest.c @@ -408,8 +408,8 @@ static int basicUnitTests(U32 seed, double compressibility, int bigTests) if (inBuff.pos != inBuff.size) goto _output_error; /* should have read the entire frame */ DISPLAYLEVEL(3, "OK \n"); - /* Re-use without init */ - DISPLAYLEVEL(3, "test%3i : decompress again without init (re-use previous settings): ", testNb++); + /* Reuse without init */ + DISPLAYLEVEL(3, "test%3i : decompress again without init (reuse previous settings): ", testNb++); outBuff.pos = 0; { size_t const remaining = ZSTD_decompressStream(zd, &outBuff, &inBuff2); if (remaining != 0) goto _output_error; } /* should reach end of frame == 0; otherwise, some data left, or an error */ @@ -653,8 +653,8 @@ static int basicUnitTests(U32 seed, double compressibility, int bigTests) DISPLAYLEVEL(3, "OK (error detected : %s) \n", ZSTD_getErrorName(r)); } } - /* Compression state re-use scenario */ - DISPLAYLEVEL(3, "test%3i : context re-use : ", testNb++); + /* Compression state reuse scenario */ + DISPLAYLEVEL(3, "test%3i : context reuse : ", testNb++); ZSTD_freeCStream(zc); zc = ZSTD_createCStream(); if (zc==NULL) goto _output_error; /* memory allocation issue */ @@ -722,6 +722,67 @@ static int basicUnitTests(U32 seed, double compressibility, int bigTests) } DISPLAYLEVEL(3, "OK \n"); + DISPLAYLEVEL(3, "test%3i : maxBlockSize = 2KB : ", testNb++); + { + ZSTD_DCtx* dctx = ZSTD_createDCtx(); + size_t singlePassSize, streamingSize, streaming2KSize; + + { + ZSTD_CCtx* cctx = ZSTD_createCCtx(); + CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1)); + CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, 18)); + CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_contentSizeFlag, 0)); + CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_maxBlockSize, 2048)); + cSize = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBufferSize); + CHECK_Z(cSize); + ZSTD_freeCCtx(cctx); + } + + CHECK_Z(ZSTD_decompressDCtx(dctx, decodedBuffer, CNBufferSize, compressedBuffer, cSize)); + singlePassSize = ZSTD_sizeof_DCtx(dctx); + CHECK_Z(singlePassSize); + + inBuff.src = compressedBuffer; + inBuff.size = cSize; + + outBuff.dst = decodedBuffer; + outBuff.size = decodedBufferSize; + + CHECK_Z(ZSTD_DCtx_setParameter(dctx, ZSTD_d_maxBlockSize, 2048)); + inBuff.pos = 0; + outBuff.pos = 0; + { + size_t const r = ZSTD_decompressStream(dctx, &outBuff, &inBuff); + CHECK_Z(r); + CHECK(r != 0, "Entire frame must be decompressed"); + } + streaming2KSize = ZSTD_sizeof_DCtx(dctx); + CHECK_Z(streaming2KSize); + + CHECK_Z(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_and_parameters)); + inBuff.pos = 0; + outBuff.pos = 0; + { + size_t const r = ZSTD_decompressStream(dctx, &outBuff, &inBuff); + CHECK_Z(r); + CHECK(r != 0, "Entire frame must be decompressed"); + } + streamingSize = ZSTD_sizeof_DCtx(dctx); + CHECK_Z(streamingSize); + + CHECK_Z(ZSTD_DCtx_setParameter(dctx, ZSTD_d_maxBlockSize, 1024)); + inBuff.pos = 0; + outBuff.pos = 0; + CHECK(!ZSTD_isError(ZSTD_decompressStream(dctx, &outBuff, &inBuff)), "decompression must fail"); + + CHECK(streamingSize < singlePassSize + (1 << 18) + 3 * ZSTD_BLOCKSIZE_MAX, "Streaming doesn't use the right amount of memory"); + CHECK(streamingSize != streaming2KSize + 3 * (ZSTD_BLOCKSIZE_MAX - 2048), "ZSTD_d_blockSizeMax didn't save the right amount of memory"); + DISPLAYLEVEL(3, "| %zu | %zu | %zu | ", singlePassSize, streaming2KSize, streamingSize); + + ZSTD_freeDCtx(dctx); + } + DISPLAYLEVEL(3, "OK \n"); + /* Decompression with ZSTD_d_stableOutBuffer */ cSize = ZSTD_compress(compressedBuffer, compressedBufferSize, CNBuffer, CNBufferSize, 1); CHECK_Z(cSize); @@ -1859,7 +1920,7 @@ static int basicUnitTests(U32 seed, double compressibility, int bigTests) DISPLAYLEVEL(3, "test%3i : Block-Level External Sequence Producer API: ", testNb++); { size_t const dstBufSize = ZSTD_compressBound(CNBufferSize); - BYTE* const dstBuf = (BYTE*)malloc(ZSTD_compressBound(dstBufSize)); + BYTE* const dstBuf = (BYTE*)malloc(dstBufSize); size_t const checkBufSize = CNBufferSize; BYTE* const checkBuf = (BYTE*)malloc(checkBufSize); int enableFallback; @@ -2295,6 +2356,102 @@ static int basicUnitTests(U32 seed, double compressibility, int bigTests) } DISPLAYLEVEL(3, "OK \n"); + DISPLAYLEVEL(3, "test%3i : Testing external sequence producer with static CCtx: ", testNb++); + { + size_t const dstBufSize = ZSTD_compressBound(CNBufferSize); + BYTE* const dstBuf = (BYTE*)malloc(dstBufSize); + size_t const checkBufSize = CNBufferSize; + BYTE* const checkBuf = (BYTE*)malloc(checkBufSize); + ZSTD_CCtx_params* params = ZSTD_createCCtxParams(); + ZSTD_CCtx* staticCCtx; + void* cctxBuf; + EMF_testCase seqProdState; + + CHECK_Z(ZSTD_CCtxParams_setParameter(params, ZSTD_c_validateSequences, 1)); + CHECK_Z(ZSTD_CCtxParams_setParameter(params, ZSTD_c_enableSeqProducerFallback, 0)); + ZSTD_CCtxParams_registerSequenceProducer(params, &seqProdState, zstreamSequenceProducer); + + { + size_t const cctxSize = ZSTD_estimateCCtxSize_usingCCtxParams(params); + cctxBuf = malloc(cctxSize); + staticCCtx = ZSTD_initStaticCCtx(cctxBuf, cctxSize); + ZSTD_CCtx_setParametersUsingCCtxParams(staticCCtx, params); + } + + // Check that compression with external sequence producer succeeds when expected + seqProdState = EMF_LOTS_OF_SEQS; + { + size_t dResult; + size_t const cResult = ZSTD_compress2(staticCCtx, dstBuf, dstBufSize, CNBuffer, CNBufferSize); + CHECK(ZSTD_isError(cResult), "EMF: Compression error: %s", ZSTD_getErrorName(cResult)); + dResult = ZSTD_decompress(checkBuf, checkBufSize, dstBuf, cResult); + CHECK(ZSTD_isError(dResult), "EMF: Decompression error: %s", ZSTD_getErrorName(dResult)); + CHECK(dResult != CNBufferSize, "EMF: Corruption!"); + CHECK(memcmp(CNBuffer, checkBuf, CNBufferSize) != 0, "EMF: Corruption!"); + } + + // Check that compression with external sequence producer fails when expected + seqProdState = EMF_BIG_ERROR; + { + size_t const cResult = ZSTD_compress2(staticCCtx, dstBuf, dstBufSize, CNBuffer, CNBufferSize); + CHECK(!ZSTD_isError(cResult), "EMF: Should have raised an error!"); + CHECK( + ZSTD_getErrorCode(cResult) != ZSTD_error_sequenceProducer_failed, + "EMF: Wrong error code: %s", ZSTD_getErrorName(cResult) + ); + } + + free(dstBuf); + free(checkBuf); + free(cctxBuf); + ZSTD_freeCCtxParams(params); + } + DISPLAYLEVEL(3, "OK \n"); + + DISPLAYLEVEL(3, "test%3i : Decoder should reject invalid frame header on legacy frames: ", testNb++); + { + const unsigned char compressed[] = { 0x26,0xb5,0x2f,0xfd,0x50,0x91,0xfd,0xd8,0xb5 }; + const size_t compressedSize = 9; + size_t const dSize = ZSTD_decompress(NULL, 0, compressed, compressedSize); + CHECK(!ZSTD_isError(dSize), "must reject when legacy frame header is invalid"); + } + DISPLAYLEVEL(3, "OK \n"); + + DISPLAYLEVEL(3, "test%3i : Test single-shot fallback for magicless mode: ", testNb++); + { + // Aquire resources + size_t const srcSize = COMPRESSIBLE_NOISE_LENGTH; + void* src = malloc(srcSize); + size_t const dstSize = ZSTD_compressBound(srcSize); + void* dst = malloc(dstSize); + size_t const valSize = srcSize; + void* val = malloc(valSize); + ZSTD_inBuffer inBuf = { dst, dstSize, 0 }; + ZSTD_outBuffer outBuf = { val, valSize, 0 }; + ZSTD_CCtx* cctx = ZSTD_createCCtx(); + ZSTD_DCtx* dctx = ZSTD_createDCtx(); + CHECK(!src || !dst || !val || !dctx || !cctx, "memory allocation failure"); + + // Write test data for decompression to dst + RDG_genBuffer(src, srcSize, compressibility, 0.0, 0xdeadbeef); + CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_format, ZSTD_f_zstd1_magicless)); + CHECK_Z(ZSTD_compress2(cctx, dst, dstSize, src, srcSize)); + + // Run decompression + CHECK_Z(ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, ZSTD_f_zstd1_magicless)); + CHECK_Z(ZSTD_decompressStream(dctx, &outBuf, &inBuf)); + + // Validate + CHECK(outBuf.pos != srcSize, "decompressed size must match"); + CHECK(memcmp(src, val, srcSize) != 0, "decompressed data must match"); + + // Cleanup + free(src); free(dst); free(val); + ZSTD_freeCCtx(cctx); + ZSTD_freeDCtx(dctx); + } + DISPLAYLEVEL(3, "OK \n"); + _end: FUZ_freeDictionary(dictionary); ZSTD_freeCStream(zc); @@ -2845,6 +3002,13 @@ static int fuzzerTests_newAPI(U32 seed, int nbTests, int startTest, if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_c_forceMaxWindow, FUZ_rand(&lseed) & 1, opaqueAPI) ); if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_c_deterministicRefPrefix, FUZ_rand(&lseed) & 1, opaqueAPI) ); + /* Set max block size parameters */ + if (FUZ_rand(&lseed) & 1) { + int maxBlockSize = (int)(FUZ_rand(&lseed) % ZSTD_BLOCKSIZE_MAX); + maxBlockSize = MAX(1024, maxBlockSize); + CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_c_maxBlockSize, maxBlockSize, opaqueAPI) ); + } + /* Apply parameters */ if (opaqueAPI) { DISPLAYLEVEL(5, "t%u: applying CCtxParams \n", testNb); @@ -2976,6 +3140,13 @@ static int fuzzerTests_newAPI(U32 seed, int nbTests, int startTest, if (FUZ_rand(&lseed) & 1) { CHECK_Z(ZSTD_DCtx_setParameter(zd, ZSTD_d_disableHuffmanAssembly, FUZ_rand(&lseed) & 1)); } + if (FUZ_rand(&lseed) & 1) { + int maxBlockSize; + CHECK_Z(ZSTD_CCtx_getParameter(zc, ZSTD_c_maxBlockSize, &maxBlockSize)); + CHECK_Z(ZSTD_DCtx_setParameter(zd, ZSTD_d_maxBlockSize, maxBlockSize)); + } else { + CHECK_Z(ZSTD_DCtx_setParameter(zd, ZSTD_d_maxBlockSize, 0)); + } { size_t decompressionResult = 1; ZSTD_inBuffer inBuff = { cBuffer, cSize, 0 }; ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 }; diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/.gitignore b/src/dependencies/zstd-1.5.6/zlibWrapper/.gitignore similarity index 100% rename from src/dependencies/zstd-1.5.4/zlibWrapper/.gitignore rename to src/dependencies/zstd-1.5.6/zlibWrapper/.gitignore diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/BUCK b/src/dependencies/zstd-1.5.6/zlibWrapper/BUCK similarity index 100% rename from src/dependencies/zstd-1.5.4/zlibWrapper/BUCK rename to src/dependencies/zstd-1.5.6/zlibWrapper/BUCK diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/Makefile b/src/dependencies/zstd-1.5.6/zlibWrapper/Makefile similarity index 100% rename from src/dependencies/zstd-1.5.4/zlibWrapper/Makefile rename to src/dependencies/zstd-1.5.6/zlibWrapper/Makefile diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/README.md b/src/dependencies/zstd-1.5.6/zlibWrapper/README.md similarity index 100% rename from src/dependencies/zstd-1.5.4/zlibWrapper/README.md rename to src/dependencies/zstd-1.5.6/zlibWrapper/README.md diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/examples/example.c b/src/dependencies/zstd-1.5.6/zlibWrapper/examples/example.c similarity index 93% rename from src/dependencies/zstd-1.5.4/zlibWrapper/examples/example.c rename to src/dependencies/zstd-1.5.6/zlibWrapper/examples/example.c index d7590e3..99fbf5b 100644 --- a/src/dependencies/zstd-1.5.4/zlibWrapper/examples/example.c +++ b/src/dependencies/zstd-1.5.6/zlibWrapper/examples/example.c @@ -77,9 +77,7 @@ int main _Z_OF((int argc, char *argv[])); void *myalloc _Z_OF((void *, unsigned, unsigned)); void myfree _Z_OF((void *, void *)); -void *myalloc(q, n, m) - void *q; - unsigned n, m; +void *myalloc(void *q, unsigned n, unsigned m) { void *buf = calloc(n, m); q = Z_NULL; @@ -110,10 +108,8 @@ void test_gzio _Z_OF((const char *fname, /* =========================================================================== * Test compress() and uncompress() */ -void test_compress(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ +void test_compress(Byte *compr, uLong comprLen, Byte *uncompr, + uLong uncomprLen) { int err; uLong len = (uLong)strlen(hello)+1; @@ -136,11 +132,7 @@ void test_compress(compr, comprLen, uncompr, uncomprLen) /* =========================================================================== * Test read/write of .gz files */ -void test_gzio(fname, uncompr, uncomprLen) - const char *fname; /* compressed file name */ - Byte *uncompr; - uLong uncomprLen; -{ +void test_gzio(const char *fname, Byte *uncompr, uLong uncomprLen) { #ifdef NO_GZCOMPRESS fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); #else @@ -222,10 +214,7 @@ void test_gzio(fname, uncompr, uncomprLen) /* =========================================================================== * Test deflate() with small buffers */ -void test_deflate(compr, comprLen) - Byte *compr; - uLong comprLen; -{ +void test_deflate(Byte *compr, uLong comprLen) { z_stream c_stream; /* compression stream */ int err; uLong len = (uLong)strlen(hello)+1; @@ -260,10 +249,8 @@ void test_deflate(compr, comprLen) /* =========================================================================== * Test inflate() with small buffers */ -void test_inflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ +void test_inflate(Byte *compr, uLong comprLen, Byte *uncompr, + uLong uncomprLen) { int err; z_stream d_stream; /* decompression stream */ @@ -301,10 +288,8 @@ void test_inflate(compr, comprLen, uncompr, uncomprLen) /* =========================================================================== * Test deflate() with large buffers and dynamic change of compression level */ -void test_large_deflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ +void test_large_deflate(Byte *compr, uLong comprLen, Byte *uncompr, + uLong uncomprLen) { z_stream c_stream; /* compression stream */ int err; @@ -355,11 +340,9 @@ void test_large_deflate(compr, comprLen, uncompr, uncomprLen) /* =========================================================================== * Test inflate() with large buffers - */ -void test_large_inflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ + */ +void test_large_inflate(Byte *compr, uLong comprLen, Byte *uncompr, + uLong uncomprLen) { int err; z_stream d_stream; /* decompression stream */ @@ -397,10 +380,7 @@ void test_large_inflate(compr, comprLen, uncompr, uncomprLen) /* =========================================================================== * Test deflate() with full flush */ -void test_flush(compr, comprLen) - Byte *compr; - uLong *comprLen; -{ +void test_flush(Byte *compr, uLong *comprLen) { z_stream c_stream; /* compression stream */ int err; uInt len = (uInt)strlen(hello)+1; @@ -435,10 +415,7 @@ void test_flush(compr, comprLen) /* =========================================================================== * Test inflateSync() */ -void test_sync(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ +void test_sync(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen) { int err; z_stream d_stream; /* decompression stream */ @@ -479,10 +456,7 @@ void test_sync(compr, comprLen, uncompr, uncomprLen) /* =========================================================================== * Test deflate() with preset dictionary */ -void test_dict_deflate(compr, comprLen) - Byte *compr; - uLong comprLen; -{ +void test_dict_deflate(Byte *compr, uLong comprLen) { z_stream c_stream; /* compression stream */ int err; @@ -516,10 +490,8 @@ void test_dict_deflate(compr, comprLen) /* =========================================================================== * Test inflate() with a preset dictionary */ -void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ +void test_dict_inflate(Byte *compr, uLong comprLen, Byte *uncompr, + uLong uncomprLen) { int err; z_stream d_stream; /* decompression stream */ @@ -567,10 +539,7 @@ void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) * Usage: example [output.gz [input.gz]] */ -int main(argc, argv) - int argc; - char *argv[]; -{ +int main(int argc, char *argv[]) { Byte *compr, *uncompr; uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ uLong uncomprLen = comprLen; diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/examples/example_original.c b/src/dependencies/zstd-1.5.6/zlibWrapper/examples/example_original.c similarity index 93% rename from src/dependencies/zstd-1.5.4/zlibWrapper/examples/example_original.c rename to src/dependencies/zstd-1.5.6/zlibWrapper/examples/example_original.c index 5b4e4d1..828b06c 100644 --- a/src/dependencies/zstd-1.5.4/zlibWrapper/examples/example_original.c +++ b/src/dependencies/zstd-1.5.6/zlibWrapper/examples/example_original.c @@ -102,9 +102,7 @@ void test_gzio _Z_OF((const char *fname, /* =========================================================================== * Test compress() and uncompress() */ -void test_compress(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; +void test_compress(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen) { int err; uLong len = (uLong)strlen(hello)+1; @@ -128,10 +126,8 @@ void test_compress(compr, comprLen, uncompr, uncomprLen) /* =========================================================================== * Test read/write of .gz files */ -void test_gzio(fname, uncompr, uncomprLen) - const char *fname; /* compressed file name */ - Byte *uncompr; - uLong uncomprLen; +void test_gzio(const char *fname /* compressed file name */, Byte *uncompr, + uLong uncomprLen) { #ifdef NO_GZCOMPRESS fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); @@ -214,9 +210,7 @@ void test_gzio(fname, uncompr, uncomprLen) /* =========================================================================== * Test deflate() with small buffers */ -void test_deflate(compr, comprLen) - Byte *compr; - uLong comprLen; +void test_deflate(Byte *compr, uLong comprLen) { z_stream c_stream; /* compression stream */ int err; @@ -252,9 +246,7 @@ void test_deflate(compr, comprLen) /* =========================================================================== * Test inflate() with small buffers */ -void test_inflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; +void test_inflate(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen) { int err; z_stream d_stream; /* decompression stream */ @@ -293,9 +285,8 @@ void test_inflate(compr, comprLen, uncompr, uncomprLen) /* =========================================================================== * Test deflate() with large buffers and dynamic change of compression level */ -void test_large_deflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; +void test_large_deflate(Byte *compr, uLong comprLen, Byte *uncompr, + uLong uncomprLen) { z_stream c_stream; /* compression stream */ int err; @@ -348,9 +339,8 @@ void test_large_deflate(compr, comprLen, uncompr, uncomprLen) /* =========================================================================== * Test inflate() with large buffers */ -void test_large_inflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; +void test_large_inflate(Byte *compr, uLong comprLen, Byte *uncompr, + uLong uncomprLen) { int err; z_stream d_stream; /* decompression stream */ @@ -389,9 +379,7 @@ void test_large_inflate(compr, comprLen, uncompr, uncomprLen) /* =========================================================================== * Test deflate() with full flush */ -void test_flush(compr, comprLen) - Byte *compr; - uLong *comprLen; +void test_flush(Byte *compr, uLong comprLen) { z_stream c_stream; /* compression stream */ int err; @@ -427,9 +415,7 @@ void test_flush(compr, comprLen) /* =========================================================================== * Test inflateSync() */ -void test_sync(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; +void test_sync(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen) { int err; z_stream d_stream; /* decompression stream */ @@ -471,9 +457,7 @@ void test_sync(compr, comprLen, uncompr, uncomprLen) /* =========================================================================== * Test deflate() with preset dictionary */ -void test_dict_deflate(compr, comprLen) - Byte *compr; - uLong comprLen; +void test_dict_deflate(Byte *compr, uLong comprLen) { z_stream c_stream; /* compression stream */ int err; @@ -508,9 +492,8 @@ void test_dict_deflate(compr, comprLen) /* =========================================================================== * Test inflate() with a preset dictionary */ -void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; +void test_dict_inflate(Byte *compr, uLong comprLen, Byte *uncompr, + uLong uncomprLen) { int err; z_stream d_stream; /* decompression stream */ @@ -559,9 +542,7 @@ void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) * Usage: example [output.gz [input.gz]] */ -int main(argc, argv) - int argc; - char *argv[]; +int main(int argc, char *argv[]) { Byte *compr, *uncompr; uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/examples/fitblk.c b/src/dependencies/zstd-1.5.6/zlibWrapper/examples/fitblk.c similarity index 100% rename from src/dependencies/zstd-1.5.4/zlibWrapper/examples/fitblk.c rename to src/dependencies/zstd-1.5.6/zlibWrapper/examples/fitblk.c diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/examples/fitblk_original.c b/src/dependencies/zstd-1.5.6/zlibWrapper/examples/fitblk_original.c similarity index 100% rename from src/dependencies/zstd-1.5.4/zlibWrapper/examples/fitblk_original.c rename to src/dependencies/zstd-1.5.6/zlibWrapper/examples/fitblk_original.c diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/examples/minigzip.c b/src/dependencies/zstd-1.5.6/zlibWrapper/examples/minigzip.c similarity index 93% rename from src/dependencies/zstd-1.5.4/zlibWrapper/examples/minigzip.c rename to src/dependencies/zstd-1.5.6/zlibWrapper/examples/minigzip.c index 717a94d..1af8152 100644 --- a/src/dependencies/zstd-1.5.4/zlibWrapper/examples/minigzip.c +++ b/src/dependencies/zstd-1.5.6/zlibWrapper/examples/minigzip.c @@ -34,7 +34,7 @@ # include #endif -#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) +#if defined(MSDOS) || defined(OS2) || defined(_WIN32) || defined(__CYGWIN__) # include # include # ifdef UNDER_CE @@ -63,7 +63,7 @@ #endif #if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) -#ifndef WIN32 /* unlink already in stdio.h for WIN32 */ +#ifndef _WIN32 /* unlink already in stdio.h for WIN32 */ extern int unlink _Z_OF((const char *)); #endif #endif @@ -82,8 +82,7 @@ The strwinerror function does not change the current setting of GetLastError. */ -static char *strwinerror (error) - DWORD error; +static char *strwinerror(DWORD error) { static char buf[1024]; @@ -121,8 +120,7 @@ static char *strwinerror (error) return buf; } -static void pwinerror (s) - const char *s; +static void pwinerror (const char *s) { if (s && *s) fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ())); @@ -198,11 +196,7 @@ const char *mode; return gz_open(NULL, fd, mode); } -gzFile gz_open(path, fd, mode) - const char *path; - int fd; - const char *mode; -{ +gzFile gz_open(const char *path, int fd, const char *mode) { gzFile gz; int ret; @@ -238,11 +232,7 @@ gzFile gz_open(path, fd, mode) int gzwrite _Z_OF((gzFile, const void *, unsigned)); -int gzwrite(gz, buf, len) - gzFile gz; - const void *buf; - unsigned len; -{ +int gzwrite(gzFile gz, const void *buf, unsigned len) { z_stream *strm; unsigned char out[BUFLEN]; @@ -262,11 +252,7 @@ int gzwrite(gz, buf, len) int gzread _Z_OF((gzFile, void *, unsigned)); -int gzread(gz, buf, len) - gzFile gz; - void *buf; - unsigned len; -{ +int gzread(gzFile gz, void *buf, unsigned len) { int ret; unsigned got; unsigned char in[1]; @@ -299,9 +285,7 @@ int gzread(gz, buf, len) int gzclose _Z_OF((gzFile)); -int gzclose(gz) - gzFile gz; -{ +int gzclose(gzFile gz) { z_stream *strm; unsigned char out[BUFLEN]; @@ -328,9 +312,7 @@ int gzclose(gz) const char *gzerror _Z_OF((gzFile, int *)); -const char *gzerror(gz, err) - gzFile gz; - int *err; +const char *gzerror(gzFile gz, int *err) { *err = gz->err; return gz->msg; @@ -353,8 +335,7 @@ int main _Z_OF((int argc, char *argv[])); /* =========================================================================== * Display error message and exit */ -void error(msg) - const char *msg; +void error(const char *msg) { fprintf(stderr, "%s: %s\n", prog, msg); exit(1); @@ -364,9 +345,7 @@ void error(msg) * Compress input to output then close both files. */ -void gz_compress(in, out) - FILE *in; - gzFile out; +void gz_compress(FILE *in, gzFile out) { local char buf[BUFLEN]; int len; @@ -397,10 +376,7 @@ void gz_compress(in, out) /* Try compressing the input file at once using mmap. Return Z_OK if * if success, Z_ERRNO otherwise. */ -int gz_compress_mmap(in, out) - FILE *in; - gzFile out; -{ +int gz_compress_mmap(FILE *in, gzFile out) { int len; int err; int ifd = fileno(in); @@ -432,10 +408,7 @@ int gz_compress_mmap(in, out) /* =========================================================================== * Uncompress input to output then close both files. */ -void gz_uncompress(in, out) - gzFile in; - FILE *out; -{ +void gz_uncompress(gzFile in, FILE *out) { local char buf[BUFLEN]; int len; int err; @@ -459,10 +432,7 @@ void gz_uncompress(in, out) * Compress the given file: create a corresponding .gz file and remove the * original. */ -void file_compress(file, mode) - char *file; - char *mode; -{ +void file_compress(char *file, char *mode) { local char outfile[MAX_NAME_LEN]; FILE *in; gzFile out; @@ -494,9 +464,7 @@ void file_compress(file, mode) /* =========================================================================== * Uncompress the given file and remove the original. */ -void file_uncompress(file) - char *file; -{ +void file_uncompress(char *file) { local char buf[MAX_NAME_LEN]; char *infile, *outfile; FILE *out; @@ -546,10 +514,7 @@ void file_uncompress(file) * -1 to -9 : compression level */ -int main(argc, argv) - int argc; - char *argv[]; -{ +int main(int argc, char *argv[]) { int copyout = 0; int uncompr = 0; gzFile file; diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/examples/zwrapbench.c b/src/dependencies/zstd-1.5.6/zlibWrapper/examples/zwrapbench.c similarity index 99% rename from src/dependencies/zstd-1.5.4/zlibWrapper/examples/zwrapbench.c rename to src/dependencies/zstd-1.5.6/zlibWrapper/examples/zwrapbench.c index 3bc9a1a..33dcb2a 100644 --- a/src/dependencies/zstd-1.5.4/zlibWrapper/examples/zwrapbench.c +++ b/src/dependencies/zstd-1.5.6/zlibWrapper/examples/zwrapbench.c @@ -26,7 +26,7 @@ #include "datagen.h" /* RDG_genBuffer */ #include "xxhash.h" -#include "zstd_zlibwrapper.h" +#include "../zstd_zlibwrapper.h" @@ -109,17 +109,17 @@ static unsigned g_nbIterations = NBLOOPS; static size_t g_blockSize = 0; int g_additionalParam = 0; -void BMK_setNotificationLevel(unsigned level) { g_displayLevel=level; } +static void BMK_setNotificationLevel(unsigned level) { g_displayLevel=level; } -void BMK_setAdditionalParam(int additionalParam) { g_additionalParam=additionalParam; } +static void BMK_setAdditionalParam(int additionalParam) { g_additionalParam=additionalParam; } -void BMK_SetNbIterations(unsigned nbLoops) +static 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) +static void BMK_SetBlockSize(size_t blockSize) { g_blockSize = blockSize; DISPLAYLEVEL(2, "using blocks of size %u KB \n", (unsigned)(blockSize>>10)); @@ -798,7 +798,7 @@ static void BMK_syntheticTest(int cLevel, int cLevelLast, double compressibility } -int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles, +static int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles, const char* dictFileName, int cLevel, int cLevelLast) { double const compressibility = (double)g_compressibilityDefault / 100; diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/gzclose.c b/src/dependencies/zstd-1.5.6/zlibWrapper/gzclose.c similarity index 94% rename from src/dependencies/zstd-1.5.4/zlibWrapper/gzclose.c rename to src/dependencies/zstd-1.5.6/zlibWrapper/gzclose.c index ba43b8c..12a2dfc 100644 --- a/src/dependencies/zstd-1.5.4/zlibWrapper/gzclose.c +++ b/src/dependencies/zstd-1.5.6/zlibWrapper/gzclose.c @@ -11,9 +11,7 @@ /* gzclose() is in a separate file so that it is linked in only if it is used. That way the other gzclose functions can be used instead to avoid linking in unneeded compression or decompression routines. */ -int ZEXPORT gzclose(file) - gzFile file; -{ +int ZEXPORT gzclose(gzFile file) { #ifndef NO_GZCOMPRESS gz_statep state; diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/gzcompatibility.h b/src/dependencies/zstd-1.5.6/zlibWrapper/gzcompatibility.h similarity index 100% rename from src/dependencies/zstd-1.5.4/zlibWrapper/gzcompatibility.h rename to src/dependencies/zstd-1.5.6/zlibWrapper/gzcompatibility.h diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/gzguts.h b/src/dependencies/zstd-1.5.6/zlibWrapper/gzguts.h similarity index 100% rename from src/dependencies/zstd-1.5.4/zlibWrapper/gzguts.h rename to src/dependencies/zstd-1.5.6/zlibWrapper/gzguts.h diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/gzlib.c b/src/dependencies/zstd-1.5.6/zlibWrapper/gzlib.c similarity index 92% rename from src/dependencies/zstd-1.5.4/zlibWrapper/gzlib.c rename to src/dependencies/zstd-1.5.6/zlibWrapper/gzlib.c index eea480a..c726515 100644 --- a/src/dependencies/zstd-1.5.4/zlibWrapper/gzlib.c +++ b/src/dependencies/zstd-1.5.6/zlibWrapper/gzlib.c @@ -33,9 +33,7 @@ local gzFile gz_open _Z_OF((const void *, int, const char *)); The gz_strwinerror function does not change the current setting of GetLastError. */ -char ZLIB_INTERNAL *gz_strwinerror (error) - DWORD error; -{ +char ZLIB_INTERNAL *gz_strwinerror(DWORD error) { static char buf[1024]; wchar_t *msgbuf; @@ -75,9 +73,7 @@ char ZLIB_INTERNAL *gz_strwinerror (error) #endif /* UNDER_CE */ /* Reset gzip file state */ -local void gz_reset(state) - gz_statep state; -{ +local void gz_reset(gz_statep state) { state.state->x.have = 0; /* no output data available */ if (state.state->mode == GZ_READ) { /* for reading ... */ state.state->eof = 0; /* not at end of file */ @@ -91,11 +87,7 @@ local void gz_reset(state) } /* Open a gzip file either by name or file descriptor. */ -local gzFile gz_open(path, fd, mode) - const void *path; - int fd; - const char *mode; -{ +local gzFile gz_open(const void *path, int fd, const char *mode) { gz_statep state; z_size_t len; int oflag; @@ -270,26 +262,17 @@ local gzFile gz_open(path, fd, mode) } /* -- see zlib.h -- */ -gzFile ZEXPORT gzopen(path, mode) - const char *path; - const char *mode; -{ +gzFile ZEXPORT gzopen(const char *path, const char *mode) { return gz_open(path, -1, mode); } /* -- see zlib.h -- */ -gzFile ZEXPORT gzopen64(path, mode) - const char *path; - const char *mode; -{ +gzFile ZEXPORT gzopen64(const char *path, const char *mode) { return gz_open(path, -1, mode); } /* -- see zlib.h -- */ -gzFile ZEXPORT gzdopen(fd, mode) - int fd; - const char *mode; -{ +gzFile ZEXPORT gzdopen(int fd, const char *mode) { char *path; /* identifier for error messages */ gzFile gz; @@ -307,19 +290,13 @@ gzFile ZEXPORT gzdopen(fd, mode) /* -- see zlib.h -- */ #ifdef WIDECHAR -gzFile ZEXPORT gzopen_w(path, mode) - const wchar_t *path; - const char *mode; -{ +gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode) { return gz_open(path, -2, mode); } #endif /* -- see zlib.h -- */ -int ZEXPORT gzbuffer(file, size) - gzFile file; - unsigned size; -{ +int ZEXPORT gzbuffer(gzFile file, unsigned size) { gz_statep state; /* get internal structure and check integrity */ @@ -343,9 +320,7 @@ int ZEXPORT gzbuffer(file, size) } /* -- see zlib.h -- */ -int ZEXPORT gzrewind(file) - gzFile file; -{ +int ZEXPORT gzrewind(gzFile file) { gz_statep state; /* get internal structure */ @@ -366,11 +341,7 @@ int ZEXPORT gzrewind(file) } /* -- see zlib.h -- */ -z_off64_t ZEXPORT gzseek64(file, offset, whence) - gzFile file; - z_off64_t offset; - int whence; -{ +z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { unsigned n; z_off64_t ret; gz_statep state; @@ -443,11 +414,7 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence) } /* -- see zlib.h -- */ -z_off_t ZEXPORT gzseek(file, offset, whence) - gzFile file; - z_off_t offset; - int whence; -{ +z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence) { z_off64_t ret; ret = gzseek64(file, (z_off64_t)offset, whence); @@ -455,9 +422,7 @@ z_off_t ZEXPORT gzseek(file, offset, whence) } /* -- see zlib.h -- */ -z_off64_t ZEXPORT gztell64(file) - gzFile file; -{ +z_off64_t ZEXPORT gztell64(gzFile file) { gz_statep state; /* get internal structure and check integrity */ @@ -472,9 +437,7 @@ z_off64_t ZEXPORT gztell64(file) } /* -- see zlib.h -- */ -z_off_t ZEXPORT gztell(file) - gzFile file; -{ +z_off_t ZEXPORT gztell(gzFile file) { z_off64_t ret; ret = gztell64(file); @@ -482,9 +445,7 @@ z_off_t ZEXPORT gztell(file) } /* -- see zlib.h -- */ -z_off64_t ZEXPORT gzoffset64(file) - gzFile file; -{ +z_off64_t ZEXPORT gzoffset64(gzFile file) { z_off64_t offset; gz_statep state; @@ -505,9 +466,7 @@ z_off64_t ZEXPORT gzoffset64(file) } /* -- see zlib.h -- */ -z_off_t ZEXPORT gzoffset(file) - gzFile file; -{ +z_off_t ZEXPORT gzoffset(gzFile file) { z_off64_t ret; ret = gzoffset64(file); @@ -515,9 +474,7 @@ z_off_t ZEXPORT gzoffset(file) } /* -- see zlib.h -- */ -int ZEXPORT gzeof(file) - gzFile file; -{ +int ZEXPORT gzeof(gzFile file) { gz_statep state; /* get internal structure and check integrity */ @@ -532,10 +489,7 @@ int ZEXPORT gzeof(file) } /* -- see zlib.h -- */ -const char * ZEXPORT gzerror(file, errnum) - gzFile file; - int *errnum; -{ +const char * ZEXPORT gzerror(gzFile file, int *errnum) { gz_statep state; /* get internal structure and check integrity */ @@ -553,9 +507,7 @@ const char * ZEXPORT gzerror(file, errnum) } /* -- see zlib.h -- */ -void ZEXPORT gzclearerr(file) - gzFile file; -{ +void ZEXPORT gzclearerr(gzFile file) { gz_statep state; /* get internal structure and check integrity */ @@ -579,11 +531,7 @@ void ZEXPORT gzclearerr(file) memory). Simply save the error message as a static string. If there is an allocation failure constructing the error message, then convert the error to out of memory. */ -void ZLIB_INTERNAL gz_error(state, err, msg) - gz_statep state; - int err; - const char *msg; -{ +void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { /* free previously allocated message and clear */ if (state.state->msg != NULL) { if (state.state->err != Z_MEM_ERROR) @@ -625,8 +573,7 @@ void ZLIB_INTERNAL gz_error(state, err, msg) available) -- we need to do this to cover cases where 2's complement not used, since C standard permits 1's complement and sign-bit representations, otherwise we could just use ((unsigned)-1) >> 1 */ -unsigned ZLIB_INTERNAL gz_intmax() -{ +unsigned ZLIB_INTERNAL gz_intmax() { unsigned p, q; p = 1; diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/gzread.c b/src/dependencies/zstd-1.5.6/zlibWrapper/gzread.c similarity index 95% rename from src/dependencies/zstd-1.5.4/zlibWrapper/gzread.c rename to src/dependencies/zstd-1.5.6/zlibWrapper/gzread.c index 584fad1..ed3c178 100644 --- a/src/dependencies/zstd-1.5.4/zlibWrapper/gzread.c +++ b/src/dependencies/zstd-1.5.6/zlibWrapper/gzread.c @@ -29,12 +29,8 @@ local z_size_t gz_read _Z_OF((gz_statep, voidp, z_size_t)); state.state->fd, and update state.state->eof, state.state->err, and state.state->msg as appropriate. This function needs to loop on read(), since read() is not guaranteed to read the number of bytes requested, depending on the type of descriptor. */ -local int gz_load(state, buf, len, have) - gz_statep state; - unsigned char *buf; - unsigned len; - unsigned *have; -{ +local int gz_load(gz_statep state, unsigned char *buf, unsigned len, + unsigned *have) { ssize_t ret; unsigned get, max = ((unsigned)-1 >> 2) + 1; @@ -64,8 +60,7 @@ local int gz_load(state, buf, len, have) If strm->avail_in != 0, then the current data is moved to the beginning of the input buffer, and then the remainder of the buffer is loaded with the available data from the input file. */ -local int gz_avail(state) - gz_statep state; +local int gz_avail(gz_statep state) { unsigned got; z_streamp strm = &(state.state->strm); @@ -99,9 +94,7 @@ local int gz_avail(state) case, all further file reads will be directly to either the output buffer or a user buffer. If decompressing, the inflate state will be initialized. gz_look() will return 0 on success or -1 on failure. */ -local int gz_look(state) - gz_statep state; -{ +local int gz_look(gz_statep state) { z_streamp strm = &(state.state->strm); /* allocate read buffers and inflate memory */ @@ -184,9 +177,7 @@ local int gz_look(state) data. If the gzip stream completes, state.state->how is reset to LOOK to look for the next gzip stream or raw data, once state.state->x.have is depleted. Returns 0 on success, -1 on failure. */ -local int gz_decomp(state) - gz_statep state; -{ +local int gz_decomp(gz_statep state) { int ret = Z_OK; unsigned had; z_streamp strm = &(state.state->strm); @@ -238,9 +229,7 @@ local int gz_decomp(state) looked for to determine whether to copy or decompress. Returns -1 on error, otherwise 0. gz_fetch() will leave state.state->how as COPY or GZIP unless the end of the input file has been reached and all data has been processed. */ -local int gz_fetch(state) - gz_statep state; -{ +local int gz_fetch(gz_statep state) { z_streamp strm = &(state.state->strm); do { @@ -268,10 +257,7 @@ local int gz_fetch(state) } /* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ -local int gz_skip(state, len) - gz_statep state; - z_off64_t len; -{ +local int gz_skip(gz_statep state, z_off64_t len) { unsigned n; /* skip over len bytes or reach end-of-file, whichever comes first */ @@ -303,11 +289,7 @@ local int gz_skip(state, len) input. Return the number of bytes read. If zero is returned, either the end of file was reached, or there was an error. state.state->err must be consulted in that case to determine which. */ -local z_size_t gz_read(state, buf, len) - gz_statep state; - voidp buf; - z_size_t len; -{ +local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) { z_size_t got; unsigned n; @@ -384,11 +366,7 @@ local z_size_t gz_read(state, buf, len) } /* -- see zlib.h -- */ -int ZEXPORT gzread(file, buf, len) - gzFile file; - voidp buf; - unsigned len; -{ +int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) { gz_statep state; /* get internal structure */ @@ -420,12 +398,8 @@ int ZEXPORT gzread(file, buf, len) } /* -- see zlib.h -- */ -z_size_t ZEXPORT gzfread(buf, size, nitems, file) - voidp buf; - z_size_t size; - z_size_t nitems; - gzFile file; -{ +z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, + gzFile file) { z_size_t len; gz_statep state; @@ -468,9 +442,7 @@ ZEXTERN int ZEXPORT gzgetc _Z_OF((gzFile file)); ZEXTERN int ZEXPORT gzgetc_ _Z_OF((gzFile file)); #endif -int ZEXPORT gzgetc(file) - gzFile file; -{ +int ZEXPORT gzgetc(gzFile file) { int ret; unsigned char buf[1]; gz_statep state; @@ -497,17 +469,12 @@ int ZEXPORT gzgetc(file) return ret < 1 ? -1 : buf[0]; } -int ZEXPORT gzgetc_(file) -gzFile file; -{ +int ZEXPORT gzgetc_(gzFile file) { return gzgetc(file); } /* -- see zlib.h -- */ -int ZEXPORT gzungetc(c, file) - int c; - gzFile file; -{ +int ZEXPORT gzungetc(int c, gzFile file) { gz_statep state; /* get internal structure */ @@ -564,11 +531,7 @@ int ZEXPORT gzungetc(c, file) } /* -- see zlib.h -- */ -char * ZEXPORT gzgets(file, buf, len) - gzFile file; - char *buf; - int len; -{ +char * ZEXPORT gzgets(gzFile file, char *buf, int len) { unsigned left, n; char *str; unsigned char *eol; @@ -628,9 +591,7 @@ char * ZEXPORT gzgets(file, buf, len) } /* -- see zlib.h -- */ -int ZEXPORT gzdirect(file) - gzFile file; -{ +int ZEXPORT gzdirect(gzFile file) { gz_statep state; /* get internal structure */ @@ -648,9 +609,7 @@ int ZEXPORT gzdirect(file) } /* -- see zlib.h -- */ -int ZEXPORT gzclose_r(file) - gzFile file; -{ +int ZEXPORT gzclose_r(gzFile file) { int ret, err; gz_statep state; diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/gzwrite.c b/src/dependencies/zstd-1.5.6/zlibWrapper/gzwrite.c similarity index 94% rename from src/dependencies/zstd-1.5.4/zlibWrapper/gzwrite.c rename to src/dependencies/zstd-1.5.6/zlibWrapper/gzwrite.c index ccd4f71..81da153 100644 --- a/src/dependencies/zstd-1.5.4/zlibWrapper/gzwrite.c +++ b/src/dependencies/zstd-1.5.6/zlibWrapper/gzwrite.c @@ -19,9 +19,7 @@ local z_size_t gz_write _Z_OF((gz_statep, voidpc, z_size_t)); /* Initialize state for writing a gzip file. Mark initialization by setting state.state->size to non-zero. Return -1 on a memory allocation failure, or 0 on success. */ -local int gz_init(state) - gz_statep state; -{ +local int gz_init(gz_statep state) { int ret; z_streamp strm = &(state.state->strm); @@ -75,10 +73,7 @@ local int gz_init(state) deflate() flush value. If flush is Z_FINISH, then the deflate() state is reset to start a new gzip stream. If gz->direct is true, then simply write to the output file without compressing, and ignore flush. */ -local int gz_comp(state, flush) - gz_statep state; - int flush; -{ +local int gz_comp(gz_statep state, int flush) { int ret, writ; unsigned have, put, max = ((unsigned)-1 >> 2) + 1; z_streamp strm = &(state.state->strm); @@ -147,10 +142,7 @@ local int gz_comp(state, flush) /* Compress len zeros to output. Return -1 on a write error or memory allocation failure by gz_comp(), or 0 on success. */ -local int gz_zero(state, len) - gz_statep state; - z_off64_t len; -{ +local int gz_zero(gz_statep state, z_off64_t len) { int first; unsigned n; z_streamp strm = &(state.state->strm); @@ -180,11 +172,7 @@ local int gz_zero(state, len) /* Write len bytes from buf to file. Return the number of bytes written. If the returned value is less than len, then there was an error. */ -local z_size_t gz_write(state, buf, len) - gz_statep state; - voidpc buf; - z_size_t len; -{ +local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { z_size_t put = len; /* if len is zero, avoid unnecessary operations */ @@ -248,11 +236,7 @@ local z_size_t gz_write(state, buf, len) } /* -- see zlib.h -- */ -int ZEXPORT gzwrite(file, buf, len) - gzFile file; - voidpc buf; - unsigned len; -{ +int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) { gz_statep state; /* get internal structure */ @@ -276,12 +260,8 @@ int ZEXPORT gzwrite(file, buf, len) } /* -- see zlib.h -- */ -z_size_t ZEXPORT gzfwrite(buf, size, nitems, file) - voidpc buf; - z_size_t size; - z_size_t nitems; - gzFile file; -{ +z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems, + gzFile file) { z_size_t len; gz_statep state; @@ -307,10 +287,7 @@ z_size_t ZEXPORT gzfwrite(buf, size, nitems, file) } /* -- see zlib.h -- */ -int ZEXPORT gzputc(file, c) - gzFile file; - int c; -{ +int ZEXPORT gzputc(gzFile file, int c) { unsigned have; unsigned char buf[1]; gz_statep state; @@ -355,10 +332,7 @@ int ZEXPORT gzputc(file, c) } /* -- see zlib.h -- */ -int ZEXPORT gzputs(file, str) - gzFile file; - const char *str; -{ +int ZEXPORT gzputs(gzFile file, const char *str) { int ret; z_size_t len; gz_statep state; @@ -382,8 +356,7 @@ int ZEXPORT gzputs(file, str) #include /* -- see zlib.h -- */ -int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) -{ +int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { int len; unsigned left; char *next; @@ -454,8 +427,7 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) return len; } -int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) -{ +int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) { va_list va; int ret; @@ -468,13 +440,10 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) #else /* !STDC && !Z_HAVE_STDARG_H */ /* -- see zlib.h -- */ -int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) - gzFile file; - const char *format; - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; -{ +int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, + int a4, int a5, int a6, int a7, int a8, int a9, int a10, + int a11, int a12, int a13, int a14, int a15, int a16, + int a17, int a18, int a19, int a20) { unsigned len, left; char *next; gz_statep state; @@ -556,10 +525,7 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, #endif /* -- see zlib.h -- */ -int ZEXPORT gzflush(file, flush) - gzFile file; - int flush; -{ +int ZEXPORT gzflush(gzFile file, int flush) { gz_statep state; /* get internal structure */ @@ -588,11 +554,7 @@ int ZEXPORT gzflush(file, flush) } /* -- see zlib.h -- */ -int ZEXPORT gzsetparams(file, level, strategy) - gzFile file; - int level; - int strategy; -{ +int ZEXPORT gzsetparams(gzFile file, int level, int strategy) { gz_statep state; z_streamp strm; @@ -630,9 +592,7 @@ int ZEXPORT gzsetparams(file, level, strategy) } /* -- see zlib.h -- */ -int ZEXPORT gzclose_w(file) - gzFile file; -{ +int ZEXPORT gzclose_w(gzFile file) { int ret = Z_OK; gz_statep state; diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/zstd_zlibwrapper.c b/src/dependencies/zstd-1.5.6/zlibWrapper/zstd_zlibwrapper.c similarity index 100% rename from src/dependencies/zstd-1.5.4/zlibWrapper/zstd_zlibwrapper.c rename to src/dependencies/zstd-1.5.6/zlibWrapper/zstd_zlibwrapper.c diff --git a/src/dependencies/zstd-1.5.4/zlibWrapper/zstd_zlibwrapper.h b/src/dependencies/zstd-1.5.6/zlibWrapper/zstd_zlibwrapper.h similarity index 100% rename from src/dependencies/zstd-1.5.4/zlibWrapper/zstd_zlibwrapper.h rename to src/dependencies/zstd-1.5.6/zlibWrapper/zstd_zlibwrapper.h